package middleware

import (
	"sync"
	"time"

	"github.com/gofiber/fiber/v2"
)

type bucket struct {
	tokens    float64
	lastCheck time.Time
}

type rateLimiter struct {
	mu       sync.Mutex
	buckets  map[string]*bucket
	rate     float64 // tokens per second
	capacity float64
}

func NewRateLimiter(requestsPerMinute int) fiber.Handler {
	rl := &rateLimiter{
		buckets:  make(map[string]*bucket),
		rate:     float64(requestsPerMinute) / 60.0,
		capacity: float64(requestsPerMinute),
	}

	return func(c *fiber.Ctx) error {
		ip := c.IP()
		rl.mu.Lock()
		b, ok := rl.buckets[ip]
		if !ok {
			b = &bucket{tokens: rl.capacity, lastCheck: time.Now()}
			rl.buckets[ip] = b
		}

		now := time.Now()
		elapsed := now.Sub(b.lastCheck).Seconds()
		b.tokens += elapsed * rl.rate
		if b.tokens > rl.capacity {
			b.tokens = rl.capacity
		}
		b.lastCheck = now

		if b.tokens < 1 {
			rl.mu.Unlock()
			return c.Status(429).JSON(fiber.Map{"error": "rate limit exceeded"})
		}
		b.tokens--
		rl.mu.Unlock()

		return c.Next()
	}
}
