package httpapi

import (
	"time"

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

func requestLogMiddleware(logger *zap.Logger) gin.HandlerFunc {
	baseLogger := logger
	if baseLogger == nil {
		baseLogger = zap.NewNop()
	}

	return func(c *gin.Context) {
		startedAt := time.Now()
		path := c.Request.URL.Path
		query := c.Request.URL.RawQuery

		c.Next()

		status := c.Writer.Status()
		latency := time.Since(startedAt)
		requestID := requestIDFromContext(c)

		if path == "/v1/health" && status < 400 {
			return
		}

		fields := []zap.Field{
			zap.String("requestId", requestID),
			zap.String("method", c.Request.Method),
			zap.String("path", path),
			zap.Int("status", status),
			zap.Duration("latency", latency),
			zap.String("clientIP", c.ClientIP()),
			zap.String("userAgent", c.Request.UserAgent()),
			zap.Int("responseBytes", c.Writer.Size()),
		}
		if query != "" {
			fields = append(fields, zap.String("query", query))
		}
		if len(c.Errors) > 0 {
			fields = append(fields, zap.String("errors", c.Errors.String()))
		}

		switch {
		case status >= 500:
			baseLogger.Error("http request completed with server error", fields...)
		case status >= 400:
			baseLogger.Warn("http request completed with client error", fields...)
		default:
			baseLogger.Info("http request completed", fields...)
		}
	}
}
