package com.jiayue.ipfcst.common.data.service.uploadfilerule;

import com.jiayue.ipfcst.common.core.util.DateMomentUtil;
import com.jiayue.ipfcst.common.data.constant.enums.AlarmTypeEnum;
import com.jiayue.ipfcst.common.data.constant.enums.HolidayTypeEnum;
import com.jiayue.ipfcst.common.data.entity.HolidayCalendar;
import com.jiayue.ipfcst.common.data.repository.HolidayCalendarRepository;
import com.jiayue.ipfcst.common.data.repository.SysParameterRepository;
import com.jiayue.ipfcst.common.data.service.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.stereotype.Service;

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

@Service
@Slf4j
public class CalculateHolidayFileDays extends BaseService {
  private final HolidayCalendarRepository holidayCalendarRepository;

  public CalculateHolidayFileDays(HolidayCalendarRepository holidayCalendarRepository) {
    this.holidayCalendarRepository = holidayCalendarRepository;
  }


  /**
   * 获取短期N+1数据天数
   *
   * @param systemDate 系统日期
   * @return 查询数据的天数
   */
  public int calculateDQDataDays(Date systemDate) {
    long todayTime = DateMomentUtil.getDayStartTime(systemDate.getTime());
    // 获取日历中所有记录
    List<HolidayCalendar> holidayCalendarList = holidayCalendarRepository.findAll();
    // 今日是否假期，false为工作日。
    boolean currentDayIsHoliday = false;
    // 第二天是否假期，false为工作日。
    boolean secondDayIsHoliday = false;
    // 计算出第二天的日期
    Long secondDay = DateMomentUtil.getDayStartTime(DateUtils.addDays(systemDate, 1).getTime());

    for (HolidayCalendar holidayCalendar : holidayCalendarList) {
      Long startTime = holidayCalendar.getStartTime();
      Long endTime = holidayCalendar.getEndTime();
      //类型 1假期 2特殊工作日【只可以是礼拜六和礼拜日】
      HolidayTypeEnum holidayType = holidayCalendar.getHolidayTypeEnum();
      if (startTime <= todayTime && endTime >= todayTime && "E1".equals(holidayType.name())) {
        // 今日是假期
        currentDayIsHoliday = true;
      }
      if (startTime <= secondDay && endTime >= secondDay && "E1".equals(holidayType.name())) {
        // 第二天是假期
        secondDayIsHoliday = true;
      }
    }
    // 定义数据天数变量
    int dataDays = 0;
    if (!currentDayIsHoliday && secondDayIsHoliday) {
      // 今日是工作日并且第二天开始是假期，遍历第二天三天四天等等，直到工作日结束。
      while (true) {
        HolidayCalendar compareHolidayCalendar = null;
        for (HolidayCalendar holidayCalendar : holidayCalendarList) {
          if (holidayCalendar.getStartTime() <= secondDay && holidayCalendar.getEndTime() >= secondDay && "E1".equals(holidayCalendar.getHolidayTypeEnum().name())) {
            // 对类型是假期的，并且在假期中的日期进行天数累加。
            dataDays++;
            // 此对象用于退出while循环是使用
            compareHolidayCalendar = holidayCalendar;
            // 重新计算下一天的时间
            secondDay = secondDay + 1000 * 60 * 60 * 24;
            break;
          }
        }
        if (compareHolidayCalendar == null) {
          // 遇到工作日时，退出while循环。
          dataDays++;
          break;
        }
      }
    }
    //获取短期天数
    try {
      String fileDqDays = super.getSysParameter("FILE_FORECAST_DAYS", "3");
      int dqSysParameter = Integer.parseInt(fileDqDays);
      if (dataDays < dqSysParameter) {
        dataDays = dqSysParameter;
      }
    } catch (RuntimeException e) {
      String errorInfo = "计算假期获取参数的短期天数失败" + e.getMessage();
      log.error(errorInfo, e);
      // 进行告警
      String name = "计算假期获取参数的短期天数失败";
      String describe = "参数表FILE_FORECAST_DAYS 获取失败";
      String solution = "使用默认值3天";
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
      // 获取参数异常时，使用默认值3天
      dataDays = 3;
    }
    return dataDays;
  }

  /**
   * 获取计划数据天数
   *
   * @param systemDate 系统日期
   * @return 查询数据的天数
   */
  public int calculateJHDataDays(Date systemDate) {
    long todayTime = DateMomentUtil.getDayStartTime(systemDate.getTime());
    // 获取日历中所有记录
    List<HolidayCalendar> holidayCalendarList = holidayCalendarRepository.findAll();
    // 今日是否生成文件，true为生成。
    boolean todayGenerateFile = true;
    // 今日是否特殊工作日，false为不是特殊日。
    boolean todaySpecialWorkDay = false;
    // 下一天是否特殊工作日，false为不是特殊日。
    boolean nextSpecialWorkDay = false;
    // 计算下一天的日期
    Long secondDay = DateMomentUtil.getDayStartTime(DateUtils.addDays(systemDate, 1).getTime());
    // 循环获取条件变量
    for (HolidayCalendar holidayCalendar : holidayCalendarList) {
      Long startTime = holidayCalendar.getStartTime();
      Long endTime = holidayCalendar.getEndTime();
      // 获取日历中的数据类型 1假期 2特殊工作日【只可以是礼拜六和礼拜日】
      HolidayTypeEnum holidayType = holidayCalendar.getHolidayTypeEnum();
      if (startTime <= todayTime && endTime >= todayTime) {
        if ("E1".equals(holidayType.name())) {
          // 今日是假期，将变量设置成false，代表不生成文件。
          todayGenerateFile = false;
        } else {
          // 今日是特殊日。
          todaySpecialWorkDay = true;
        }
      }
      if (startTime <= secondDay && endTime >= secondDay && "E2".equals(holidayType.name())) {
        // 第二天是特殊工作日
        nextSpecialWorkDay = true;
      }
    }
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(todayTime);
    if ((cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) && todaySpecialWorkDay == false) {
      todayGenerateFile = false;
    }

    // 定义数据天数变量
    int dataDays = 0;
    if (todayGenerateFile || todaySpecialWorkDay) {
      // 生成文件
      if (!nextSpecialWorkDay) {
        // 遍历第二天三天四天等等，直到工作日结束。
        while (true) {
          HolidayCalendar compareHolidayCalendar = null;
          for (HolidayCalendar holidayCalendar : holidayCalendarList) {
            if (holidayCalendar.getStartTime() <= secondDay && holidayCalendar.getEndTime() >= secondDay) {
              // 获取下一天的日历对象
              compareHolidayCalendar = holidayCalendar;
              break;
            }
          }
          if (compareHolidayCalendar != null) {
            if ("E2".equals(compareHolidayCalendar.getHolidayTypeEnum().name())) {
              // 特殊工作日
              dataDays++;
              break;
            }
          } else {
            // 如果第二天是周六或者周日
            cal.setTimeInMillis(secondDay);
            if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
              dataDays++;
              break;
            }
          }
          // 假期
          dataDays++;
          secondDay = secondDay + 1000 * 60 * 60 * 24;
        }
      }

      try {
        // 第二天是特殊工作日，生成第二天的数据,天数从参数获取

        String filePowerplanDays = super.getSysParameter("FILE_POWERPLAN_DAYS", "1");
        int jhSysParameter = Integer.parseInt(filePowerplanDays);
        if (dataDays < jhSysParameter) {
          dataDays = jhSysParameter;
        }
      } catch (RuntimeException e) {
        String errorInfo = "计算计划获取参数的天数失败" + e.getMessage();
        log.error(errorInfo, e);
        // 进行告警
        String name = "计算计划获取参数的天数失败";
        String describe = "参数表FILE_POWERPLAN_DAYS获取失败";
        String solution = "使用默认值1天";
        super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
        // 获取参数异常时，使用默认值1天
        dataDays = 1;
      }
    }
    return dataDays;
  }
}
