package com.ycwl.basic.task;

import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
import com.ycwl.basic.mapper.ScenicDeviceStatsMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.model.mobile.statistic.req.CommonQueryReq;
import com.ycwl.basic.model.mobile.statistic.resp.AppStatisticsFunnelVO;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.model.pc.scenicDeviceStats.entity.ScenicDeviceStatsEntity;
import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.service.mobile.AppStatisticsService;
import com.ycwl.basic.utils.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

@Slf4j
@Component
@EnableScheduling
@Profile("prod")
public class ScenicStatsTask {
    @Autowired
    private ScenicDeviceStatsMapper mapper;
    @Autowired
    private StatisticsMapper statisticsMapper;
    @Autowired
    private AppStatisticsService statisticsService;
    @Autowired
    private ScenicRepository scenicRepository;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Scheduled(cron = "0 1 0 * * *")
    public void countDeviceStats() {
        Date yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday());
        Date yesterdayEnd = DateUtil.endOfDay(yesterdayStart);
        Date twoDaysBeforeStart = DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.yesterday(), -1));
        Date twoDaysBeforeEnd = DateUtil.endOfDay(twoDaysBeforeStart);
        // 前天的数据
        List<ScenicDeviceStatsEntity> list = mapper.countDeviceStats(twoDaysBeforeStart, twoDaysBeforeEnd);
        if (!list.isEmpty()) {
            list.forEach(stats -> {
                stats.setDate(twoDaysBeforeStart);
                mapper.insert(stats);
            });
        }
        list = mapper.countDeviceStats(yesterdayStart, yesterdayEnd);
        if (!list.isEmpty()) {
            list.forEach(stats -> {
                stats.setDate(yesterdayStart);
                mapper.insert(stats);
            });
        }
    }
    @Scheduled(cron = "0 1 0 * * *")
    public void countScenicStats() {
        log.info("开始执行景区统计任务，统计前7天至昨天的数据");

        // 获取所有景区列表
        ScenicReqQuery query = new ScenicReqQuery();
        query.setPageSize(1000);
        List<ScenicV2DTO> scenicList = scenicRepository.list(query);

        // 循环统计前7天（至昨天）的数据
        for (int daysAgo = 1; daysAgo <= 7; daysAgo++) {
            Date targetDate = DateUtil.offsetDay(new Date(), -daysAgo);
            Date startTime = DateUtil.beginOfDay(targetDate);
            Date endTime = DateUtil.endOfDay(targetDate);

            log.info("正在统计第{}天前的数据，日期: {}", daysAgo, DateUtil.formatDate(startTime));

            scenicList.forEach((scenic) -> {
                try {
                    CommonQueryReq commonQueryReq = new CommonQueryReq();
                    Long scenicId = Long.valueOf(scenic.getId());
                    commonQueryReq.setScenicId(scenicId);
                    commonQueryReq.setStartTime(startTime);
                    commonQueryReq.setEndTime(endTime);
                    commonQueryReq.setRealtime(true);

                    // 执行统计查询
                    ApiResponse<AppStatisticsFunnelVO> resp = statisticsService.userConversionFunnel(commonQueryReq);
                    AppStatisticsFunnelVO data = resp.getData();

                    // 写入数据库（REPLACE INTO 会自动更新已存在的记录）
                    statisticsMapper.insertStat(scenicId, startTime, data);

                    // 删除该景区该日期的缓存，确保下次查询时获取最新数据
                    invalidateStatisticsCache(scenicId, startTime);
                } catch (Exception e) {
                    log.error("统计景区 {} 在日期 {} 的数据时发生错误", scenic.getId(), DateUtil.formatDate(startTime), e);
                }
            });

            log.info("第{}天前的数据统计完成，日期: {}", daysAgo, DateUtil.formatDate(startTime));
        }

        log.info("景区统计任务执行完成");
    }

    /**
     * 删除景区统计缓存
     * @param scenicId 景区ID
     * @param date 统计日期
     */
    private void invalidateStatisticsCache(Long scenicId, Date date) {
        String redisKey = String.format("statistics:tmp_cache:%s:%s",
                scenicId,
                DateUtil.formatDate(date));
        redisTemplate.delete(redisKey);
    }
}
