// internal/workers/notification_worker.go - FIXED
package workers

import (
	"log"
	"lost-and-found/internal/models"
	"lost-and-found/internal/repositories"
	"time"

	"gorm.io/gorm"
)

// NotificationWorker handles sending notifications asynchronously
type NotificationWorker struct {
	db               *gorm.DB
	notificationRepo *repositories.NotificationRepository
	matchRepo        *repositories.MatchResultRepository
	stopChan         chan bool
}

// NewNotificationWorker creates a new notification worker
func NewNotificationWorker(db *gorm.DB) *NotificationWorker {
	return &NotificationWorker{
		db:               db,
		notificationRepo: repositories.NewNotificationRepository(db),
		matchRepo:        repositories.NewMatchResultRepository(db),
		stopChan:         make(chan bool),
	}
}

// Start starts the notification worker
// ✅ FIXED: Now runs in goroutine (non-blocking)
func (w *NotificationWorker) Start() {
	log.Println("📬 Notification Worker started")

	// ✅ Run in goroutine to avoid blocking
	go func() {
		// Run every 5 minutes
		ticker := time.NewTicker(5 * time.Minute)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				w.sendPendingNotifications()
			case <-w.stopChan:
				log.Println("📬 Notification Worker stopped")
				return
			}
		}
	}()
	// ✅ Return immediately after starting goroutine
}

// Stop stops the notification worker
func (w *NotificationWorker) Stop() {
	close(w.stopChan)
}

// sendPendingNotifications sends notifications for unnotified matches
func (w *NotificationWorker) sendPendingNotifications() {
	log.Println("📧 Checking for pending notifications...")

	// Get unnotified matches
	matches, err := w.matchRepo.FindUnnotifiedMatches()
	if err != nil {
		log.Printf("❌ Error fetching unnotified matches: %v", err)
		return
	}

	if len(matches) == 0 {
		log.Println("✅ No pending notifications")
		return
	}

	log.Printf("📧 Found %d pending notifications", len(matches))

	sentCount := 0
	for _, match := range matches {
		// Send notification to lost item owner
		if err := w.sendMatchNotification(&match); err != nil {
			log.Printf("❌ Failed to send notification for match ID %d: %v", match.ID, err)
			continue
		}

		// Mark as notified
		if err := w.matchRepo.MarkAsNotified(match.ID); err != nil {
			log.Printf("❌ Failed to mark match ID %d as notified: %v", match.ID, err)
			continue
		}

		sentCount++
	}

	log.Printf("✅ Sent %d notifications", sentCount)
}

// sendMatchNotification sends a match notification
func (w *NotificationWorker) sendMatchNotification(match *models.MatchResult) error {
	// Create notification
	err := models.CreateMatchNotification(
		w.db,
		match.LostItem.UserID,
		match.Item.Name,
		match.ID,
	)

	if err != nil {
		return err
	}

	log.Printf("📧 Sent match notification to user ID %d for item: %s", 
		match.LostItem.UserID, match.Item.Name)

	return nil
}

// RunNow runs notification sending immediately (for testing)
func (w *NotificationWorker) RunNow() {
	log.Println("▶️ Running notification sending manually...")
	w.sendPendingNotifications()
}