package infra

import (
	"net"
	"net/http"
	"strings"
)

// rateLimitClientIP extrae la IP del cliente del request.
// Prioridad: X-Forwarded-For (primer valor) > X-Real-IP > RemoteAddr.
// Para X-Forwarded-For multi-hop solo se usa el primer IP (cliente original).
func rateLimitClientIP(r *http.Request) string {
	if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
		parts := strings.Split(xff, ",")
		ip := strings.TrimSpace(parts[0])
		if ip != "" {
			return ip
		}
	}
	if xri := r.Header.Get("X-Real-IP"); xri != "" {
		return strings.TrimSpace(xri)
	}
	host, _, err := net.SplitHostPort(r.RemoteAddr)
	if err == nil {
		return host
	}
	return r.RemoteAddr
}

// RateLimitMiddleware retorna un Middleware que aplica rate limiting por IP del cliente.
// Si el request supera el limite responde 429 con headers Retry-After y X-RateLimit-*.
// La IP se extrae con prioridad X-Forwarded-For > X-Real-IP > RemoteAddr.
func RateLimitMiddleware(rl *RateLimiter) Middleware {
	return RateLimiterByKey(rl, rateLimitClientIP)
}
