package handlers

import (
	"fmt"
	"net/http"

	"veza-backend-api/internal/services"
	"veza-backend-api/internal/workers"

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

// WebhookHandler gère les handlers de webhooks
type WebhookHandler struct {
	webhookService *services.WebhookService
	webhookWorker  *workers.WebhookWorker
	logger         *zap.Logger
}

// NewWebhookHandler crée un nouveau handler de webhooks
func NewWebhookHandler(
	webhookService *services.WebhookService,
	webhookWorker *workers.WebhookWorker,
	logger *zap.Logger,
) *WebhookHandler {
	return &WebhookHandler{
		webhookService: webhookService,
		webhookWorker:  webhookWorker,
		logger:         logger,
	}
}

// RegisterWebhook gère l'enregistrement d'un webhook
func (h *WebhookHandler) RegisterWebhook() gin.HandlerFunc {
	return func(c *gin.Context) {
		// Récupérer l'ID utilisateur
		userIDInterface, exists := c.Get("user_id")
		if !exists {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
			return
		}

		userID := uint(userIDInterface.(uint))

		var req struct {
			URL    string   `json:"url" binding:"required,url"`
			Events []string `json:"events" binding:"required,min=1"`
		}

		if err := c.ShouldBindJSON(&req); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		webhook, err := h.webhookService.RegisterWebhook(c.Request.Context(), userID, req.URL, req.Events)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to register webhook"})
			return
		}

		c.JSON(http.StatusCreated, webhook)
	}
}

// ListWebhooks liste les webhooks d'un utilisateur
func (h *WebhookHandler) ListWebhooks() gin.HandlerFunc {
	return func(c *gin.Context) {
		userIDInterface, exists := c.Get("user_id")
		if !exists {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
			return
		}

		userID := uint(userIDInterface.(uint))

		webhooks, err := h.webhookService.ListWebhooks(c.Request.Context(), userID)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to list webhooks"})
			return
		}

		c.JSON(http.StatusOK, webhooks)
	}
}

// DeleteWebhook supprime un webhook
func (h *WebhookHandler) DeleteWebhook() gin.HandlerFunc {
	return func(c *gin.Context) {
		userIDInterface, exists := c.Get("user_id")
		if !exists {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
			return
		}

		userID := uint(userIDInterface.(uint))
		webhookID := c.Param("id")

		var webhookIDUint uint
		if _, err := fmt.Sscanf(webhookID, "%d", &webhookIDUint); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid webhook ID"})
			return
		}

		err := h.webhookService.DeleteWebhook(c.Request.Context(), webhookIDUint, userID)
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "Webhook not found"})
			return
		}

		c.JSON(http.StatusOK, gin.H{"message": "Webhook deleted successfully"})
	}
}

// GetWebhookStats retourne les statistiques des webhooks
func (h *WebhookHandler) GetWebhookStats() gin.HandlerFunc {
	return func(c *gin.Context) {
		stats := h.webhookWorker.GetStats()

		c.JSON(http.StatusOK, gin.H{
			"stats": stats,
		})
	}
}

// TestWebhook teste un webhook
func (h *WebhookHandler) TestWebhook() gin.HandlerFunc {
	return func(c *gin.Context) {
		_ = c.Param("id") // webhookID

		// TODO: Implémenter test webhook
		// Envoyer un événement test avec données de test

		c.JSON(http.StatusOK, gin.H{"message": "Webhook test sent"})
	}
}
