package services

import (
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"

	"fotbal-club/internal/config"
	"fotbal-club/internal/models"
	"fotbal-club/pkg/email"

	"gorm.io/gorm"
)

// StartNewsletterScheduler starts a background job that sends automated newsletters.
// It can be configured via env NEWSLETTER_INTERVAL_HOURS and is guarded by config.NewsletterEnabled.
func StartNewsletterScheduler(db *gorm.DB, emailSvc email.EmailService) {
	interval := 24 * time.Hour // default daily for demo; real use might be weekly
	if v := os.Getenv("NEWSLETTER_INTERVAL_HOURS"); v != "" {
		if h, err := time.ParseDuration(v + "h"); err == nil {
			interval = h
		}
	}

	// Run once on startup only if enabled
	if config.AppConfig != nil && config.AppConfig.NewsletterEnabled {
		go runNewsletterCycle(db, emailSvc)
	} else {
		log.Printf("[newsletter] scheduler is disabled at startup; waiting for enable toggle")
	}

	// Periodic ticker
	go func() {
		ticker := time.NewTicker(interval)
		defer ticker.Stop()
		for range ticker.C {
			if config.AppConfig != nil && config.AppConfig.NewsletterEnabled {
				runNewsletterCycle(db, emailSvc)
			} else {
				log.Printf("[newsletter] skipped cycle (disabled)")
			}
		}
	}()
}

func runNewsletterCycle(db *gorm.DB, emailSvc email.EmailService) {
	log.Printf("[newsletter] starting automated newsletter cycle")
	cacheDir := filepath.Join("cache", "prefetch")

	// Fetch subscribers in batches
	var subs []models.NewsletterSubscription
	if err := db.Find(&subs).Error; err != nil {
		log.Printf("[newsletter] failed to load subscribers: %v", err)
		return
	}

	for _, s := range subs {
		if !s.IsActive {
			continue
		}
		// Normalize preferences to new structure
		ct := make([]string, 0, 4)
		if v, ok := s.Preferences["blogs"].(bool); ok && v { ct = append(ct, "blogs") }
		if v, ok := s.Preferences["events"].(bool); ok && v { ct = append(ct, "events") }
		if v, ok := s.Preferences["matches"].(bool); ok && v { ct = append(ct, "matches") }
		if v, ok := s.Preferences["scores"].(bool); ok && v { ct = append(ct, "scores") }
		// Backward-compat: weekly implies blogs; matches implies matches
		if v, ok := s.Preferences["weekly"].(bool); ok && v && !contains(ct, "blogs") { ct = append(ct, "blogs") }
		if v, ok := s.Preferences["matches"].(bool); ok && v && !contains(ct, "matches") { ct = append(ct, "matches") }

		// Optional competitions list if stored under key like competitions
		comps := []string{}
		if raw, ok := s.Preferences["competitions"].(string); ok && raw != "" {
			// comma-separated codes
			for _, p := range strings.Split(raw, ",") {
				if v := strings.TrimSpace(p); v != "" { comps = append(comps, v) }
			}
		}

		prefs := NewsletterPrefs{
			Email:        s.Email,
			ContentTypes: ct,
			Competitions: comps,
			Frequency:    "daily",
		}
		subj, content := BuildNewsletterDigest(cacheDir, prefs)
		if strings.TrimSpace(content) == "" { continue }

		data := &email.NewsletterData{
			Subject:    subj,
			Content:    content,
			Recipients: []string{s.Email},
		}

		if err := emailSvc.SendNewsletter(data); err != nil {
			log.Printf("[newsletter] failed to send to %s: %v", s.Email, err)
		}
		// small sleep to avoid hammering SMTP
		time.Sleep(200 * time.Millisecond)
	}

	log.Printf("[newsletter] automated cycle finished")
}

func contains(list []string, v string) bool {
    for _, x := range list {
        if x == v {
            return true
        }
    }
    return false
}
