package middlewares

import (
	"net"
	"net/http"
	"sync"
	"time"
)

type rateEntry struct {
	Count     int
	ExpiresAt time.Time
}

var (
	rateMu sync.Mutex
	rateDB = make(map[string]*rateEntry)
)

func RateLimit(keyFn func(*http.Request) string, limit int, window time.Duration) func(http.Handler) http.Handler {

	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

			key := keyFn(r)
			now := time.Now()

			rateMu.Lock()
			e, ok := rateDB[key]
			if !ok || now.After(e.ExpiresAt) {
				e = &rateEntry{
					Count:     0,
					ExpiresAt: now.Add(window),
				}
				rateDB[key] = e
			}

			e.Count++
			if e.Count > limit {
				rateMu.Unlock()
				http.Error(w, "Too many requests", http.StatusTooManyRequests)
				return
			}
			rateMu.Unlock()

			next.ServeHTTP(w, r)
		})
	}
}

// helpers
func RateByIP(r *http.Request) string {
	ip, _, _ := net.SplitHostPort(r.RemoteAddr)
	return "ip:" + ip
}

func RateByUser(r *http.Request) string {
	return "user:" + r.URL.Path // id path’ten okunabilir
}
