package com.engine.attendance.vacation.cmd;

import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.common.util.DateUtil;
import com.engine.common.util.DbTools;
import com.engine.common.util.Utils;
import com.engine.core.interceptor.CommandContext;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
public class HandleOverdueVocationCmd extends AbstractCommonCommand<Map<String,Object>> {
    public HandleOverdueVocationCmd(Map<String,Object> params){
        this.params=params;
    }

    @Override
    public BizLogContext getLogContext() {
        return null;
    }

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {
        String releaseDate = Util.null2String(params.get("releaseDate"));
        if ("".equals(releaseDate)){
            releaseDate = DateUtil.getCurrentDate();
        }
        String sql = "select a.id,a.jqid,a.ygid,a.wxsc,a.zfsc,a.sxrq,a.jzrq,a.yqsxrq,b.jb,b.jywxcl,b.yqsc,b.edkyqcs,b.yqhedzgxz from uf_jcl_kq_jqye a left join uf_jcl_kq_jqed b on a.jqid=b.jb where a.wxsc>0";
        List<Map<String,Object>> holidayBalanceList =  DbTools.getSqlToList(sql);

        //需要作废的假期余额
        String finalReleaseDate = releaseDate;
        List<String> needCancelHolidayIds = holidayBalanceList.parallelStream().filter(e->"0".equals(e.get("jywxcl")) && DateUtil.getTime(finalReleaseDate).compareTo(DateUtil.getTime(e.get("yqsxrq").toString())) >0).map(e->e.get("id").toString()).collect(Collectors.toList());
        //需要延长的假期余额
        List<Map<String,Object>> needExtendHolidayList = holidayBalanceList.parallelStream().filter(e->"1".equals(e.get("jywxcl"))&& DateUtil.getTime(finalReleaseDate).compareTo(DateUtil.getTime(e.get("yqsxrq").toString())) >0 && needExtend(e)).collect(Collectors.toList());
        //正在生效的假期余额
        holidayBalanceList = holidayBalanceList.parallelStream().filter(e->DateUtil.getTime(finalReleaseDate).compareTo(DateUtil.getTime(e.get("yqsxrq").toString())) <=0).collect(Collectors.toList());

        Map<String,List<Map<String,Object>>> holidayBalanceGroup = holidayBalanceList.stream().collect(Collectors.groupingBy(e->e.get("ygid")+"&"+e.get("jqid")));

        /**
         * 作废过期假期余额
         */
        sql = "update uf_jcl_kq_jqye set zfsc=wxsc,wxsc=0  where id in (";
        List<List<String>> needCancelPartions = Lists.partition(needCancelHolidayIds,200);
        for (List<String> list : needCancelPartions){
            String updateSql = sql+String.join(",",list)+")";
            log.info("needCancelPartions updateSql : [{}]",updateSql );
            DbTools.update(updateSql);
        }
        Map<String,List<String>> updateData = Maps.newHashMap();
        /**
         * 获得需要延长失效时间的假期余额
         */
        for (Map<String,Object> needExtendHoliday:needExtendHolidayList){
            //失效日期
            String jzrq = Util.null2String(needExtendHoliday.get("jzrq"));
            //延期失效日期
            String yqsxrq = Util.null2String(needExtendHoliday.get("yqsxrq"));
            //延期后额度上限值
            double yqhedzgxz =Utils.convertDouble(needExtendHoliday.get("yqhedzgxz"));
            //延期时间
            String yqsc = Util.null2String(needExtendHoliday.get("yqsc"));
            //未休时长
            double wxsc = Utils.convertDouble(needExtendHoliday.get("wxsc"));
            //作废时长
            double zfsc = Utils.convertDouble(needExtendHoliday.get("zfsc"));

            String jqid = Util.null2String(needExtendHoliday.get("jqid"));

            String ygid = Util.null2String(needExtendHoliday.get("ygid"));

            int betweenMonths = DateUtil.getBetWeenMonths(jzrq,yqsxrq);
            //目前延期的次数
            int nowtimes = betweenMonths/getMonth(yqsc)+1;

            int needExtendMonth = nowtimes*getMonth(yqsc);
            //最终延期日期
            String finalyqsxrq = DateUtil.nextMonth(jzrq,needExtendMonth,DateUtil.yyyyMMdd);

            List<Map<String,Object>> havedHoliday = holidayBalanceGroup.get(ygid+"&"+jqid);
            //需要延期的未休时长
            double needExtendWxsc = wxsc;
            //需要作废的未休时长
            double needzfsc = zfsc;
            if (havedHoliday != null && havedHoliday.size() > 0){
                double havedHolidayTime = havedHoliday.stream().mapToDouble(e->Utils.convertDouble(e.get("wxsc"))).sum();
                if (havedHolidayTime+wxsc > yqhedzgxz){
                    needExtendWxsc=Utils.subtract(yqhedzgxz,havedHolidayTime);
                    if (needExtendWxsc < 0){
                        needExtendWxsc = 0;
                    }
                    needzfsc = needzfsc+ Utils.subtract(wxsc,needExtendWxsc);
                }
            }
            String key = finalyqsxrq+"&"+wxsc+"&"+needzfsc;
            List<String> idList = updateData.get(key);
            if (idList == null){
                idList = Lists.newArrayList();
                updateData.put(key,idList);
            }
            idList.add(needExtendHoliday.get("id").toString());
        }
        sql = "update uf_jcl_kq_jqye set yqsxrq=?,wxsc=?,zfsc=? where id in (";
        for (Map.Entry<String,List<String>> entry: updateData.entrySet()){
            String key = entry.getKey();
            List<String> ids = entry.getValue();
            List<List<String>> needExtendPartions = Lists.partition(ids,200);
            for (List<String> list : needExtendPartions){
                String updateSql = sql+String.join(",",list)+")";
                log.info("needExtendPartions updateSql : [{}]",updateSql);
                DbTools.update(updateSql,key.split("&")[0],key.split("&")[1],key.split("&")[2]);
            }
        }

        return null;
    }

    public boolean needExtend(Map<String,Object> dataMap){
        //额度可延期次数
        int edkyqcs = Integer.valueOf(Util.null2String(dataMap.get("edkyqcs")));

        int times = getExtendTimes(dataMap);
        return times<edkyqcs;
    }

    //获得已延期多少次
    public int getExtendTimes(Map<String,Object> dataMap){
        //失效日期
        String jzrq = Util.null2String(dataMap.get("jzrq"));
        //延期失效日期
        String yqsxrq = Util.null2String(dataMap.get("yqsxrq"));
        //延期时长
        String yqsc = Util.null2String(dataMap.get("yqsc"));

        int betweenMonths = DateUtil.getBetWeenMonths(jzrq,yqsxrq);

        int time = betweenMonths/getMonth(yqsc);

        return time;
    }

    public int getMonth(String yqsc){
        int month = 0;
        if (yqsc.equals("0")){
            month=1;
        }else if (yqsc.equals("1")){
            month=2;
        }else if (yqsc.equals("2")){
            month=3;
        }else if (yqsc.equals("3")){
            month=6;
        }else if (yqsc.equals("4")){
            month=12;
        }
        return month;
    }
}
