package com.fs.app.task;

import com.fs.app.taskService.SopLogsTaskService;
import com.fs.common.core.redis.RedisCache;
import com.fs.course.mapper.FsCourseWatchLogMapper;
import com.fs.course.mapper.FsUserCourseVideoMapper;
import com.fs.course.service.IFsCourseLinkService;
import com.fs.common.utils.redis.RedisActiveKeyIndexRepairService;
import com.fs.course.service.IFsCourseWatchLogService;
import com.fs.sop.mapper.QwSopLogsMapper;
import com.fs.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.concurrent.atomic.AtomicBoolean;

@Component
@Slf4j
public class CourseWatchLogScheduler {
    private final AtomicBoolean isRunning1 = new AtomicBoolean(false);

    private final AtomicBoolean isRunning2 = new AtomicBoolean(false);

    private final AtomicBoolean isRunning3 = new AtomicBoolean(false);

    private final AtomicBoolean isRunning4 = new AtomicBoolean(false);

    @Autowired
    private FsCourseWatchLogMapper courseWatchLogMapper;

    @Autowired
    private QwSopLogsMapper qwSopLogsMapper;

    @Autowired
    RedisCache redisCache;

    @Autowired
    private RedisActiveKeyIndexRepairService redisActiveKeyIndexRepairService;

    @Autowired
    private FsUserCourseVideoMapper courseVideoMapper;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IFsCourseWatchLogService courseWatchLogService;

    @Autowired
    private SopLogsTaskService sopLogsTaskService;

//    // 定时任务批量更新到数据库
//    @Scheduled(fixedRate = 60000) // 每分钟执行一次
//    public void scheduleBatchUpdateToDatabase() {
//        courseWatchLogService.scheduleBatchUpdateToDatabase();
//    }



//    /**
//     * 检查看课状态
//     */
//    @Scheduled(fixedRate = 60000) // 每分钟执行一次
//    public void checkWatchStatus() {
//        // 尝试设置标志为 true，表示任务开始执行
//        if (!isRunning1.compareAndSet(false, true)) {
//            log.warn("检查看课中任务执行 - 上一个任务尚未完成，跳过此次执行");
//            return;
//        }
//        try {
//            log.info("检查看课中任务执行>>>>>>>>>>>>");
//            courseWatchLogService.scheduleBatchUpdateToDatabase();
////            courseWatchLogService.scheduleBatchUpdateToDatabaseIsOpen();
//            courseWatchLogService.checkWatchStatus();
//            log.info("检查看课中任务执行完成>>>>>>>>>>>>");
//        }catch (Exception e) {
//            log.error("检查看课中任务执行完成 - 定时任务执行失败", e);
//        } finally {
//            // 重置标志为 false，表示任务已完成
//            isRunning1.set(false);
//        }
//
//    }


    @Scheduled(fixedRate = 60000) // 每分钟执行一次
    public void checkWatchStatus() {
        // 尝试设置标志为 true，表示任务开始执行
        if (!isRunning1.compareAndSet(false, true)) {
            log.info("检查看课中任务执行 - 上一个任务尚未完成，跳过此次执行");
            return;
        }

        try {
            log.info("检查看课中任务执行>>>>>>>>>>>>");
            courseWatchLogService.scheduleBatchUpdateToDatabase();
            courseWatchLogService.checkWatchStatus();
            log.info("检查看课中任务执行完成>>>>>>>>>>>>");

            // 检查当前时间是否为整五分钟（0, 5, 10, 15, ... 55分钟）
            Calendar calendar = Calendar.getInstance();
            int minute = calendar.get(Calendar.MINUTE);

            // 只有当分钟数是5的倍数时才执行创建完课消息
            if (minute % 5 == 0) {
                try {
                    long startTime = System.currentTimeMillis();
                    log.info("创建完课消息 - 定时任务开始"+System.currentTimeMillis());
                    sopLogsTaskService.createCourseFinishMsg();
                    long endTime = System.currentTimeMillis();
                    long duration = endTime - startTime;
                    log.info("创建完课消息 - 定时任务成功完成"+duration);
                } catch (Exception e) {
                    log.error("创建完课消息 - 定时任务执行失败", ExceptionUtils.getStackTrace(e));
                }
            }
        } catch (Exception e) {
            log.error("检查看课中任务执行完成 - 定时任务执行失败", ExceptionUtils.getStackTrace(e));
        } finally {
            // 重置标志为 false，表示任务已完成
            isRunning1.set(false);
        }
    }



    /**
     * 创建完课消息
     * 注释原因：与checkWatchStatus()中的创建完课消息逻辑重复，导致生成两条相同记录
     * 已改为在checkWatchStatus()方法中每5分钟触发一次
     */
//    @Scheduled(fixedRate = 300000) // 每五分钟执行一次
//    public void createCourseFinishMsg() {
//        // 尝试设置标志为 true，表示任务开始执行
//        if (!isRunning3.compareAndSet(false, true)) {
//            log.warn("创建完课消息 - 上一个任务尚未完成，跳过此次执行");
//            return;
//        }
//
//        try {
//            log.info("创建完课消息 - 定时任务开始");
//            sopLogsTaskService.createCourseFinishMsg();
//            log.info("创建完课消息 - 定时任务成功完成");
//        } catch (Exception e) {
//            log.error("创建完课消息 - 定时任务执行失败", e);
//        } finally {
//            // 重置标志为 false，表示任务已完成
//            isRunning3.set(false);
//        }
//
//    }

    @Autowired
    private IFsCourseLinkService courseLinkService;


    // 定时任务，每天0点执行

    /**
     * 每天删除过期短链
     */
    @Scheduled(cron = "0 0 0 * * ?")  // 0点0分0秒执行
    public void delCourseExpireLink() {
        try {
            log.info("删除过期短链 - 定时任务开始");
            courseLinkService.delCourseExpireLink();
            log.info("删除过期短链 - 定时任务成功完成");
        } catch (Exception e) {
            log.error("删除过期短链 - 定时任务执行失败", e);
        }

    }

    @Scheduled(fixedRate = 30000) // 每30s执行一次
    public void checkFsUserWatchStatus() {
        // 尝试设置标志为 true，表示任务开始执行
        if (!isRunning4.compareAndSet(false, true)) {
            log.warn("WXH5-检查会员看课中任务执行 - 上一个任务尚未完成，跳过此次执行");
            return;
        }
        try {
            log.info("WXH5-检查会员看课中任务执行>>>>>>>>>>>>");
            courseWatchLogService.scheduleUpdateDurationToDatabase();
            courseWatchLogService.checkFsUserWatchStatus();
            log.info("WXH5-检查会员看课中任务执行完成>>>>>>>>>>>>");
        }catch (Exception e) {
            log.error("WXH5-检查会员看课中任务执行完成 - 定时任务执行失败", e);
        } finally {
            // 重置标志为 false，表示任务已完成
            isRunning4.set(false);
        }

    }

    /**
     * 每天凌晨 1 点：SCAN 修补活跃 key 索引（与业务 track 配合，兜底漏登记/发版空窗）
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void repairRedisActiveKeyIndexes() {
        try {
            redisActiveKeyIndexRepairService.repairAllIndexes();
        } catch (Exception e) {
            log.error("Redis 活跃 key 索引修补定时任务失败", e);
        }
    }

}
