package cn.novalon.gym.manage.datacount.scheduler;

import cn.novalon.gym.manage.datacount.domain.DataStatistics;
import cn.novalon.gym.manage.datacount.service.IDataStatisticsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.time.LocalDate;

/**
 * 数据统计定时任务
 * 每日凌晨执行统计数据更新
 *
 * @author system
 * @date 2026-06-09
 */
@Component
public class DataStatisticsScheduler {

    private static final Logger log = LoggerFactory.getLogger(DataStatisticsScheduler.class);

    @Autowired
    private IDataStatisticsService dataStatisticsService;

    /**
     * 每日凌晨2点执行前一天的日统计数据
     * 使用cron表达式: 0 0 2 * * ?
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void executeDailyStatistics() {
        LocalDate yesterday = LocalDate.now().minusDays(1);
        log.info("Starting daily statistics task for date: {}", yesterday);

        dataStatisticsService.executeDailyStatistics(yesterday)
                .subscribe(
                        null,
                        error -> log.error("Daily statistics task failed for date: {}", yesterday, error),
                        () -> log.info("Daily statistics task completed for date: {}", yesterday)
                );
    }

    /**
     * 每周一凌晨3点执行上周的周统计数据
     * 使用cron表达式: 0 0 3 ? * MON
     */
    @Scheduled(cron = "0 0 3 ? * MON")
    public void executeWeeklyStatistics() {
        LocalDate lastWeek = LocalDate.now().minusWeeks(1);
        log.info("Starting weekly statistics task for week of: {}", lastWeek);

        // 执行上周每天的统计数据汇总
        LocalDate weekStart = lastWeek.with(java.time.temporal.TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY));
        LocalDate weekEnd = lastWeek.with(java.time.temporal.TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY));

        for (LocalDate date = weekStart; !date.isAfter(weekEnd); date = date.plusDays(1)) {
            final LocalDate statDate = date;
            dataStatisticsService.executeDailyStatistics(statDate)
                    .block();
        }

        log.info("Weekly statistics task completed for week: {} - {}", weekStart, weekEnd);
    }

    /**
     * 每月1日凌晨3点执行上个月的月统计数据
     * 使用cron表达式: 0 0 3 1 * ?
     */
    @Scheduled(cron = "0 0 3 1 * ?")
    public void executeMonthlyStatistics() {
        LocalDate lastMonth = LocalDate.now().minusMonths(1);
        log.info("Starting monthly statistics task for month: {}", lastMonth.getMonth());

        // 执行上个月每天的统计数据补全
        LocalDate startOfMonth = lastMonth.withDayOfMonth(1);
        LocalDate endOfMonth = lastMonth.with(java.time.temporal.TemporalAdjusters.lastDayOfMonth());

        for (LocalDate date = startOfMonth; !date.isAfter(endOfMonth); date = date.plusDays(1)) {
            final LocalDate statDate = date;
            dataStatisticsService.executeDailyStatistics(statDate)
                    .block();
        }

        log.info("Monthly statistics task completed for month: {}", lastMonth.getMonth());
    }

    /**
     * 每月15日凌晨4点清理30天前的旧统计数据
     * 使用cron表达式: 0 0 4 15 * ?
     */
    @Scheduled(cron = "0 0 4 15 * ?")
    public void cleanupOldStatistics() {
        LocalDate cutoffDate = LocalDate.now().minusDays(30);
        log.info("Starting cleanup old statistics task, removing data before: {}", cutoffDate);

        // 清理Redis中的旧统计数据
        String pattern = "datacount:statistics:*:" + cutoffDate.toString();
        cn.novalon.gym.manage.common.util.RedisUtil redisUtil = null;
        try {
            // 这里可以通过注入的service来清理，但当前实现使用Redis缓存30天自动过期
            log.info("Old statistics cleanup completed, cutoff date: {}", cutoffDate);
        } catch (Exception e) {
            log.error("Failed to cleanup old statistics", e);
        }
    }
}
