package middlewares

import (
	"GoMembership/pkg/logger"
	"net/http"
	"sync"

	"github.com/gin-gonic/gin"
	"golang.org/x/time/rate"
)

type IPRateLimiter struct {
	ips map[string]*rate.Limiter
	mu  *sync.RWMutex
	r   rate.Limit
	b   int
}

func NewIPRateLimiter(r int, b int) *IPRateLimiter {
	return &IPRateLimiter{
		ips: make(map[string]*rate.Limiter),
		mu:  &sync.RWMutex{},
		r:   rate.Limit(r),
		b:   b,
	}
}

func (i *IPRateLimiter) GetLimiter(ip string) *rate.Limiter {
	i.mu.Lock()
	defer i.mu.Unlock()

	limiter, exists := i.ips[ip]
	if !exists {
		limiter = rate.NewLimiter(i.r, i.b)
		i.ips[ip] = limiter
	}

	return limiter
}

// func RateLimitMiddleware() gin.HandlerFunc {
// 	if iPLimiter == nil {

// 		iPLimiter := NewIPRateLimiter(
// 				rate.Limit(config.Security.Ratelimits.Limit),
// 				config.Security.Ratelimits.Burst)
// 	}

// 	return func(c *gin.Context) {
// 		ip := c.ClientIP()
// 		l := iPLimiter.GetLimiter(ip)
// 		if !l.Allow() {
// 			c.JSON(http.StatusTooManyRequests, gin.H{
// 				"error": "Too many requests",
// 			})
// 			c.Abort()
// 			return
// 		}
// 		c.Next()
// 	}
// }

func RateLimitMiddleware(limiter *IPRateLimiter) gin.HandlerFunc {
	logger.Info.Printf("Limiter with Limit: %v, Burst: %v", limiter.r, limiter.b)
	return func(c *gin.Context) {
		if limiter == nil {
			logger.Error.Println("Limiter missing")
			c.AbortWithStatus(http.StatusInternalServerError)
			return
		}

		ip := c.ClientIP()
		l := limiter.GetLimiter(ip)
		if !l.Allow() {
			c.JSON(http.StatusTooManyRequests, gin.H{
				"error": "Too many requests",
			})
			c.Abort()
			return
		}
		c.Next()
	}
}
