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


import com.engine.attendance.attendanceanalysis.cmd.item.AbsenteeismItemCmd;
import com.engine.attendance.attendanceanalysis.cmd.item.BeLateItemCmd;
import com.engine.attendance.attendanceanalysis.service.AllowanceService;
import com.engine.attendance.enums.*;
import com.engine.common.util.DateUtil;
import com.engine.common.util.DbTools;
import com.engine.common.util.Utils;
import com.engine.core.impl.Service;
import com.google.common.collect.Maps;
import weaver.general.Util;

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

public class AllowanceServiceImpl extends Service implements AllowanceService {

    @Override
    public Map<String, Object> allowanceHandle(Map<String, Object> param) {
        String userId = Util.null2String(param.get("userId"));
        String analysisDate = Util.null2String(param.get("analysisDate"));

        Map<String,Object> resultMap = Maps.newHashMap();
        String sql = "select jtlx,sc,zt from uf_jcl_kq_cqjt where zt=1 and yg=? and rq=?";
        List<Map<String,Object>> allowanceList = DbTools.getSqlToList(sql,userId,DateUtil.beforeDay(analysisDate,1));
        if (allowanceList.size() == 0){
            return resultMap;
        }
        Set<String> allowances = allowanceList.stream().map(e-> e.get("jtlx").toString()).collect(Collectors.toSet());
        Map<String,List<Map<String,Object>>> allowanceGroupByList = allowanceList.stream().collect(Collectors.groupingBy(e->e.get("jtlx").toString()));
        sql = "select * from uf_jcl_kq_kqxm where id in ("+String.join(",",allowances)+")";
        List<Map<String,Object>> itemList = DbTools.getSqlToList(sql);
        Map<String,List<Map<String,Object>>> itemGroupbyList = itemList.stream().collect(Collectors.groupingBy(e->e.get("id").toString()));


        allowanceGroupByList.entrySet().forEach(e -> {
            String jtlx = e.getKey();
            List<Map<String,Object>> list = e.getValue();
            Map<String,Object> item = itemGroupbyList.get(jtlx).get(0);
            String csjthdclfs = Util.null2String(item.get("csjthdclfs"));
            String tcscws = Util.null2String(item.get("tcscws"));
            String hsdw = Util.null2String(item.get("hsdw"));
            if ("1".equals(csjthdclfs)){
                //次日免班
                resultMap.put("ifnotWork","true");
            }else if ("2".equals(csjthdclfs)){
                //推迟上班
                double scsum = list.stream().mapToDouble(f->Double.valueOf(f.get("sc").toString())).sum();
                scsum = Utils.converTimeToMinute(scsum,hsdw);
                double multiple = Double.valueOf(tcscws);
                resultMap.put(jtlx, Utils.multiply(scsum,multiple));
            }
        });
        if (resultMap.get("ifnotWork") != null){
            //次日免班

        }else {
            //推迟上班分钟数
            double delayMinute = 0;
            for (Map.Entry<String,Object> entry :resultMap.entrySet()){
                delayMinute = delayMinute+Double.valueOf(String.valueOf(entry.getValue()));
            }
            resultMap.put("delayMinute",delayMinute);
        }


        return resultMap;
    }

    @Override
    public Map<String, Object> removeAbnormal(Map<String, Object> param) {
        List<Map<String,Object>> abnormalClockInList = (List<Map<String,Object>>)param.get("abnormalClockInList");
        //班次
        List<Map<String,Object>> scheduleResult = (List<Map<String,Object>>)param.get("scheduleResult");
        //分析日期
        String analysisDate = Util.null2String(param.get("analysisDate"));
        //考勤项目
        List<Map<String,Object>> attendanceItems = (List<Map<String,Object>>)param.get("attendanceItems");

        int delayMinute = Double.valueOf(Util.null2String(param.get("delayMinute"))).intValue();

        List<Map<String,Object>> lateList = abnormalClockInList.stream().filter(e-> AttendanceItemTypeEnum.LATE.equals(e.get("itemType")) && (boolean)e.get("record")).collect(Collectors.toList());

        if (delayMinute > 0 && lateList.size() > 0){
            lateList = lateList.stream().sorted(Comparator.comparing(e-> DateUtil.getTime(e.get("classStartTime").toString()).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
            Map<String,Object> lateMap = lateList.get(0);
            //早上卡嗲
            String classStartTime = Util.null2String(lateMap.get("classStartTime"));
            //早上打卡时间
            String classEndTime = Util.null2String(lateMap.get("classEndTime"));

            //消除迟到
            for (Map<String,Object> abnormalClockIn:abnormalClockInList){
                if (abnormalClockIn.get("itemType").equals(AttendanceItemTypeEnum.LATE) &&
                        abnormalClockIn.get("classStartTime").equals(lateMap.get("classStartTime")) ){
                    abnormalClockInList.remove(abnormalClockIn);
                }
            }
            //延迟上班后新的上班时间
            String newClassStartTime = DateUtil.AfterMinutes(classStartTime,delayMinute);

            if (DateUtil.getTime(newClassStartTime).compareTo(DateUtil.getTime(classEndTime)) >=0){
                //消除迟到

            }else {
                //重新计算迟到项目以及时间
                int between = Utils.removeRestTime(newClassStartTime,classEndTime,scheduleResult,analysisDate);
                Map<String,Object> lateParams = Maps.newHashMap();
                lateParams.put("attendanceItems",attendanceItems);
                lateParams.put("time",between);
                lateParams.put("rqlx",scheduleResult.get(0).get("rqlx"));


                lateParams.put("workfor", WorkForTimeEnum.WORK_TIME.getKey());
                Map<String,Object> result = commandExecutor.execute(new BeLateItemCmd(lateParams));
                List<Map<String,Object>> workTimeBeLateItems = (List<Map<String,Object>>)result.get("attendanceItems");
                if (workTimeBeLateItems.size() == 0){
                    workTimeBeLateItems = (List<Map<String,Object>>)commandExecutor.execute(new AbsenteeismItemCmd(lateParams)).get("attendanceItems");
                }
                if (workTimeBeLateItems.size() == 0){
                    workTimeBeLateItems = attendanceItems.stream().filter(e-> SystemItemEnum.MISSING_ABSENTEEISM.getKey().equals(e.get("key"))).collect(Collectors.toList());
                    workTimeBeLateItems.get(0).put("kczgsc",CheckBoxEnum.CHECKED.getKey());
                    workTimeBeLateItems.get(0).put("qbkcsc","1");
                    workTimeBeLateItems.get(0).put("cckcbc","1");
                }
                if (workTimeBeLateItems.size() > 0){
                    Map<String,Object> saveWorkTimeBeLateParam = Maps.newHashMap();
                    double hsl = Double.valueOf(Util.null2String(workTimeBeLateItems.get(0).get("hsl")));
                    String hsdw = Util.null2String(workTimeBeLateItems.get(0).get("hsdw"));
                    String kczgsc = Util.null2String(workTimeBeLateItems.get(0).get("kczgsc"));
                    if (CheckBoxEnum.CHECKED.getKey().equals(kczgsc)){
                        //起步扣除分钟数
                        int qbkcsc = Integer.valueOf(Util.null2String(workTimeBeLateItems.get(0).get("qbkcsc")));
                        //超出后单次累加扣除分钟数
                        int cckcbc = Integer.valueOf(Util.null2String(workTimeBeLateItems.get(0).get("cckcbc")));
                        if (between <= qbkcsc){
                            between = qbkcsc;
                        }else {
                            int deductionDuration = between-qbkcsc;
                            between = Double.valueOf(Utils.getItemduration(cckcbc,AccountingUnitEnum.MINUTES.getKey(),deductionDuration,AccountingUnitEnum.MINUTES)).intValue()+qbkcsc;

                        }
                    }
                    double itemduration = Utils.getItemduration(hsl,hsdw,between,AccountingUnitEnum.MINUTES);
                    saveWorkTimeBeLateParam.put("item",workTimeBeLateItems.get(0).get("key"));
                    saveWorkTimeBeLateParam.put("itemduration",itemduration);
                    saveWorkTimeBeLateParam.put("betweenMinutes",between);
                    saveWorkTimeBeLateParam.put("itemType", AttendanceItemTypeEnum.LATE);
                    saveWorkTimeBeLateParam.put("hsdw",hsdw);
                    saveWorkTimeBeLateParam.put("hsl",hsl);
                    saveWorkTimeBeLateParam.put("kczgsc",kczgsc);
                    saveWorkTimeBeLateParam.put("classStartTime",classStartTime);
                    saveWorkTimeBeLateParam.put("classEndTime",classEndTime);
                    saveWorkTimeBeLateParam.put("pointTime",lateMap.get("pointTime"));
                    saveWorkTimeBeLateParam.put("bdlx",lateMap.get("bdlx"));
                    saveWorkTimeBeLateParam.put("record",lateMap.get("record"));
                    abnormalClockInList.add(saveWorkTimeBeLateParam);

                }
            }

        }
        return null;
    }

}
