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

import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.workflow.cmd.GetAskForLeaveRecordListCmd;
import com.engine.attendance.workflow.cmd.GetKqCycleTimeIntervalCmd;
import com.engine.attendance.workflow.cmd.GetRestDayIntervalCmd;
import com.engine.attendance.workflow.service.AskForLeaveService;
import com.engine.common.exception.AttendanceRunTimeException;
import com.engine.common.util.DateUtil;
import com.engine.common.util.DbTools;
import com.engine.core.impl.Service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;

import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class AskForLeaveServiceImpl extends Service implements AskForLeaveService {

    @Override
    public Map<String, Object> getUesdHolidayItem(Map<String, Object> params) {
        Map<String,Object> resultMap = Maps.newHashMap();
        // 流程表单主表数据
        Map<String,String> mainTableData = (Map<String,String>)params.get("mainTableData");
        // 流程表单明细表1数据
        List<Map<String, String>> detailTableData = (List<Map<String, String>>)params.get("detailTableData");


        if (detailTableData == null || detailTableData.size() == 0){
            return Maps.newHashMap();
        }
        detailTableData = detailTableData.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("ksrq")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());


        //第一笔开始时间
        String firstStartDate = detailTableData.get(0).get("ksrq");

        //请假人员
        String qjry = mainTableData.get("qjry");
        //假期类型
        String jqlx = mainTableData.get("jqlx");

        String sql = "select id,mc,hsdw,hsl,jcbyxsyqjb,yxsydjb,qzsyyxjb from uf_jcl_kq_kqxm where id=?";

        Map<String,Object> holidayItem = DbTools.getSqlToMap(sql,jqlx);


        if (CheckBoxEnum.CHECKED.getKey().equals(holidayItem.get("qzsyyxjb")) &&
                CheckBoxEnum.CHECKED.getKey().equals(holidayItem.get("jcbyxsyqjb"))){
            Map<String,Object> holidayPriorityItem = DbTools.getSqlToMap(sql,holidayItem.get("yxsydjb"));

            sql = "select id,jqid,sxrq,ktsc,yxsc,wxsc,yqsxrq,ztsc from uf_jcl_kq_jqye where ygid=? and jqid=? and sxrq<=? and yqsxrq>=? order by sxrq";

            List<Map<String,Object>> holidayBalanceList = DbTools.getSqlToList(sql,qjry,holidayPriorityItem.get("id"),firstStartDate,firstStartDate);

            Map<String,Object> useItemMap = Maps.newHashMap();
            for (Map<String, String> detail:detailTableData){
                String ksrq = detail.get("ksrq");
                List<Map<String,Object>> list = holidayBalanceList.stream().filter(e-> DateUtil.getTime(e.get("yqsxrq").toString()).compareTo(DateUtil.getTime(ksrq))>=0).collect(Collectors.toList());
                log.info("ksrq : [{}], list : [{}]",ksrq,list);
                double totalUnearnedLeave = list.stream().mapToDouble(e->Double.valueOf(e.get("wxsc").toString())).sum();
                if (totalUnearnedLeave == 0){
                    List<Map<String,String>> details = (List<Map<String,String>>)useItemMap.get(holidayItem.get("id"));
                    if (details == null){
                        details = Lists.newArrayList();
                    }
                    details.add(detail);
                    useItemMap.put(holidayItem.get("id").toString(),details);
                }else {
                    List<Map<String,String>> details = (List<Map<String,String>>)useItemMap.get(holidayPriorityItem.get("id"));
                    if (details == null){
                        details = Lists.newArrayList();
                    }
                    details.add(detail);
                    useItemMap.put(holidayPriorityItem.get("id").toString(),details);
                }
            }
            //需要使用到2种以上假期
            if (useItemMap.size() > 1){
                throw new AttendanceRunTimeException("优先使用的"+holidayPriorityItem.get("mc")+"余额不足");
            }else {
                if (useItemMap.get(holidayPriorityItem.get("id")) != null){
                    resultMap.put("jqlx",holidayPriorityItem.get("id"));
                    resultMap.put("hsdw",holidayPriorityItem.get("hsdw"));
                    resultMap.put("hsl",holidayPriorityItem.get("hsl"));
                    resultMap.put("mc",holidayPriorityItem.get("mc"));
                    resultMap.put("jcbyxsyqjb",CheckBoxEnum.CHECKED.getKey());
                }else if (useItemMap.get(holidayItem.get("id")) != null){
                    resultMap.put("jqlx",jqlx);
                    resultMap.put("hsdw",holidayItem.get("hsdw"));
                    resultMap.put("hsl",holidayItem.get("hsl"));
                    resultMap.put("mc",holidayItem.get("mc"));
                    resultMap.put("jcbyxsyqjb",CheckBoxEnum.UNCHECKED.getKey());
                }
            }
        }else {
            resultMap.put("jqlx",jqlx);
            resultMap.put("hsdw",holidayItem.get("hsdw"));
            resultMap.put("hsl",holidayItem.get("hsl"));
            resultMap.put("mc",holidayItem.get("mc"));
            resultMap.put("jcbyxsyqjb",CheckBoxEnum.UNCHECKED.getKey());
        }

        return resultMap;
    }

    @Override
    public Map<String, Object> getAskForLeaveRecordList(Map<String, Object> params) {
        return commandExecutor.execute(new GetAskForLeaveRecordListCmd(params,user));
    }

    @Override
    public Map<String, Object> getRestDayInterval(Map<String, Object> params) {
        Map<String, Object> resultMap = Maps.newHashMap();
        String itemId = Util.null2String(params.get("itemId"));
        String sql = "select zdycrqqjndxxb from uf_jcl_kq_kqxm where id=?";
        List<Map<String,Object>> itemList = DbTools.getSqlToList(sql,itemId);
        String zdycrqqjndxxb = Util.null2String(itemList.get(0).get("zdycrqqjndxxb"));
        if (CheckBoxEnum.UNCHECKED.getKey().equals(zdycrqqjndxxb)){
            return resultMap;
        }
        return commandExecutor.execute(new GetRestDayIntervalCmd(params,user));
    }
}
