package com.heyu.api.schedule;

import com.heyu.api.data.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.quartz.CronExpression;
import org.quartz.TriggerUtils;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.scheduling.support.CronSequenceGenerator;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Slf4j
public class CronTriggerUtils {


    /**
     * @param cronExpression cron表达式
     * @param numTimes       下一(几)次运行的时间
     * @return
     */
    public static Date getNextExecTime(String cronExpression) {
        CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
        try {
            cronTriggerImpl.setCronExpression(cronExpression);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 这个是重点，一行代码搞定
        List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 1);
        for (Date date : dates) {
            return date;
        }
        return null;
    }


    /**
     * @param cronExpression cron表达式
     * @param numTimes       下一(几)次运行的时间
     * @return
     */
    public static Date getCurrentExecTime(String cronExpression) {
        CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cronExpression);
        Date lastMinute = DateUtils.getBeforeMinute(new Date(), 1);
        Date nextTriggerTime = cronSequenceGenerator.next(lastMinute);//lastMinute 我这里是上一分钟的date类型对象
        return nextTriggerTime;
    }

    /**
     * @param cronExpression cron表达式
     * @param numTimes       下一(几)次运行的时间
     * @return
     */
    public static List<String> getNextsExecTime(String cronExpression, Integer numTimes) {
        List<String> list = new ArrayList<>();
        CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
        try {
            cronTriggerImpl.setCronExpression(cronExpression);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 这个是重点，一行代码搞定
        List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, numTimes);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Date date : dates) {
            list.add(dateFormat.format(date));
        }
        return list;
    }


    public static String cronCurrentDate(Date currentDate, String cronExpression) {
        try {
            TimeLevelEnums enums = TimeLevelEnums.getTimeLevel(cronExpression);
            System.out.println(enums);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (TimeLevelEnums.years.equals(enums)) {
                Date date = DateUtils.formateDate(currentDate, "yyyy-00-00 00:00:00");
                return dateFormat.format(date);
            } else if (TimeLevelEnums.months.equals(enums)) {
                Date date = DateUtils.formateDate(currentDate, "yyyy-MM-00 00:00:00");
                return dateFormat.format(date);
            } else if (TimeLevelEnums.days.equals(enums)) {
                Date date = DateUtils.formateDate(currentDate, "yyyy-MM-dd 00:00:00");
                return dateFormat.format(date);
            } else if (TimeLevelEnums.hours.equals(enums)) {
                Date date = DateUtils.formateDate(currentDate, "yyyy-MM-dd HH:00:00");
                return dateFormat.format(date);
            } else if (TimeLevelEnums.minutes.equals(enums)) {
                Date date = DateUtils.formateDate(currentDate, "yyyy-MM-dd HH:mm:00");
                return dateFormat.format(date);
            } else if (TimeLevelEnums.seconds.equals(enums)) {
                Date date = DateUtils.formateDate(currentDate, "yyyy-MM-dd HH:mm:ss");
                return dateFormat.format(date);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;

    }




    public static boolean isRun(Date date, String cronExpression) {
        try {

            CronExpression cronMonth = new CronExpression(cronExpression);
            if (cronMonth.isSatisfiedBy(date)) {
                return true;
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return false;
    }



    @Test
    public void test1() {

        String cronExpression = "0 0 12 * * ?";

     //   String currentDate = cronCurrentDate(new Date(), cronExpression);

//        System.out.println(currentDate);


        Date date = DateUtils.parseDate("2025-10-19 12:01:00");

        System.out.println(isRun(date, cronExpression));
    }


    /***
     * https://help.aliyun.com/document_detail/133509.html
     *
     */
    //             示例
    //                      */5 * * * * ?：每隔 5 秒执行一次
    //
    //                      0 */1 * * * ?：每隔 1 分钟执行一次
    //
    //                      0 0 2 1 * ?：每月 1 日的凌晨 2 点执行一次
    //
    //                      0 15 10 ? * MON-FRI：周一到周五每天上午 10：15 执行作业
    //
    //                      0 15 10 ? 6L 2002-2006：2002 年至 2006 年的每个月的最后一个星期五上午 10:15 执行作业
    //
    //                      0 0 23 * * ?：每天 23 点执行一次
    //
    //                      0 0 1 * * ?：每天凌晨 1 点执行一次
    //
    //                      0 0 1 1 * ?：每月 1 日凌晨 1 点执行一次
    //
    //                      0 0 23 L * ?：每月最后一天 23 点执行一次
    //
    //                      0 0 1 ? * L：每周星期天凌晨 1 点执行一次
    //
    //                      0 26,29,33 * * * ?：在 26 分、29 分、33 分执行一次
    //
    //                      0 0 0,13,18,21 * * ?：每天的 0 点、13 点、18 点、21 点都执行一次
    //
    //                      0 0 10,14,16 * * ?：每天上午 10 点，下午 2 点，4 点执行一次
    //
    //                      0 0/30 9-17 * * ?：朝九晚五工作时间内每半小时执行一次
    //
    //                      0 0 12 ? * WED：每个星期三中午 12 点执行一次
    //
    //                      0 0 12 * * ?：每天中午 12 点触发
    //
    //                      0 15 10 ? * *：每天上午 10:15 触发
    //
    //                      0 15 10 * * ?：每天上午 10:15 触发
    //
    //                      0 15 10 * * ? *：每天上午 10:15 触发
    //
    //                      0 15 10 * * ? 2005：2005 年的每天上午 10:15 触发
    //
    //                      0 * 14 * * ?：每天下午 2 点到 2:59 期间的每 1 分钟触发
    //
    //                      0 0/5 14 * * ?：每天下午 2 点到 2:55 期间的每 5 分钟触发
    //
    //                      0 0/5 14,18 * * ?：每天下午 2 点到 2:55 期间和下午 6 点到 6:55 期间的每 5 分钟触发
    //
    //                      0 0-5 14 * * ?：每天下午 2 点到 2:05 期间的每 1 分钟触发
    //
    //                      0 10,44 14 ? 3 WED：每年三月的星期三的下午 2:10 和 2:44 触发
    //
    //                      0 15 10 ? * MON-FRI：周一至周五的上午 10:15 触发
    //
    //                      0 15 10 15 * ?：每月 15 日上午 10:15 触发
    //
    //                      0 15 10 L * ?：每月最后一日的上午 10:15 触发
    //
    //                      0 15 10 ? * 6L：每月的最后一个星期五上午 10:15 触发
    //
    //                      0 15 10 ? * 6L 2002-2005：2002 年至 2005 年的每月的最后一个星期五上午 10:15 触发
    //
    //                      0 15 10 ? * 6#3：每月的第三个星期五上午 10:15 触发
    public static void main(String[] args) throws Exception {
        String cronExpression = "0 0 23 * * ?";
        CronExpression cronMonth = new CronExpression(cronExpression);
        Date date = DateUtils.formateDate(new Date(), "yyyy-MM-dd HH:mm:00");

        System.out.println("xxxxxxxxxx" + date);


        Date nextTunTime = CronTriggerUtils.getCurrentExecTime(cronExpression);

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(TimeLevelEnums.getTimeLevel(cronExpression));
        CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cronExpression);
        for (int i = 0; i < 10; i++) {
            System.out.println(df.format(nextTunTime));
            Date nextTriggerTime = cronSequenceGenerator.next(nextTunTime);//lastMinute 我这里是上一分钟的date类型对象
            nextTunTime = nextTriggerTime;
        }

        if (cronMonth.isSatisfiedBy(date)) {
            System.out.println("xxxxxxxx");
        }


    }


}
