package middleware

import (
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func RequestLogger(logger *zap.Logger) gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		c.Next()

		latency := time.Since(start)
		fields := []zap.Field{
			zap.String("request_id", GetRequestID(c)),
			zap.String("method", c.Request.Method),
			zap.String("path", c.Request.URL.Path),
			zap.String("route", c.FullPath()),
			zap.Int("status", c.Writer.Status()),
			zap.Float64("latency_ms", float64(latency.Microseconds())/1000),
			zap.String("client_ip", c.ClientIP()),
			zap.String("user_agent", c.GetHeader("User-Agent")),
			zap.String("referer", c.GetHeader("Referer")),
			zap.Int("response_size", c.Writer.Size()),
		}
		if userID, ok := c.Get(ContextUserID); ok {
			fields = append(fields, zap.Any("user_id", userID))
		}
		if adminID, ok := c.Get(ContextAdminID); ok {
			fields = append(fields, zap.Any("admin_id", adminID))
		}
		if len(c.Errors) > 0 {
			fields = append(fields, zap.String("errors", strings.TrimSpace(c.Errors.String())))
		}

		switch {
		case c.Writer.Status() >= 500:
			logger.Error("http request", fields...)
		case c.Writer.Status() >= 400:
			logger.Warn("http request", fields...)
		default:
			logger.Info("http request", fields...)
		}
	}
}
