package shop.alien.store.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import shop.alien.mapper.StoreInfoMapper;
import shop.alien.entity.store.StoreInfo;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 统计数据定时任务
 * 定时计算并保存统计数据到store_track_statistics表
 *
 * @author system
 * @since 2026-01-14
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class TrackStatisticsScheduler {
    
    private final TrackEventService trackEventService;
    private final StoreInfoMapper storeInfoMapper;

    /**
     * 每天凌晨1点执行，计算前一天的统计数据
     * cron表达式: 秒 分 时 日 月 周
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void calculateDailyStatistics() {
        log.info("开始执行日统计数据计算任务");
        
        try {
            // 计算前一天的日期
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            Date yesterday = calendar.getTime();
            
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            log.info("计算日期: {}", sdf.format(yesterday));
            
            // 查询所有店铺（只查询未删除的）
            LambdaQueryWrapper<StoreInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreInfo::getDeleteFlag, 0);
            List<StoreInfo> stores = storeInfoMapper.selectList(wrapper);
            log.info("共{}个店铺需要计算统计数据", stores.size());
            
            int successCount = 0;
            int failCount = 0;
            
            for (StoreInfo store : stores) {
                try {
                    trackEventService.calculateAndSaveStatistics(store.getId(), yesterday, "DAILY");
                    successCount++;
                    log.debug("店铺{}的日统计数据计算成功", store.getId());
                } catch (Exception e) {
                    failCount++;
                    log.error("店铺{}的日统计数据计算失败", store.getId(), e);
                }
            }
            
            log.info("日统计数据计算任务完成: 成功{}, 失败{}", successCount, failCount);
        } catch (Exception e) {
            log.error("执行日统计数据计算任务失败", e);
        }
    }

    /**
     * 每周一凌晨2点执行，计算上一周的统计数据
     */
    @Scheduled(cron = "0 0 2 ? * MON")
    public void calculateWeeklyStatistics() {
        log.info("开始执行周统计数据计算任务");
        
        try {
            // 计算上一周的日期（上周一）
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.WEEK_OF_YEAR, -1);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            Date lastWeekMonday = calendar.getTime();
            
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            log.info("计算日期: {}", sdf.format(lastWeekMonday));
            
            // 查询所有店铺（只查询未删除的）
            LambdaQueryWrapper<StoreInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreInfo::getDeleteFlag, 0);
            List<StoreInfo> stores = storeInfoMapper.selectList(wrapper);
            log.info("共{}个店铺需要计算统计数据", stores.size());
            
            int successCount = 0;
            int failCount = 0;
            
            for (StoreInfo store : stores) {
                try {
                    trackEventService.calculateAndSaveStatistics(store.getId(), lastWeekMonday, "WEEKLY");
                    successCount++;
                    log.debug("店铺{}的周统计数据计算成功", store.getId());
                } catch (Exception e) {
                    failCount++;
                    log.error("店铺{}的周统计数据计算失败", store.getId(), e);
                }
            }
            
            log.info("周统计数据计算任务完成: 成功{}, 失败{}", successCount, failCount);
        } catch (Exception e) {
            log.error("执行周统计数据计算任务失败", e);
        }
    }

    /**
     * 每月1号凌晨3点执行，计算上一个月的统计数据
     */
    @Scheduled(cron = "0 0 3 1 * ?")
    public void calculateMonthlyStatistics() {
        log.info("开始执行月统计数据计算任务");
        
        try {
            // 计算上一个月的日期（上月1号）
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            Date lastMonthFirstDay = calendar.getTime();
            
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            log.info("计算日期: {}", sdf.format(lastMonthFirstDay));
            
            // 查询所有店铺（只查询未删除的）
            LambdaQueryWrapper<StoreInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreInfo::getDeleteFlag, 0);
            List<StoreInfo> stores = storeInfoMapper.selectList(wrapper);
            log.info("共{}个店铺需要计算统计数据", stores.size());
            
            int successCount = 0;
            int failCount = 0;
            
            for (StoreInfo store : stores) {
                try {
                    trackEventService.calculateAndSaveStatistics(store.getId(), lastMonthFirstDay, "MONTHLY");
                    successCount++;
                    log.debug("店铺{}的月统计数据计算成功", store.getId());
                } catch (Exception e) {
                    failCount++;
                    log.error("店铺{}的月统计数据计算失败", store.getId(), e);
                }
            }
            
            log.info("月统计数据计算任务完成: 成功{}, 失败{}", successCount, failCount);
        } catch (Exception e) {
            log.error("执行月统计数据计算任务失败", e);
        }
    }
}
