package handlers

import (
	"net/http"
	"strings"

	"git.warky.dev/wdevs/whatshooked/pkg/logging"
	"git.warky.dev/wdevs/whatshooked/pkg/whatsapp/businessapi"
)

// BusinessAPIWebhook handles both verification (GET) and webhook events (POST)
func (h *Handlers) BusinessAPIWebhook(w http.ResponseWriter, r *http.Request) {
	accountID := extractAccountIDFromPath(r.URL.Path)

	if r.Method == http.MethodGet {
		logging.Info("WhatsApp webhook verification request", "account_id", accountID, "method", "GET")
		h.businessAPIWebhookVerify(w, r)
		return
	}

	if r.Method == http.MethodPost {
		logging.Info("WhatsApp webhook event received", "account_id", accountID, "method", "POST")
		h.businessAPIWebhookEvent(w, r)
		return
	}

	logging.Warn("WhatsApp webhook invalid method", "account_id", accountID, "method", r.Method)
	http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}

// businessAPIWebhookVerify handles webhook verification from Meta
// GET /webhooks/whatsapp/{accountID}?hub.mode=subscribe&hub.verify_token=XXX&hub.challenge=YYY
func (h *Handlers) businessAPIWebhookVerify(w http.ResponseWriter, r *http.Request) {
	// Extract account ID from URL path
	accountID := extractAccountIDFromPath(r.URL.Path)
	if accountID == "" {
		logging.Warn("WhatsApp webhook verification missing account ID")
		http.Error(w, "Account ID required in path", http.StatusBadRequest)
		return
	}

	// Get the account configuration
	var accountConfig *struct {
		ID          string
		Type        string
		VerifyToken string
	}

	for _, cfg := range h.config.WhatsApp {
		if cfg.ID == accountID && cfg.Type == "business-api" {
			if cfg.BusinessAPI != nil {
				accountConfig = &struct {
					ID          string
					Type        string
					VerifyToken string
				}{
					ID:          cfg.ID,
					Type:        cfg.Type,
					VerifyToken: cfg.BusinessAPI.VerifyToken,
				}
				break
			}
		}
	}

	if accountConfig == nil {
		logging.Error("Business API account not found or not configured", "account_id", accountID)
		http.Error(w, "Account not found", http.StatusNotFound)
		return
	}

	// Get query parameters
	mode := r.URL.Query().Get("hub.mode")
	token := r.URL.Query().Get("hub.verify_token")
	challenge := r.URL.Query().Get("hub.challenge")

	logging.Info("Webhook verification request",
		"account_id", accountID,
		"mode", mode,
		"has_challenge", challenge != "")

	// Verify the token matches
	if mode == "subscribe" && token == accountConfig.VerifyToken {
		logging.Info("Webhook verification successful", "account_id", accountID)
		w.WriteHeader(http.StatusOK)
		writeBytes(w, []byte(challenge))
		return
	}

	logging.Warn("Webhook verification failed",
		"account_id", accountID,
		"mode", mode,
		"token_match", token == accountConfig.VerifyToken)
	http.Error(w, "Forbidden", http.StatusForbidden)
}

// businessAPIWebhookEvent handles incoming webhook events from Meta
// POST /webhooks/whatsapp/{accountID}
func (h *Handlers) businessAPIWebhookEvent(w http.ResponseWriter, r *http.Request) {
	// Extract account ID from URL path
	accountID := extractAccountIDFromPath(r.URL.Path)
	if accountID == "" {
		logging.Warn("WhatsApp webhook event missing account ID")
		http.Error(w, "Account ID required in path", http.StatusBadRequest)
		return
	}

	logging.Info("WhatsApp webhook processing started", "account_id", accountID)

	// Get the client from the manager
	client, exists := h.whatsappMgr.GetClient(accountID)
	if !exists {
		logging.Error("Client not found for webhook", "account_id", accountID)
		http.Error(w, "Account not found", http.StatusNotFound)
		return
	}

	// Verify it's a Business API client
	if client.GetType() != "business-api" {
		logging.Error("Account is not a Business API client", "account_id", accountID, "type", client.GetType())
		http.Error(w, "Not a Business API account", http.StatusBadRequest)
		return
	}

	// Cast to Business API client to access HandleWebhook
	baClient, ok := client.(*businessapi.Client)
	if !ok {
		logging.Error("Failed to cast to Business API client", "account_id", accountID)
		http.Error(w, "Internal error", http.StatusInternalServerError)
		return
	}

	// Process the webhook
	if err := baClient.HandleWebhook(r); err != nil {
		logging.Error("Failed to process webhook", "account_id", accountID, "error", err)
		http.Error(w, "Internal error", http.StatusInternalServerError)
		return
	}

	logging.Info("WhatsApp webhook processed successfully", "account_id", accountID)

	// Return 200 OK to acknowledge receipt
	w.WriteHeader(http.StatusOK)
	writeBytes(w, []byte("OK"))
}

// extractAccountIDFromPath extracts the account ID from the URL path
// Example: /webhooks/whatsapp/business -> "business"
func extractAccountIDFromPath(path string) string {
	// Remove trailing slash if present
	path = strings.TrimSuffix(path, "/")

	// Split by /
	parts := strings.Split(path, "/")

	// Expected format: /webhooks/whatsapp/{accountID}
	if len(parts) >= 4 {
		return parts[3]
	}

	return ""
}
