package com.chinaweal.aiccs.common.util;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.chinaweal.aiccs.aiccs.system.entity.HolidayInfo;
import com.chinaweal.aiccs.aiccs.system.service.IHolidayInfoService;
import com.chinaweal.youfool.framework.springboot.util.SpringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 工作日工具类
 *
 * @author ymc
 * @since 2024年07月02日 16:57
 */
@Component
public class HolidaysUtil {

    private static HolidaysUtil _THIS;

    // 使用CopyOnWriteArrayList以确保线程安全
    private volatile static List<HolidayInfo> holidays = new CopyOnWriteArrayList<>();

    @Autowired
    private IHolidayInfoService iHolidayInfoService;

    public static void flushCache() {
        synchronized (HolidaysUtil.class) {
            holidays.clear();
            loadHolidaysFromDatabase();
        }
    }

    public static List<HolidayInfo> getHolidays() {
        return holidays;
    }

    /**
     * 从数据库加载节假日/工作日信息
     *
     * @return
     * @author ymc
     * @since 2024年7月23日 20:04
     */
    private static void loadHolidaysFromDatabase() {
        holidays = _THIS.iHolidayInfoService.lambdaQuery()
                .eq(HolidayInfo::getIsDisabled, false)
                .ge(HolidayInfo::getYear, DateUtil.year(new Date()))
                .list();
    }

    /**
     * 获取工作日截止时间
     *
     * @param numDays
     * @return
     * @author ymc
     * @since 2024年7月3日 15:46
     */
    public static LocalDateTime getNextWorkingDay(int numDays) {
        return getNextWorkingDay(DateUtil.date(), numDays);
    }

    /**
     * 获取工作日截止时间（起算点为收到申请之日的次日）
     *
     * @param startDate 开始日期
     * @param numDays   工作日数，可以是正数或负数
     * @return
     * @author ymc
     * @since 2024年7月2日 18:56
     */
    public static LocalDateTime getNextWorkingDay(Date startDate, int numDays) {
        if (numDays == 0) return null; // 如果numDays为0，直接返回null或进行其他处理

        List<Date> workingDays = new ArrayList<>();
        Date currentDate = startDate;
        boolean currentDateIsWorkingDay = isWorkingDay(currentDate);
        boolean isNegative = numDays < 0;  // 是否负数

        if (isNegative) numDays = -numDays; // 转换为正数方便处理
        if (currentDateIsWorkingDay) numDays = numDays + 1;
        while (workingDays.size() < numDays) {
            if (isWorkingDay(currentDate)) {
                workingDays.add(currentDate);
            }
            // 向前移动一天 or 向后移动一天
            currentDate = DateUtil.offsetDay(currentDate, isNegative ? -1 : 1);
        }

        // 返回workingDays最后一条数据，设置当天最大时间
        if (!workingDays.isEmpty()) {
            LocalDateTime localDateTime = DateUtil.parseLocalDateTime(DateUtil.formatDate(workingDays.get(workingDays.size() - 1)), DatePattern.NORM_DATE_PATTERN);
            localDateTime = localDateTime.withHour(23).withMinute(59).withSecond(59);
            return localDateTime;
        }
        return null;
    }

    /**
     * 计算两个日期相差多少个工作日
     * @author ymc
     * @since 2024年7月24日 20:10
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getWorkingDaysBetweenDates(Date startDate, Date endDate) {
        // 节假日天数
        int holidays = 0;
        boolean isNegative = startDate.after(endDate);
        if (isNegative) {
            Date temp = startDate;
            startDate = endDate;
            endDate = temp;
        }
        int days = (int) DateUtil.between(startDate, endDate, DateUnit.DAY);
        while (!startDate.after(endDate)) {
            if (!isWorkingDay(startDate)) {
                holidays++;
            }
            startDate = DateUtil.offsetDay(startDate, 1);
        }
        return days - holidays;
    }

    /**
     * 是否为工作日
     *
     * @param date
     * @return
     * @author ymc
     * @since 2024年7月2日 19:59
     */
    public static boolean isWorkingDay(Date date) {
        // 获取节假日列表
        List<String> holidays_jj = holidays.stream()
                .filter(holidayInfo -> "1".equals(holidayInfo.getType()))
                .map(HolidayInfo::getHolidayDate).collect(Collectors.toList());

        // 获取工作日列表
        List<String> holidays_nm = holidays.stream()
                .filter(holidayInfo -> "2".equals(holidayInfo.getType()))
                .map(HolidayInfo::getHolidayDate).collect(Collectors.toList());

        if (holidays_nm.contains(DateUtil.formatDate(date))) {
            return true;
        } else {
            return !DateUtil.isWeekend(date) && !holidays_jj.contains(DateUtil.formatDate(date));
        }
    }

    public static void main(String[] args) {
        System.out.println(getNextWorkingDay(5));
        System.out.println(DateUtil.between(DateUtil.parse("2024-07-31 23:59:59"), DateUtil.parse("2024-07-25 13:59:59"), DateUnit.DAY));
        System.out.println(getWorkingDaysBetweenDates(DateUtil.parse("2024-07-25 13:59:59"), DateUtil.parse("2024-07-31 23:59:59")));
    }

    @PostConstruct
    public void init() {
        _THIS = this;
        loadHolidaysFromDatabase();
    }

//    static {
//        initializeHolidays();
//    }

//    private static void initializeHolidays() {
//        // 节假日
//        holidays.add(new HolidayInfo().setHolidayName("中秋节假期").setHolidayDate("2024-09-16").setType("1").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("中秋节假期").setHolidayDate("2024-09-17").setType("1").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("国庆假期").setHolidayDate("2024-10-01").setType("1").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("国庆假期").setHolidayDate("2024-10-02").setType("1").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("国庆假期").setHolidayDate("2024-10-03").setType("1").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("国庆假期").setHolidayDate("2024-10-04").setType("1").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("国庆假期").setHolidayDate("2024-10-07").setType("1").setYear(2024));
//
//        // 工作日
//        holidays.add(new HolidayInfo().setHolidayName("中秋节补班").setHolidayDate("2024-09-14").setType("2").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("国庆补班").setHolidayDate("2024-09-29").setType("2").setYear(2024));
//        holidays.add(new HolidayInfo().setHolidayName("国庆补班").setHolidayDate("2024-10-12").setType("2").setYear(2024));
//    }
}
