package middleware

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

	"aggios-app/backend/internal/config"
)

type rateLimiter struct {
	mu       sync.Mutex
	attempts map[string][]time.Time
	maxAttempts int
}

func newRateLimiter(maxAttempts int) *rateLimiter {
	rl := &rateLimiter{
		attempts: make(map[string][]time.Time),
		maxAttempts: maxAttempts,
	}
	
	// Clean old entries every minute
	go func() {
		ticker := time.NewTicker(1 * time.Minute)
		defer ticker.Stop()
		for range ticker.C {
			rl.cleanup()
		}
	}()
	
	return rl
}

func (rl *rateLimiter) cleanup() {
	rl.mu.Lock()
	defer rl.mu.Unlock()
	
	now := time.Now()
	for ip, attempts := range rl.attempts {
		var valid []time.Time
		for _, t := range attempts {
			if now.Sub(t) < time.Minute {
				valid = append(valid, t)
			}
		}
		if len(valid) == 0 {
			delete(rl.attempts, ip)
		} else {
			rl.attempts[ip] = valid
		}
	}
}

func (rl *rateLimiter) isAllowed(ip string) bool {
	rl.mu.Lock()
	defer rl.mu.Unlock()
	
	now := time.Now()
	attempts := rl.attempts[ip]
	
	// Filter attempts within the last minute
	var validAttempts []time.Time
	for _, t := range attempts {
		if now.Sub(t) < time.Minute {
			validAttempts = append(validAttempts, t)
		}
	}
	
	if len(validAttempts) >= rl.maxAttempts {
		return false
	}
	
	validAttempts = append(validAttempts, now)
	rl.attempts[ip] = validAttempts
	
	return true
}

// RateLimit limits requests per IP address
func RateLimit(cfg *config.Config) func(http.Handler) http.Handler {
	limiter := newRateLimiter(cfg.Security.MaxAttemptsPerMin)
	
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			ip := r.RemoteAddr
			
			if !limiter.isAllowed(ip) {
				http.Error(w, "Too many requests", http.StatusTooManyRequests)
				return
			}
			
			next.ServeHTTP(w, r)
		})
	}
}
