package middleware

import (
	"net/http"
	"strings"

	"veza-backend-api/internal/services"

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

// WebhookAPIKeyMiddleware crée un middleware pour valider les clés API de webhook (BE-SEC-012)
func WebhookAPIKeyMiddleware(webhookService *services.WebhookService, logger *zap.Logger) gin.HandlerFunc {
	return func(c *gin.Context) {
		// Extraire la clé API depuis les headers
		apiKey := extractAPIKey(c)
		if apiKey == "" {
			c.JSON(http.StatusUnauthorized, gin.H{
				"error": "API key required",
			})
			c.Abort()
			return
		}

		// Valider la clé API
		webhook, err := webhookService.ValidateAPIKey(c.Request.Context(), apiKey)
		if err != nil {
			logger.Warn("Invalid webhook API key",
				zap.String("api_key_prefix", apiKey[:min(8, len(apiKey))]+"..."),
				zap.Error(err))
			c.JSON(http.StatusUnauthorized, gin.H{
				"error": "Invalid API key",
			})
			c.Abort()
			return
		}

		// Stocker le webhook dans le contexte pour utilisation ultérieure
		c.Set("webhook", webhook)
		c.Set("webhook_id", webhook.ID)
		c.Set("user_id", webhook.UserID)

		c.Next()
	}
}

// extractAPIKey extrait la clé API depuis les headers
// Supporte X-API-Key et Authorization: Bearer <api_key>
func extractAPIKey(c *gin.Context) string {
	// Essayer X-API-Key header
	if apiKey := c.GetHeader("X-API-Key"); apiKey != "" {
		return apiKey
	}

	// Essayer Authorization header avec Bearer
	authHeader := c.GetHeader("Authorization")
	if authHeader != "" {
		parts := strings.SplitN(authHeader, " ", 2)
		if len(parts) == 2 && strings.ToLower(parts[0]) == "bearer" {
			return parts[1]
		}
		// Si pas de "Bearer", essayer directement la valeur
		if len(parts) == 1 {
			return parts[0]
		}
	}

	return ""
}

// min retourne le minimum de deux entiers
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
