package router

import (
	"net/http"
	"strings"

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

	"github.com/tidbcloud/inference-service/internal/config"
)

// requireAPIKey creates a middleware that checks for a valid API key
func requireAPIKey(getAPIKey func() string) gin.HandlerFunc {
	return func(c *gin.Context) {
		apiKey := getAPIKey()

		// Skip authentication if no API key is configured
		if apiKey == "" {
			c.Next()
			return
		}

		// Extract Bearer token from Authorization header
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			c.Error(httperr.Errorf(http.StatusUnauthorized, "Missing Bearer token"))
			c.Abort()
			return
		}

		// Check for Bearer token format
		const bearerPrefix = "Bearer "
		if !strings.HasPrefix(authHeader, bearerPrefix) {
			c.Error(httperr.Errorf(http.StatusUnauthorized, "Missing Bearer token"))
			c.Abort()
			return
		}

		// Extract token
		token := strings.TrimPrefix(authHeader, bearerPrefix)

		// Validate token
		if token != apiKey {
			zap.L().Warn("Unauthorized access",
				zap.String("path", c.Request.URL.Path),
				zap.String("method", c.Request.Method),
				zap.String("remote", c.Request.RemoteAddr))
			c.Error(httperr.Errorf(http.StatusUnauthorized, "Invalid API key"))
			c.Abort()
			return
		}

		c.Next()
	}
}

// RequireServiceAPIKey middleware checks for valid service API key
func RequireServiceAPIKey() gin.HandlerFunc {
	return requireAPIKey(func() string { return config.Global().Server.CheckServiceAPIKey })
}

// RequireManagementAPIKey middleware checks for valid management API key
func RequireManagementAPIKey() gin.HandlerFunc {
	return requireAPIKey(func() string { return config.Global().Server.CheckManagementAPIKey })
}
