// Filename: internal/scheduler/scheduler.go
package scheduler

import (
	"context"
	"gemini-balancer/internal/repository"
	"gemini-balancer/internal/service"
	"time"

	"github.com/go-co-op/gocron"
	"github.com/sirupsen/logrus"
)

type Scheduler struct {
	gocronScheduler *gocron.Scheduler
	logger          *logrus.Entry
	statsService    *service.StatsService
	keyRepo         repository.KeyRepository
}

func NewScheduler(statsSvc *service.StatsService, keyRepo repository.KeyRepository, logger *logrus.Logger) *Scheduler {
	s := gocron.NewScheduler(time.UTC)
	s.TagsUnique()
	return &Scheduler{
		gocronScheduler: s,
		logger:          logger.WithField("component", "Scheduler📆"),
		statsService:    statsSvc,
		keyRepo:         keyRepo,
	}
}

func (s *Scheduler) Start() {
	s.logger.Info("Starting scheduler and registering jobs...")

	// 任务一：每小时执行一次的统计聚合
	// 使用CRON表达式，精确定义“每小时的第5分钟”执行
	_, err := s.gocronScheduler.Cron("5 * * * *").Tag("stats-aggregation").Do(func() {
		s.logger.Info("Executing hourly request stats aggregation...")
		// 为后台定时任务创建一个新的、空的 context
		ctx := context.Background()
		if err := s.statsService.AggregateHourlyStats(ctx); err != nil {
			s.logger.WithError(err).Error("Hourly stats aggregation failed.")
		} else {
			s.logger.Info("Hourly stats aggregation completed successfully.")
		}
	})
	if err != nil {
		s.logger.Errorf("Failed to schedule [stats-aggregation]: %v", err)
	}

	// 任务二：(预留) 自动健康检查

	// 任务三：每日执行一次的软删除Key清理
	// Executes once daily at 3:15 AM UTC.
	_, err = s.gocronScheduler.Cron("15 3 * * *").Tag("cleanup-soft-deleted-keys").Do(func() {
		s.logger.Info("Executing daily cleanup of soft-deleted API keys...")

		// [假设保留7天，实际应来自配置
		const retentionDays = 7

		count, err := s.keyRepo.HardDeleteSoftDeletedBefore(time.Now().AddDate(0, 0, -retentionDays))
		if err != nil {
			s.logger.WithError(err).Error("Daily cleanup of soft-deleted keys failed.")
		} else if count > 0 {
			s.logger.Infof("Daily cleanup completed: Permanently deleted %d expired soft-deleted keys.", count)
		} else {
			s.logger.Info("Daily cleanup completed: No expired soft-deleted keys found to delete.")
		}
	})
	if err != nil {
		s.logger.Errorf("Failed to schedule [cleanup-soft-deleted-keys]: %v", err)
	}

	s.gocronScheduler.StartAsync()
	s.logger.Info("Scheduler started.")
}

func (s *Scheduler) Stop() {
	s.logger.Info("Stopping scheduler...")
	s.gocronScheduler.Stop()
	s.logger.Info("Scheduler stopped.")
}
