package com.engine.attendance.workflow.service.impl;

import com.engine.attendance.workflow.service.EnterpriseCalendarService;
import com.engine.common.util.*;
import com.engine.core.impl.Service;
import com.ibm.icu.util.ChineseCalendar;
import weaver.general.BaseBean;
import weaver.general.Util;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: sy
 * @Description: 企业日历实现类
 * @Date: 2024/4/19
 **/
public class EnterpriseCalendarServiceImpl extends Service implements EnterpriseCalendarService {
    BaseBean bs = new BaseBean();
    @Override
    public Map<String, Object> initCalendar(Map<String, Object> params) {
        String yearStr = Util.null2String(params.get("year"));
        String calendarId = Util.null2String(params.get("calendarId"));
        int year = Integer.parseInt(yearStr);
        //查询所属机构
        String sql = "select * from uf_jcl_kq_rlmc where id = " + calendarId;
        Map<String,Object> data = DbTools.getSqlToMap(sql);
        //所属机构
        String org = Util.null2String(data.get("szjg"));
        //单双休设置相关信息
        //单双休设置，标准双休-0，单双休-1，单休-2
        String restDaySetting = Util.null2String(data.get("dxzsz"));
        //双周休息日，周一-周日，0-6
        String doubleRestDays = Util.null2String(data.get("dzxxr"));
        //单周休息日，周一-周日，0-6
        String singleRestDays = Util.null2String(data.get("xzxxr"));
        //单双休轮转设置，先单后双-0，先双后单-1
        String restDayTransSetting = Util.null2String(data.get("dxzz"));
        //是否按上一年继续轮转
        String transContinue= Util.null2String(data.get("asynjx"));
        //在单双周轮换时，判断第一周的休息日情况
        boolean doubleRestSign = true;
        if (restDaySetting.equals("1")) {
            doubleRestSign = restDayTransSetting.equals("1");
            if (transContinue.equals("1")) {
                doubleRestSign = checkFirstWeekRest(year, calendarId, doubleRestSign);
            }
        }

        //查询formmodeid
        Map<String,String> formModeIdMap = Utils.getFormmodeIdMap();
        String formModeId = formModeIdMap.get("uf_jcl_kq_rlxx");
        Calendar calendar = Calendar.getInstance();
        List<Map<String, Object>> dateInfoList = new ArrayList<>();
        Map<String, Object> dateInfo;
        for (int i = 1; i <= 12; i++) {
            calendar.set(year, i - 1, 1);
            int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

            for (int day = 0; day < daysInMonth; day++) {
                dateInfo = new HashMap<>();
                dateInfo = createDateInfo(calendar);
                dateInfo.put("formmodeid",formModeId);
                dateInfo.put("modeuuid", UUID.randomUUID().toString());
                dateInfo.put("modedatacreater","1");
                dateInfo.put("modedatacreatertype","0");
                dateInfo.put("modedatacreatedate", DateUtil.getCurrentTime().split(" ")[0]);
                dateInfo.put("modedatacreatetime",DateUtil.getCurrentTime().split(" ")[1]);
                dateInfo.put("rlmc", calendarId);
                dateInfo.put("nd", yearStr);
                dateInfo.put("szjg", org);
                //判断日历设置是否有单双休相关数值，并修改日期类型
                //双休时，判断双休休息日是否包括当前日期的星期值，休息日类型低于节假日类型
                if ("0".equals(restDaySetting) && doubleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                    dateInfo.put("rqlx", "2");
                }
                //单休时，判断单休休息日是否包括当前日期的星期值，休息日类型低于节假日类型
                else if ("2".equals(restDaySetting) && singleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                    dateInfo.put("rqlx", "2");
                }
                //单双休时，判断当前周是单休还是双休，并在各自得情况下判断休息日是否包括当前日期的星期值，休息日类型低于节假日类型
                else if ("1".equals(restDaySetting)) {
                    if (doubleRestSign && doubleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                        dateInfo.put("rqlx", "2");
                    } else if (!doubleRestSign && singleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                        dateInfo.put("rqlx", "2");
                    }
                    //单双休时，每一周都要轮换单双休状态
                    if ("6".equals(dateInfo.get("xq"))) {
                        doubleRestSign = !doubleRestSign;
                    }
                }
                dateInfoList.add(dateInfo);
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
        }
        //删除老数据
        String delSql = "delete from uf_jcl_kq_rlxx where rlmc = " + calendarId + " and nd = " + yearStr;
        boolean delSign = DbTools.update(delSql);
        bs.writeLog("delSign : " +  delSign + ", delSql : " + delSql);
        //插入新数据
        String tableName = "uf_jcl_kq_rlxx";
        if (dateInfoList.size() > 0) {
            bs.writeLog("入库开始---");
            boolean insertSign = CommonUtil.insertBatch(dateInfoList, tableName);
            bs.writeLog("insertSign : " + insertSign);
        }
        return new HashMap<>();
    }

    private boolean checkFirstWeekRest(int year, String calendarId, boolean doubleRestSign) {
        Calendar calendar =Calendar.getInstance();
        calendar.set(year, Calendar.JANUARY, 1);
        String firstDayWeek = getWeek(calendar);
        int lastYear = year -1;
        int firstIndex = Integer.parseInt(firstDayWeek);
        //获取目标年度第一天所在周的之前的一周日期
        List<String> lastWeekDays = new ArrayList<>();
        for (int i = 1; i <= 7; i++) {
            lastWeekDays.add(lastYear + "-12-" + (31 - firstIndex));
            firstIndex++;
        }
        //查询上一步中查询的日期中有几个公休日
        String sql = "select * from uf_jcl_kq_rlxx where rlmc = " + calendarId + " and nd =" + lastYear+ " and rq in ('"+String.join("','",lastWeekDays)+"')";
        List<Map<String,Object>> data = DbTools.getSqlToList(sql);
        int restDayNum = 0;
        if (data.size() > 0) {
            for (Map<String,Object> map : data) {
                if (Util.null2String(map.get("rqlx")).equals("2")) {
                    restDayNum++;
                }
            }
            return restDayNum < 2;
        } else {
            return doubleRestSign;
        }
    }

    private Map<String, Object> createDateInfo(Calendar calendar) {
        Map<String, Object> dateInfo = new HashMap<>();
        // 获取阳历年-月-日
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 使用SimpleDateFormat格式化Calendar中的日期
        String solarDate  = sdf.format(calendar.getTime());
        //获取农历日期
        LunarCalendar lunarCalendar = new LunarCalendar(calendar);
        String lunarDate = lunarCalendar.traditionLunarDay();
        //获取目标日期是周几, 此功能中周一-周日为0-6
        String weekIndex = getWeek(calendar);
        //获取日期特定名称，节气或节日
        String specialDay = "";
        //判断日期是否为节气
        SolarTermsUtil solarTermsUtil = new SolarTermsUtil(calendar);
        String termInfo = solarTermsUtil.getSolartermsMsg();
        if (!termInfo.equals("")) {
            specialDay = termInfo.replace(" ", "");
        }
        //判断日期是否为节日
        String holidayInfo = getHolidayInfo(calendar, lunarCalendar);
        if (!holidayInfo.equals("")) {
            specialDay = specialDay + holidayInfo;
        }
        //判断日期类型
        String dayType = getDayType(weekIndex, specialDay);
        dateInfo.put("rq", solarDate);
        dateInfo.put("nlrq", lunarDate);
        dateInfo.put("xq", weekIndex);
        dateInfo.put("mc", specialDay.equals("") ? null : specialDay);
        dateInfo.put("rqlx", dayType);
        return dateInfo;
    }

    private String getDayType(String weekIndex, String specialDay) {
        String dayType = "0";
        List<String> realHolidayList = new ArrayList<>();
        realHolidayList.add("春节");
        realHolidayList.add("元旦节");
        realHolidayList.add("劳动节");
        realHolidayList.add("国庆节");
        realHolidayList.add("端午节");
        realHolidayList.add("中秋节");
        realHolidayList.add("清明");
        for (String holiday : realHolidayList) {
            if (specialDay.contains(holiday)) {
                dayType = "1";
                break;
            }
        }
//        if (!"1".equals(dayType)) {
//            if ("5".equals(weekIndex) || "6".equals(weekIndex)) {
//                dayType = "2";
//            }
//        }
        return dayType;
    }

    private String getHolidayInfo(Calendar calendar, LunarCalendar lunarCalendar) {
        String holidayInfo = "";
        //公历节日
        int solarMonth = calendar.get(Calendar.MONTH) + 1; // Calendar.MONTH 从0开始计数
        int solarDay = calendar.get(Calendar.DAY_OF_MONTH);
        if (solarMonth == 1 && solarDay == 1) {
            holidayInfo = holidayInfo + "元旦节";
        }
        if (solarMonth == 2 && solarDay == 14) {
            holidayInfo = holidayInfo + "情人节";
        }
        if (solarMonth == 3 && solarDay == 8) {
            holidayInfo = holidayInfo + "妇女节";
        }
        if (solarMonth == 3 && solarDay == 12) {
            holidayInfo = holidayInfo + "植树节";
        }
        if (solarMonth == 4 && solarDay == 1) {
            holidayInfo = holidayInfo + "愚人节";
        }
        if (solarMonth == 5 && solarDay == 1) {
            holidayInfo = holidayInfo + "劳动节";
        }
        if (solarMonth == 5 && solarDay == 4) {
            holidayInfo = holidayInfo + "中国青年节";
        }
        if (solarMonth == 6 && solarDay == 1) {
            holidayInfo = holidayInfo + "儿童节";
        }
        if (solarMonth == 7 && solarDay == 1) {
            holidayInfo = holidayInfo + "建党节";
        }
        if (solarMonth == 8 && solarDay == 1) {
            holidayInfo = holidayInfo + "建军节";
        }
        if (solarMonth == 9 && solarDay == 10) {
            holidayInfo = holidayInfo + "教师节";
        }
        if (solarMonth == 10 && solarDay == 1) {
            holidayInfo = holidayInfo + "国庆节";
        }
        //农历节日，春节
        int lunarMonth = lunarCalendar.getMonth();
        int lunarDay = lunarCalendar.getDay();

        if (lunarMonth == 1 && lunarDay == 1) {
            holidayInfo = holidayInfo + "春节";
        }
        if (lunarMonth == 1 && lunarDay == 15) {
            holidayInfo = holidayInfo + "元宵节";
        }
        if (lunarMonth == 5 && lunarDay == 5) {
            holidayInfo = holidayInfo + "端午节";
        }
        if (lunarMonth == 7 && lunarDay == 7) {
            holidayInfo = holidayInfo + "七夕节";
        }
        if (lunarMonth == 8 && lunarDay == 15) {
            holidayInfo = holidayInfo + "中秋节";
        }
        if (lunarMonth == 9 && lunarDay == 9) {
            holidayInfo = holidayInfo + "重阳节";
        }
        //除夕特殊处理
        if (lunarMonth == 12) {
            int monthDays = LunarCalendar.monthDays(lunarCalendar.getYear(), lunarMonth);
            if (monthDays == lunarDay) {
                holidayInfo = holidayInfo + "除夕";
            }
        }
        return holidayInfo;
    }

    //根据日期取得星期几，
    public static String getWeek(Calendar cal){
        //日历详细表中字段xq枚举值与该方法中的周几值存在差值，故存在相关处理逻辑
        int weekIndex = cal.get(Calendar.DAY_OF_WEEK) - 2;
        if(weekIndex<0){
            weekIndex = 6;
        }
        return String.valueOf(weekIndex);
    }
}
