package com.engine.attendance.vacation.job.holidaygeneration.tactics;

import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.enums.QuotaChangeMethodEnum;
import com.engine.attendance.enums.StartingUnitEnum;
import com.engine.attendance.vacation.util.VocationCommonUtil;
import com.engine.common.util.DateUtil;
import com.google.common.collect.Maps;
import weaver.general.TimeUtil;
import weaver.general.Util;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

/**
 * 循环按间隔时长折算发放
 */
public class ByIntervalPayMentWay implements HolidayGenerationWay{
    @Override
    public boolean support(int personClassfiy) {
        if (personClassfiy == 2){
            return true;
        }
        return false;
    }

    @Override
    public Map<String,Object> compute(Map<String, Object> data) {
        String userId = Util.null2String(data.get("userId"));
        String releaseDate = Util.null2String(data.get("releaseDate"));
        String cover = Util.null2String(data.get("cover"));
        if ("".equals(releaseDate)) {
            releaseDate = DateUtil.getCurrentTime();
        }
        List<Map<String, Object>> vocationList = (List<Map<String, Object>>) data.get("vocationList");
        //起算日期
        String qsrq = Util.null2String(vocationList.get(0).get("qsrqValue"));
        //额度有效期间
        String edyxqsz = Util.null2String(vocationList.get(0).get("edyxqsz"));
        //额度有效期间单位
        String edyxq = Util.null2String(vocationList.get(0).get("edyxq"));
        //累计承认工龄月份数栏位值
        String ljcrglyfslwz = Util.null2String(vocationList.get(0).get("ljcrglyfslwzValue")).equals("")?"0":Util.null2String(vocationList.get(0).get("ljcrglyfslwzValue"));
        //依据字段
        String yjzd = Util.null2String(vocationList.get(0).get("yjzdValue"));
        //调整起算日期策略
        String dzqsrq = Util.null2String(vocationList.get(0).get("dzqsrq"));
        //分割日期
        String fgrq = Util.null2String(vocationList.get(0).get("fgrq"));
        //提前执行发放操作的天数
        int dqtqffts = Integer.valueOf(Util.null2String(vocationList.get(0).get("dqtqffts")));
        //执行发放的时间点
        String ffdtffsj = Util.null2String(vocationList.get(0).get("ffdtffsj"));
        //入职当期额度按比例折算
        String rzdqedablzs = Util.null2String(vocationList.get(0).get("rzdqedablzs"));
        //首次获得额度按比例折算
        String schdedablzs = Util.null2String(vocationList.get(0).get("schdedablzs"));
        //额度变更时额度处理方式
        String edbgsedclfs = Util.null2String(vocationList.get(0).get("edbgsedclfs"));
        //额度单位
        String eddw = Util.null2String(vocationList.get(0).get("edbgsedclfs"));
        //尾数处理
        String wscl = Util.null2String(vocationList.get(0).get("wscl"));
        //首次获得额度控制生效日期
        String schdedkzsxrq = Util.null2String(vocationList.get(0).get("schdedkzsxrq"));

        if ("".equals(qsrq)){
            return Maps.newHashMap();
        }
        qsrq = VocationCommonUtil.getAfterAdjustTime(qsrq, dzqsrq, fgrq);
        for (Map<String, Object> vocationMap : vocationList) {
            vocationMap.put("qsrqValue", qsrq);
        }

        if (DateUtil.getTime(releaseDate).compareTo(DateUtil.getTime(qsrq)) < 0){
            //releaseDate=qsrq;
            return Maps.newHashMap();
        }

        //相差天数
        int betweenDays = DateUtil.getBetWeenDays(qsrq, releaseDate.split(" ")[0]);
        //相差月份
        int betweenMonth = DateUtil.getBetWeenMonths(qsrq, releaseDate.split(" ")[0]);
        //总工龄天数
        int allWorkDays = Double.valueOf(ljcrglyfslwz).intValue() * 30 + betweenDays;
        //总月数
        int allMonths = betweenMonth + Double.valueOf(ljcrglyfslwz).intValue();

        Map<String, Object> insertHoliDayParam = VocationCommonUtil.getInsertHoliDayParam(vocationList.get(0), userId, qsrq, releaseDate);

        List<Map<String,Object>> dataList = VocationCommonUtil.ifexist("uf_jcl_kq_jqye", insertHoliDayParam);

        String sxrq = insertHoliDayParam.get("sxrq").toString();
        String jzrq = insertHoliDayParam.get("jzrq").toString();
        //实际休息时长
        double restTime = 0;

        //工龄小于1年的新员工,且额度有效期单位为自然年
        if (allMonths < 12 && edyxq.equals(StartingUnitEnum.NATURAL_YEAR.getKey())) {
            if (QuotaChangeMethodEnum.CONVERT.getKey().equals(edbgsedclfs) || CheckBoxEnum.CHECKED.getKey().equals(schdedablzs)) {
                restTime = getRestTime(insertHoliDayParam,vocationList,QuotaChangeMethodEnum.CONVERT,releaseDate,userId);
            }else {
                restTime = getRestTime(insertHoliDayParam,vocationList,QuotaChangeMethodEnum.NO_CONVERT,releaseDate,userId);
            }
            if (CheckBoxEnum.CHECKED.getKey().equals(schdedkzsxrq)) {
                int seniority = "".equals(ljcrglyfslwz)?0:Double.valueOf(ljcrglyfslwz).intValue();
                String divideTime = DateUtil.beforeMonth(qsrq,seniority);
                divideTime = sxrq.split("-")[0]+"-"+divideTime.split("-")[1]+"-"+divideTime.split("-")[2];
                insertHoliDayParam.put("sxrq", divideTime);
                dataList = VocationCommonUtil.ifexist("uf_jcl_kq_jqye", insertHoliDayParam);
                //已存在数据且不覆盖
                if (dataList.size()>0 && !"1".equals(cover)) {
                    return insertHoliDayParam;
                }
            }
            insertHoliDayParam.put("ktsc", restTime);
        }else if (allMonths >= 12 && edyxq.equals(StartingUnitEnum.NATURAL_YEAR.getKey())) {
            if (CheckBoxEnum.CHECKED.getKey().equals(rzdqedablzs) && betweenMonth < 12
                    && sxrq.split("-")[0].equals(releaseDate.split("-")[0]) && releaseDate.split("-")[0].equals(qsrq.split("-")[0])) {
                //入职不满一年，且入职当期额度按比例折算
                restTime = getRestTime(insertHoliDayParam,vocationList,QuotaChangeMethodEnum.CONVERT,releaseDate,userId);
            }else {
                if (QuotaChangeMethodEnum.CONVERT.getKey().equals(edbgsedclfs)) {
                    restTime = getRestTime(insertHoliDayParam,vocationList,QuotaChangeMethodEnum.CONVERT,releaseDate,userId);
                } else if (QuotaChangeMethodEnum.NO_CONVERT.getKey().equals(edbgsedclfs)) {
                    restTime = getRestTime(insertHoliDayParam,vocationList,QuotaChangeMethodEnum.NO_CONVERT,releaseDate,userId);
                }
            }

        }else if (edyxq.equals(StartingUnitEnum.STARTING_YEAR.getKey())) {
            //起算年
            String startTime = releaseDate.split("-")[0]+"-"+qsrq.split("-")[1]+"-"+qsrq.split("-")[2];
            String beforeEndTime = DateUtil.beforeDay(startTime,1);
            String criticalTime = DateUtil.beforeDay(beforeEndTime,dqtqffts+1);
            if (releaseDate.split(" ")[0].equals(criticalTime)){
                releaseDate = beforeEndTime;
            }
            int betweenYear = DateUtil.getBetWeenYears(qsrq,releaseDate.split(" ")[0]);
            allMonths = Double.valueOf(ljcrglyfslwz).intValue();
            int intervalYear = allMonths / 12+betweenYear;
            Map<String, Object> vocationMap = VocationCommonUtil.getVocationMap(vocationList, intervalYear, yjzd,userId);
            double edktsc = vocationMap.size()>0?Double.valueOf(vocationMap.get("edktsc").toString()):0;
            int days = 0;
            if (DateUtil.getTime(qsrq).compareTo(DateUtil.getTime(sxrq)) >=0){
                days = DateUtil.getBetWeenDays(qsrq,releaseDate.split(" ")[0])+1;
            }else {
                days = DateUtil.getBetWeenDays(sxrq,releaseDate.split(" ")[0])+1;
            }
            if (days<0){
                days = 0;
            }
            int yearDays = DateUtil.getDays(sxrq, Calendar.DAY_OF_YEAR);
            restTime=VocationCommonUtil.computeRestDays(days, yearDays, edktsc, wscl);

        } else if (edyxq.equals(StartingUnitEnum.NATURAL_MONTH.getKey())){
            //自然月
            int beforeDays = DateUtil.getDays(releaseDate,Calendar.DAY_OF_MONTH);
            String criticalTime = DateUtil.beforeDay(releaseDate.split("-")[0]+"-"+releaseDate.split("-")[1]+"-"+beforeDays,dqtqffts+1);
            if (releaseDate.split(" ")[0].equals(criticalTime)){
                releaseDate = releaseDate.split("-")[0]+"-"+releaseDate.split("-")[1]+"-"+beforeDays;
            }

            betweenMonth = DateUtil.getBetWeenMonths(qsrq,sxrq);

            allMonths = betweenMonth+Double.valueOf(ljcrglyfslwz).intValue();
            Map<String, Object> vocationMap = VocationCommonUtil.getVocationMap(vocationList, allMonths, yjzd,userId);
            int days = DateUtil.getBetWeenDays(sxrq,releaseDate.split(" ")[0])+1;
            if (days <0){
                days=0;
            }
            int monthDays = DateUtil.getDays(sxrq,Calendar.DAY_OF_MONTH);

            double edktsc = vocationMap.size()>0?Double.valueOf(vocationMap.get("edktsc").toString()):0;
            restTime = VocationCommonUtil.computeRestDays(days, monthDays, edktsc, wscl);

        } else if (edyxq.equals(StartingUnitEnum.STARTING_MONTH.getKey())){
            ///起算月
            String beforeEndTime = DateUtil.beforeDay(sxrq,1);
            String criticalTime = DateUtil.beforeDay(beforeEndTime,dqtqffts+1);
            if (releaseDate.split(" ")[0].equals(criticalTime)){
                releaseDate = beforeEndTime;
            }

            betweenMonth = DateUtil.getBetWeenMonths(qsrq,sxrq);
            allMonths = betweenMonth+Double.valueOf(ljcrglyfslwz).intValue();

            Map<String, Object> vocationMap = VocationCommonUtil.getVocationMap(vocationList, allMonths, yjzd,userId);
            double edktsc = vocationMap.size()>0?Double.valueOf(vocationMap.get("edktsc").toString()):0;
            int days = DateUtil.getBetWeenDays(sxrq,releaseDate.split(" ")[0])+1;
            if (days <0){
                days=0;
            }
            int monthDays = DateUtil.getBetWeenDays(sxrq,jzrq)+1;
            restTime = VocationCommonUtil.computeRestDays(days, monthDays, edktsc, wscl);

        } else if (edyxq.equals(StartingUnitEnum.NATURAL_WEEK.getKey())){
            //起自然周
            int dayOfWeek = TimeUtil.getDayOfWeek(releaseDate);
            if (dayOfWeek == 0){
                dayOfWeek = 7;
            }
            String time = releaseDate.split("-")[0]+"-"+releaseDate.split("-")[1] +"-"+releaseDate.split(" ")[0].split("-")[2];
            String beforeJxrq = DateUtil.AfterDay(time,8-dayOfWeek);
            String criticalTime = DateUtil.beforeDay(beforeJxrq,dqtqffts+1);
            if (releaseDate.split(" ")[0].equals(criticalTime)){
                releaseDate = beforeJxrq;
            }

            betweenDays = DateUtil.getBetWeenDays(qsrq,sxrq)+1;
            if (DateUtil.getTime(sxrq).compareTo(DateUtil.getTime(qsrq)) <=0){
                betweenDays = 0;
            }
            allWorkDays = Double.valueOf(ljcrglyfslwz).intValue()*30+betweenDays;
            Map<String, Object> vocationMap = VocationCommonUtil.getVocationMap(vocationList, allWorkDays/7, yjzd,userId);
            double edktsc = vocationMap.size()>0?Double.valueOf(vocationMap.get("edktsc").toString()):0;

            int days = DateUtil.getBetWeenDays(sxrq,releaseDate.split(" ")[0])+1;
            if (days <0){
                days=0;
            }
            int monthDays = 7;
            restTime = VocationCommonUtil.computeRestDays(days, monthDays, edktsc, wscl);

        } else if (edyxq.equals(StartingUnitEnum.STARTING_WEEK.getKey())){
            //起算周
            String time = releaseDate.split("-")[0]+"-"+releaseDate.split("-")[1] +"-"+releaseDate.split(" ")[0].split("-")[2];
            int day = DateUtil.getBetWeenDays(qsrq,time);
            int residueDays = day%7;
            String beforeSxrq = DateUtil.beforeDay(time,residueDays);
            String beforeEndTime = DateUtil.AfterDay(beforeSxrq,6);
            String criticalTime = DateUtil.beforeDay(beforeEndTime,dqtqffts+1);
            if (releaseDate.split(" ")[0].equals(criticalTime)){
                releaseDate = beforeEndTime;
            }

            betweenDays = DateUtil.getBetWeenDays(qsrq,sxrq)+1;
            if (betweenDays <=7){
                betweenDays=0;
            }
            allWorkDays = Double.valueOf(ljcrglyfslwz).intValue()*30+betweenDays;
            Map<String, Object> vocationMap = VocationCommonUtil.getVocationMap(vocationList, allWorkDays/7, yjzd,userId);
            int days = DateUtil.getBetWeenDays(sxrq,releaseDate.split(" ")[0])+1;
            if (days <0){
                days=0;
            }
            double edktsc = vocationMap.size()>0?Double.valueOf(vocationMap.get("edktsc").toString()):0;
            int monthDays = 7;
            restTime = VocationCommonUtil.computeRestDays(days, monthDays, edktsc, wscl);

        } else if (edyxq.equals(StartingUnitEnum.NATURAL_DAY.getKey())){
            //自然天
            betweenDays = DateUtil.getBetWeenDays(qsrq,sxrq)+1;
            allWorkDays = Double.valueOf(ljcrglyfslwz).intValue()*30+betweenDays;
            Map<String, Object> vocationMap = VocationCommonUtil.getVocationMap(vocationList, allWorkDays, yjzd,userId);
            restTime = vocationMap.size()>0?Double.valueOf(vocationMap.get("edktsc").toString()):0;
        }
        insertHoliDayParam.put("ktsc", restTime);

        VocationCommonUtil.updateHolidayBalance("uf_jcl_kq_jqye", insertHoliDayParam,dataList);

        return insertHoliDayParam;
    }

    public double getRestTime(Map<String, Object> insertHoliDayParam,List<Map<String, Object>> vocationList,QuotaChangeMethodEnum changeMethodEnum,String releaseDate,String userId){
        String sxrq = insertHoliDayParam.get("sxrq").toString();
        String qsrq = Util.null2String(vocationList.get(0).get("qsrqValue"));
        String nextSxrq = DateUtil.nextYear(sxrq,1,DateUtil.yyyyMMdd);
        //累计承认工龄月份数栏位值
        String ljcrglyfslwz = Util.null2String(vocationList.get(0).get("ljcrglyfslwzValue"));
        //依据字段
        String yjzd = Util.null2String(vocationList.get(0).get("yjzdValue"));
        //尾数处理
        String wscl = Util.null2String(vocationList.get(0).get("wscl"));
        //提前执行发放操作的天数
        int dqtqffts = Integer.valueOf(Util.null2String(vocationList.get(0).get("dqtqffts")));
        //执行发放的时间点
        String ffdtffsj = Util.null2String(vocationList.get(0).get("ffdtffsj"));

        int seniority = "".equals(ljcrglyfslwz)?0:Double.valueOf(ljcrglyfslwz).intValue();

        String nowEndYearTime = releaseDate.split("-")[0]+"-12-31";
        if (DateUtil.getTime(releaseDate).compareTo(DateUtil.getTime(sxrq)) <0){
            return 0;
        }
        //临界时间点，直接发放全年
        String criticalTime = DateUtil.beforeDay(nowEndYearTime,dqtqffts+1);
        if (releaseDate.split(" ")[0].equals(criticalTime)){
            releaseDate = nowEndYearTime;
        }

        int yearDays = DateUtil.getDays(sxrq, Calendar.DAY_OF_YEAR);

        double restTime=0.0;
        //折算
        if (changeMethodEnum == QuotaChangeMethodEnum.CONVERT){
            int beginYearMonth = DateUtil.getBetWeenMonths(qsrq,sxrq);
            if (beginYearMonth < 0){
                beginYearMonth = 0;
            }
            beginYearMonth =  beginYearMonth+seniority;
            int endYearMonth = DateUtil.getBetWeenMonths(qsrq,nextSxrq);
            endYearMonth = endYearMonth+seniority;
            int beginYear = beginYearMonth/12;
            int endYear = endYearMonth/12;
            Map<String,Object> beginYearmap = VocationCommonUtil.getVocationMap(vocationList, beginYear, yjzd,userId);
            Map<String,Object> endYearmap = VocationCommonUtil.getVocationMap(vocationList, endYear, yjzd,userId);
            double beginEdktsc = Double.valueOf(beginYearmap.get("edktsc") == null?  "0" :Util.null2String(beginYearmap.get("edktsc")));
            double endEdktsc = Double.valueOf(endYearmap.get("edktsc") == null?  "0" :Util.null2String(endYearmap.get("edktsc")));

            //残年分割日期
            String divideTime = DateUtil.beforeMonth(qsrq,seniority);
            divideTime = sxrq.split("-")[0]+"-"+divideTime.split("-")[1]+"-"+divideTime.split("-")[2];

            //当前后额定可休时长一样时，代表没有残年情况
            if (beginEdktsc == endEdktsc){
                if (DateUtil.getTime(qsrq).compareTo(DateUtil.getTime(sxrq)) >0){
                    //新员工入职
                    int days = DateUtil.getBetWeenDays(qsrq,releaseDate.split(" ")[0])+1;
                    restTime = VocationCommonUtil.computeRestDays(days, yearDays, endEdktsc, wscl);
                }else {
                    int days = DateUtil.getTime(releaseDate).getDayOfYear();
                    restTime = VocationCommonUtil.computeRestDays(days, yearDays, endEdktsc, wscl);
                }
            }else {
                //考虑残年
                if (DateUtil.getTime(qsrq).compareTo(DateUtil.getTime(sxrq)) >0){
                    //新员工入职
                    if (DateUtil.getTime(divideTime).compareTo(DateUtil.getTime(qsrq)) >=0){
                        if (DateUtil.getTime(releaseDate).compareTo(DateUtil.getTime(divideTime)) >=0){
                            int beforeDays = DateUtil.getBetWeenDays(qsrq,divideTime);
                            double beforeRestTime = VocationCommonUtil.computeRestDays(beforeDays, yearDays, beginEdktsc, wscl);

                            int afterDays = DateUtil.getBetWeenDays(divideTime,releaseDate.split(" ")[0])+1;
                            double afterRestTime = VocationCommonUtil.computeRestDays(afterDays, yearDays, endEdktsc, wscl);
                            restTime = beforeRestTime+afterRestTime;
                        }else {
                            int beforeDays = DateUtil.getBetWeenDays(qsrq,releaseDate.split(" ")[0])+1;
                            restTime = VocationCommonUtil.computeRestDays(beforeDays, yearDays, beginEdktsc, wscl);
                        }
                    }else {
                        int afterDays = DateUtil.getBetWeenDays(qsrq,releaseDate.split(" ")[0])+1;
                        restTime = VocationCommonUtil.computeRestDays(afterDays, yearDays, endEdktsc, wscl);
                    }
                }else {
                    if (DateUtil.getTime(releaseDate).compareTo(DateUtil.getTime(divideTime)) >=0){
                        int beforeDays = DateUtil.getBetWeenDays(sxrq,divideTime);
                        double beforeRestTime = VocationCommonUtil.computeRestDays(beforeDays, yearDays, beginEdktsc, wscl);

                        int afterDays = DateUtil.getBetWeenDays(divideTime,releaseDate.split(" ")[0])+1;
                        double afterRestTime = VocationCommonUtil.computeRestDays(afterDays, yearDays, endEdktsc, wscl);
                        restTime = beforeRestTime+afterRestTime;
                    }else {
                        int beforeDays = DateUtil.getBetWeenDays(sxrq,releaseDate.split(" ")[0])+1;
                        restTime = VocationCommonUtil.computeRestDays(beforeDays, yearDays, beginEdktsc, wscl);
                    }
                }
            }

        }else {
            //不折算
            int beginYearMonth = DateUtil.getBetWeenMonths(qsrq,sxrq);
            if (beginYearMonth < 0){
                beginYearMonth = 0;
            }
            beginYearMonth =  beginYearMonth+seniority;
            int beginYear = beginYearMonth/12;
            Map<String,Object> beginYearmap = VocationCommonUtil.getVocationMap(vocationList, beginYear, yjzd,userId);
            double beginEdktsc = Double.valueOf(beginYearmap.get("edktsc") == null?  "0" :Util.null2String(beginYearmap.get("edktsc")));
            int days = 0;
            if (DateUtil.getTime(qsrq).compareTo(DateUtil.getTime(sxrq)) >=0){
                days = DateUtil.getBetWeenDays(qsrq,releaseDate.split(" ")[0])+1;
            }else {
                days = DateUtil.getBetWeenDays(sxrq,releaseDate.split(" ")[0])+1;
            }
            restTime=VocationCommonUtil.computeRestDays(days, yearDays, beginEdktsc, wscl);
        }
        return restTime;
    }


}
