package com.common.schedule;

import com.common.service.PartitionTableService;
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 java.util.List;

@Component
public class PartitionTableSchedule {

    private static final Logger logger = LoggerFactory.getLogger(PartitionTableSchedule.class);

    @Autowired
    private PartitionTableService partitionTableService;

    // ============================================================
    //  原有定时任务 — 每月15日凌晨1点（CREATE TABLE ... PARTITION OF 方式）(取消）
    // ============================================================

    /**
     * 每月15日凌晨1点执行
     * cron表达式: 秒 分 时 日 月 周
     */
    //@Scheduled(cron = "0 0 1 15 * ?")
    public void createNextMonthPartitionTables() {
        logger.info("开始执行创建下个月分区表任务...");

        try {
            int partitionCount = partitionTableService.getNextMonthPartitionCount();
            logger.info("需要创建 {} 个分区表", partitionCount);

            partitionTableService.createNextMonthPartitionTable();

            logger.info("创建下个月分区表任务完成");
        } catch (Exception e) {
            logger.error("定时创建分区表任务失败: {}", e.getMessage(), e);
        }
    }

    // ============================================================
    //  新增定时任务 — 通过达梦存储过程预创建下月分区（凌晨2:00）
    //  涉及5个主表: alarm / alarm_visit / syslog_normal_data
    //              / syslog_normal_alarm / syslog_non_normal_message
    //  存储过程: CREATE_TABLE_DAILY_PARTITIONS
    // ============================================================

    /**
     * 每月15日凌晨2:00 — 预创建下月分区表
     * cron: 秒 分 时 日 月 周
     */
    @Scheduled(cron = "0 0 2 15 * ?")
    public void createNextMonthPartitionsOn15th() {
        executeMonthlyPartitionCreation("15日");
    }

    /**
     * 每月28日凌晨2:00 — 预创建下月分区表
     */
    @Scheduled(cron = "0 0 2 28 * ?")
    public void createNextMonthPartitionsOn28th() {
        executeMonthlyPartitionCreation("28日");
    }

    /**
     * 每月最后一天凌晨2:00 — 预创建下月分区表
     * Spring CronExpression 支持 L 表示最后一天
     */
    @Scheduled(cron = "0 0 2 L * ?")
    public void createNextMonthPartitionsOnLastDay() {
        executeMonthlyPartitionCreation("月末最后一天");
    }

    /**
     * 统一的月度分区创建执行逻辑
     * 通过达梦存储过程 CREATE_TABLE_DAILY_PARTITIONS 批量创建
     */
    private void executeMonthlyPartitionCreation(String triggerDesc) {
        logger.info("==================== 月度分区预创建任务触发 ====================");
        logger.info("触发时机: 每月{} 凌晨2:00", triggerDesc);

        try {
            partitionTableService.createNextMonthPartitionsByProcedure();
            logger.info("月度分区预创建任务执行完成 (触发: {})", triggerDesc);
        } catch (Exception e) {
            logger.error("月度分区预创建任务执行失败 (触发: {}), 错误: {}", triggerDesc, e.getMessage(), e);
        }

        logger.info("================================================================");
    }

    // ============================================================
    //  已注释的备选定时任务
    // ============================================================

    /**
     * 测试任务 - 每分钟执行一次（开发环境使用）
     * 生产环境注释或删除此方法
     */
    //@Scheduled(cron = "0 * * * * ?")
    public void testCreatePartitionTables() {
        logger.info("测试任务: 开始创建分区表...");
        partitionTableService.createNextMonthPartitionTable();
        logger.info("测试任务: 分区表创建完成");
    }

    /**
     * 每天检查第二天的分区表状态 - 凌晨2点执行
     */
    //@Scheduled(cron = "0 0 2 * * ?")
    public void checkTomorrowPartitionTable() {
        logger.info("开始检查第二天的分区表状态...");

        try {
            PartitionTableService.PartitionTableStatus status =
                    partitionTableService.checkTomorrowPartitionTable();

            if (status.isExists()) {
                logger.info("第二天分区表已存在: {}", status.getTableName());
            } else if (status.isCreated()) {
                logger.info("第二天分区表创建成功: {}", status.getTableName());
            } else {
                logger.warn("第二天分区表检查异常: {}", status.getMessage());
                // 这里添加告警通知，比如发送邮件、短信等
                //sendAlertNotification(status);
            }

        } catch (Exception e) {
            logger.error("检查第二天分区表失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 每周一检查未来7天的分区表状态
     */
    //@Scheduled(cron = "0 0 3 * * MON")
    public void checkNextWeekPartitionTables() {
        logger.info("开始检查未来7天的分区表状态...");

        try {
            List<PartitionTableService.PartitionTableStatus> statusList = partitionTableService.checkFuturePartitionTables(7);

            int missingCount = 0;
            for (PartitionTableService.PartitionTableStatus status : statusList) {
                if (!status.isExists()) {
                    missingCount++;
                    logger.warn("未来分区表缺失: {}", status.getTableName());
                }
            }

            if (missingCount > 0) {
                logger.warn("发现 {} 个未来分区表缺失", missingCount);
                // 可以触发自动创建或发送告警
            } else {
                logger.info("未来7天分区表状态正常");
            }

        } catch (Exception e) {
            logger.error("检查未来分区表失败: {}", e.getMessage(), e);
        }
    }

}