package services

import (
	"context"
	"log"
	"time"

	"github.com/tapper/backend/database"
	"github.com/tapper/backend/models"
)

func StartDecayCron(ctx context.Context) {
	log.Println("[decay] Starting MMR decay cron")
	ticker := time.NewTicker(1 * time.Hour)
	defer ticker.Stop()

	runDecay()

	for {
		select {
		case <-ctx.Done():
			log.Println("[decay] Shutting down")
			return
		case <-ticker.C:
			runDecay()
		}
	}
}

func runDecay() {
	cfg, err := GetEloConfig()
	if err != nil {
		log.Printf("[decay] Failed to get Elo config: %v", err)
		return
	}

	if !cfg.DecayEnabled {
		return
	}

	decayThreshold := time.Now().UTC().Add(-time.Duration(cfg.DecayDays) * 24 * time.Hour)

	var users []models.User
	err = database.DB.
		Where("mmr > ? AND last_match_at IS NOT NULL AND last_match_at < ?", cfg.DecayFloor, decayThreshold).
		Find(&users).Error
	if err != nil {
		log.Printf("[decay] Failed to query users for decay: %v", err)
		return
	}

	decayed := 0
	for _, user := range users {
		// Active bans pause decay.
		if ban := GetActiveBan(user.ID); ban != nil {
			continue
		}

		if user.LastMatchAt == nil {
			continue
		}

		daysInactive := int(time.Since(*user.LastMatchAt).Hours() / 24)
		daysOverThreshold := daysInactive - cfg.DecayDays
		if daysOverThreshold <= 0 {
			continue
		}

		totalDecay := cfg.DecayPerDay * daysOverThreshold
		newMMR := user.MMR - totalDecay
		if newMMR < cfg.DecayFloor {
			newMMR = cfg.DecayFloor
		}

		if newMMR == user.MMR {
			continue
		}

		delta := newMMR - user.MMR

		history := models.MMRHistory{
			UserID: user.ID,
			OldMMR: user.MMR,
			NewMMR: newMMR,
			Delta:  delta,
			Reason: models.MMRReasonDecay,
		}
		database.DB.Create(&history)

		database.DB.Model(&user).Update("mmr", newMMR)
		decayed++
	}

	if decayed > 0 {
		log.Printf("[decay] Applied MMR decay to %d users", decayed)
	}
}
