package infra

import (
	"net/http"
)

// RateLimiterByKey retorna un Middleware que aplica rate limiting usando keyFunc para extraer la clave del request.
// Permite limitar por API key, user ID, o cualquier dimension custom.
// Cuando keyFunc devuelve "" no se aplica limit (request pasa sin tocar el bucket).
// Cuando se supera el limite responde 429 con headers X-RateLimit-* y Retry-After.
func RateLimiterByKey(rl *RateLimiter, keyFunc func(r *http.Request) string) Middleware {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			key := keyFunc(r)
			if key == "" {
				// Sin clave no se aplica limit.
				next.ServeHTTP(w, r)
				return
			}

			result := RateLimiterCheck(rl, key)
			headers := RateLimitHeaders(result, rl.burst)
			for k, v := range headers {
				w.Header()[k] = v
			}

			if !result.Allowed {
				HTTPErrorResponse(w, HTTPError{
					Status:  http.StatusTooManyRequests,
					Code:    "rate_limited",
					Message: "too many requests",
				})
				return
			}

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