package webhook

import (
	"encoding/json"
	"fmt"
	"log"
	"time"

	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
)

type EventType string

const (
	EventUserRegistered   EventType = "user.registered"
	EventUserLogin        EventType = "user.login"
	EventUserRecharged    EventType = "user.recharged"
	EventUserExpired      EventType = "user.expired"
	EventCardUsed         EventType = "card.used"
	EventCardExpired      EventType = "card.expired"
	EventAbnormalDetected EventType = "abnormal.detected"
)

type WebhookPayload struct {
	Event     EventType              `json:"event"`
	Timestamp int64                  `json:"timestamp"`
	Data      map[string]interface{} `json:"data"`
}

func TriggerEvent(appID uint, event EventType, data map[string]interface{}) {
	var webhooks []model.WebhookConfig
	if err := database.DB.Where("application_id = ? AND status = ?", appID, "active").Find(&webhooks).Error; err != nil {
		log.Printf("Failed to fetch webhooks: %v", err)
		return
	}

	for _, webhook := range webhooks {
		var events []string
		if err := json.Unmarshal([]byte(webhook.Events), &events); err != nil {
			log.Printf("Failed to parse webhook events: %v", err)
			continue
		}

		if !containsEvent(events, string(event)) {
			continue
		}

		payload := WebhookPayload{
			Event:     event,
			Timestamp: time.Now().Unix(),
			Data:      data,
		}

		go sendWebhookNotification(&webhook, payload)
	}
}

func containsEvent(events []string, event string) bool {
	for _, e := range events {
		if e == event || e == "*" {
			return true
		}
	}
	return false
}

func sendWebhookNotification(webhook *model.WebhookConfig, payload WebhookPayload) {
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		log.Printf("Failed to marshal webhook payload: %v", err)
		return
	}

	log.Printf("Sending webhook to %s: %s", webhook.URL, string(payloadBytes))
	fmt.Printf("[Webhook] Sending to %s: Event=%s, AppID=%d\n", webhook.URL, payload.Event, webhook.ApplicationID)
}
