package services

import (
	"log"

	"github.com/robfig/cron/v3"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
)

var cronScheduler *cron.Cron

// IniciarCron arranca el scheduler de tareas. Llamar desde app.go o main.go.
func IniciarCron() {
	cronScheduler = cron.New()

	// Ejecutar todos los días a las 8:00 AM
	_, err := cronScheduler.AddFunc("0 8 * * *", ProcesarVencimientos)
	if err != nil {
		log.Printf("[CRON] Error registrando tarea: %v", err)
		return
	}

	cronScheduler.Start()
	log.Println("[CRON] Scheduler iniciado — verificando vencimientos diariamente a las 8:00 AM")
}

// DetenerCron para graceful shutdown
func DetenerCron() {
	if cronScheduler != nil {
		cronScheduler.Stop()
	}
}

// ProcesarVencimientos es la función principal del cron
func ProcesarVencimientos() {
	log.Println("[CRON] Iniciando procesamiento de vencimientos...")

	reglas, err := models.GetReglasActivas()
	if err != nil {
		log.Printf("[CRON] Error obteniendo reglas: %v", err)
		return
	}

	for _, regla := range reglas {
		contratos, err := models.GetContratosProximosVencer(regla.DiasAntes)
		if err != nil {
			log.Printf("[CRON] Error obteniendo contratos para regla %d: %v", regla.ID, err)
			continue
		}
		if len(contratos) == 0 {
			continue
		}

		// Filtrar por AplicaA
		var filtrados []models.Contrato
		for _, c := range contratos {
			switch regla.AplicaA {
			case "renovable":
				for _, s := range c.Servicios {
					if s.Tipo == "renovable" {
						filtrados = append(filtrados, c)
						break
					}
				}
			case "unico":
				for _, s := range c.Servicios {
					if s.Tipo == "unico" {
						filtrados = append(filtrados, c)
						break
					}
				}
			default:
				filtrados = append(filtrados, c)
			}
		}
		if len(filtrados) == 0 {
			continue
		}

		// Agrupar contratos por cliente
		porCliente := make(map[uint][]models.Contrato)
		for _, c := range filtrados {
			porCliente[c.ClienteID] = append(porCliente[c.ClienteID], c)
		}

		for clienteID, grupoContratos := range porCliente {
			// Evitar duplicados: ya enviado hoy para esta regla + cliente
			if models.YaEnviadoHoy(clienteID, regla.ID) {
				log.Printf("[CRON] Ya enviado hoy a cliente %d para regla %d — saltando", clienteID, regla.ID)
				continue
			}

			cliente := &grupoContratos[0].Cliente
			if err := EnviarNotificacionGrupo(&regla, cliente, grupoContratos); err != nil {
				log.Printf("[CRON] Error enviando a cliente %d: %v", clienteID, err)
			} else {
				log.Printf("[CRON] Enviado a cliente %d (%s) — %d contrato(s)",
					clienteID, cliente.Email, len(grupoContratos))
			}
		}
	}

	log.Println("[CRON] Procesamiento de vencimientos finalizado")
}
