package com.engine.attendance.workflow.action.askforleave;

import com.engine.attendance.enums.AccountingUnitEnum;
import com.engine.attendance.enums.CheckBoxEnum;
import com.engine.attendance.workflow.enums.AskAndEvctionWayEnum;
import com.engine.attendance.workflow.service.MakeUpClockInService;
import com.engine.attendance.workflow.service.impl.MakeUpClockInServiceImpl;
import com.engine.common.util.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class AskForLeaveWorkFlowSubmitAction implements Action {
    private MakeUpClockInService makeUpClockInService = ServiceUtil.getService(MakeUpClockInServiceImpl.class);

    @Override
    public String execute(RequestInfo requestInfo) {
        String requestid = requestInfo.getRequestid();

        try {

            // 流程表单主表数据
            HashMap<String, String> mainTableData = CommonUtil.getMainTableInfo(requestInfo);
            log.info("mainTableData : [{}]", mainTableData);
            // 流程表单明细表1数据
            List<Map<String, String>> detailTableData = CommonUtil.getDetailTableInfo(requestInfo, 0);
            log.info("detailTableData : [{}]", detailTableData);

            String detail2TableName = requestInfo.getDetailTableInfo().getDetailTable()[1].getTableDBName();
            log.info("detail2TableName : [{}]", detail2TableName);
            //请假人员
            String qjry = mainTableData.get("qjry");
            //实际假期类型
            String jqlx = mainTableData.get("sjqjlx");
            //第一笔开始时间
            String firstStartDate = detailTableData.get(0).get("ksrq");

            List<Map<String, Object>> detailTable2 = Lists.newArrayList();

            /**
             * 考勤周期校验
             */

            Map<String, Object> params = Maps.newHashMap();
            params.put("userId", qjry);
            params.put("submitDate", DateUtil.getCurrentDate());

            Map<String, Object> dataMap = makeUpClockInService.getKqCycleTimeIntervalCmd(params);

            List<Map<String, Object>> dateList = (List<Map<String, Object>>) dataMap.get("data");

            boolean status = (boolean) dataMap.get("status");
            if (!status) {
                log.error("该人员没有考勤周期");
                requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
                requestInfo.getRequestManager().setMessagecontent("该人员没有考勤周期！");
                return Action.FAILURE_AND_CONTINUE;
            }
            if (dateList.size() == 0) {
                log.error("申请人员当前时间没有考勤周期，请联系管理员！");
                requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
                requestInfo.getRequestManager().setMessagecontent("申请人员当前时间没有考勤周期，请联系管理员！");
                return Action.FAILURE_AND_CONTINUE;
            }

            for (Map<String, String> detailTable : detailTableData) {
                String bdkrq = detailTable.get("ksrq");
                boolean mark = true;
                for (Map<String, Object> date : dateList) {
                    //存在考勤周期内
                    String startDate = Util.null2String(date.get("startDate"));
                    String endDate = Util.null2String(date.get("endDate"));
                    if (DateUtil.getTime(startDate).compareTo(DateUtil.getTime(bdkrq)) <= 0 &&
                            DateUtil.getTime(endDate).compareTo(DateUtil.getTime(bdkrq)) >= 0) {
                        mark = false;
                    }
                }
                if (mark) {
                    //已关账
                    log.error("请假日期:{}，已关账无法提交", bdkrq);
                    requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
                    requestInfo.getRequestManager().setMessagecontent("请假日期:" + bdkrq + "不在当前月份对应考勤周期内无法再提交请假！");
                    return Action.FAILURE_AND_CONTINUE;
                }
            }


            /**
             * 假期校验及入库
             */
            String 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, jqlx, firstStartDate, firstStartDate);

            Map<String, Object> holidayBalanceMap = holidayBalanceList.stream().collect(Collectors.toMap(e -> e.get("id").toString(), e -> e));

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

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

            //假期核算单位
            String hsdw = Util.null2String(holidayItem.get("hsdw"));
            //请假方式
            String cxjqj = mainTableData.get("cxjqj");

            for (Map<String, String> detailData : detailTableData) {
                String ksrq = detailData.get("ksrq");
                //请假时间
                double leaveDuration = 0;
                if (cxjqj.equals(AskAndEvctionWayEnum.ALLDAY.getKey())) {
                    leaveDuration = 1;
                } else if (cxjqj.equals(AskAndEvctionWayEnum.HALFDAY.getKey())) {
                    leaveDuration = 0.5;
                } else if (cxjqj.equals(AskAndEvctionWayEnum.TIME_INTERVAL.getKey()) || cxjqj.equals(AskAndEvctionWayEnum.HOUR.getKey())) {
                    leaveDuration = Double.valueOf(Util.null2String(detailData.get("qjsc")));
                }
                if (hsdw.equals(AccountingUnitEnum.HOUR.getKey()) && (cxjqj.equals(AskAndEvctionWayEnum.ALLDAY.getKey()) || cxjqj.equals(AskAndEvctionWayEnum.HALFDAY.getKey()))) {
                    leaveDuration = leaveDuration * 8;
                }
                log.info("leaveDuration : [{}]", leaveDuration);
                List<Map<String, Object>> holidayBalancefilterList = holidayBalanceList.stream().filter(e -> DateUtil.getTime(e.get("yqsxrq").toString()).compareTo(DateUtil.getTime(ksrq)) >= 0).collect(Collectors.toList());
                for (Map<String, Object> holidayBalance : holidayBalancefilterList) {
                    //额定未休时长
                    double wxsc = holidayBalance.get("wxsc") == null ? 0 : Double.valueOf(holidayBalance.get("wxsc").toString());
                    if (leaveDuration > 0) {
                        Map<String, Object> detail2Map = Maps.newHashMap();
                        detail2Map.put("glmxid", detailData.get("id"));
                        detail2Map.put("jqye", holidayBalance.get("id"));
                        detail2Map.put("mainid", mainTableData.get("id"));
                        detail2Map.put("glrq", detailData.get("ksrq"));
                        if (leaveDuration > wxsc) {
                            detail2Map.put("sysc", wxsc);
                            leaveDuration = Utils.subtract(leaveDuration, wxsc);
                            wxsc = 0;
                        } else {
                            detail2Map.put("sysc", leaveDuration);
                            leaveDuration = 0;
                            wxsc = Utils.subtract(wxsc, leaveDuration);
                        }
                        detailTable2.add(detail2Map);
                        holidayBalance.put("wxsc", wxsc);
                    }
                }
                if (leaveDuration > 0) {
                    //假期余额不足
                    String message = ksrq + "对应的" + holidayItem.get("mc") + "假期余额不足！";
                    log.error(message);
                    requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
                    requestInfo.getRequestManager().setMessagecontent(message);
                    return Action.FAILURE_AND_CONTINUE;
                }
            }
            log.info("detailTable2 : [{}]", detailTable2);

            //更新流程明细表2
            String delteSql = "delete from " + detail2TableName + " where mainid=?";
            DbTools.update(delteSql, requestid);
            if (!CommonUtil.insertBatch(detailTable2, detail2TableName)) {
                //更新流程明细表2失败
                String message = "更新流程明细表2失败";
                log.error(message);
                requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
                requestInfo.getRequestManager().setMessagecontent(message);
                return Action.FAILURE_AND_CONTINUE;
            }

            //更新假期余额在途时长
            Map<String, Object> balanceMap = Maps.newHashMap();
            for (Map<String, Object> data : detailTable2) {
                String jqye = Util.null2String(data.get("jqye"));
                double sysc = Double.valueOf(data.get("sysc").toString());
                double havedSysc = balanceMap.get(jqye) == null ? 0 : Double.valueOf(balanceMap.get(jqye).toString());
                sysc = Utils.add(sysc, havedSysc);
                balanceMap.put(jqye, sysc);
            }
            for (Map.Entry<String, Object> entry : balanceMap.entrySet()) {
                String id = entry.getKey();
                double ztsc = Double.valueOf(entry.getValue().toString());
                Map<String, Object> map = (Map<String, Object>) holidayBalanceMap.get(id);

                double havedztsc = Util.null2String(map.get("ztsc")).equals("") ? 0 : Double.valueOf(map.get("ztsc").toString());
                double havedwxsc = Util.null2String(map.get("wxsc")).equals("") ? 0 : Double.valueOf(map.get("wxsc").toString());

                double updatedztsc = Utils.add(havedztsc, ztsc);
                double updatedwxsc = Utils.subtract(havedwxsc, ztsc);

                String updateSql = "update uf_jcl_kq_jqye set wxsc=?,ztsc=? where id=?";
                if (!DbTools.update(updateSql, updatedwxsc, updatedztsc, id)) {
                    //更新假期余额失败
                    String message = "更新假期余额失败";
                    log.error(message);
                    requestInfo.getRequestManager().setMessageid("11111" + requestid + "22222");
                    requestInfo.getRequestManager().setMessagecontent(message);
                    return Action.FAILURE_AND_CONTINUE;
                }
            }
        }catch (Exception e){
            log.error("AskForLeaveWorkFlowSubmitAction error : [{}]",e);
            return Action.FAILURE_AND_CONTINUE;
        }

        return Action.SUCCESS;
    }
}
