package infra

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

// rateLimiterClient mantiene el estado de un bucket para una clave concreta.
type rateLimiterClient struct {
	tokens   float64
	lastSeen time.Time
}

// RateLimiter mantiene el estado token-bucket de todos los clientes en memoria.
// rate son los tokens recargados por segundo, burst es la capacidad maxima del bucket.
// El campo clients es un mapa key -> bucket protegido por mu.
type RateLimiter struct {
	rate    float64
	burst   int
	mu      sync.Mutex
	clients map[string]*rateLimiterClient
}

// RateLimitConfig parametriza el middleware de rate limiting.
// KeyFunc extrae la clave del request (nil = IP del cliente).
// CleanupInterval controla la frecuencia del GC de entries inactivas (0 = no GC).
type RateLimitConfig struct {
	RequestsPerSecond float64
	BurstSize         int
	KeyFunc           func(r *http.Request) string
	CleanupInterval   time.Duration
}

// RateLimitResult es el resultado de evaluar un request contra el limiter.
// Allowed indica si el request puede pasar.
// Remaining son los tokens restantes en el bucket despues del check.
// ResetAt es el momento en que el bucket vuelve a estar lleno.
// RetryAfter son los segundos hasta que se pueda reintentar (0 si Allowed).
type RateLimitResult struct {
	Allowed    bool
	Remaining  int
	ResetAt    time.Time
	RetryAfter float64
}
