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

import com.engine.attendance.attendanceanalysis.cmd.*;
import com.engine.attendance.attendanceanalysis.cmd.getclockInpoint.AdjustByWorkOverTimeCmd;
import com.engine.attendance.attendanceanalysis.cmd.getclockInpoint.GetClockInPointCmd;
import com.engine.attendance.attendanceanalysis.dto.ClockPointDTO;
import com.engine.attendance.attendanceanalysis.service.UtilService;
import com.engine.attendance.component.persongroup.service.SchedulingResultsService;
import com.engine.attendance.component.persongroup.service.impl.SchedulingResultsServiceImpl;
import com.engine.attendance.enums.*;
import com.engine.common.util.DateUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.common.util.Utils;
import com.engine.core.impl.Service;
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.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class UtilServiceImpl extends Service implements UtilService {
    private SchedulingResultsService schedulingResultsService = ServiceUtil.getService(SchedulingResultsServiceImpl.class);

    /**
     * 获取人员班次信息
     * @param params
     * @return
     */
    @Override
    public Map<String, Object> getSchedulingInFormation(Map<String, Object> params) {
        /** 班次信息*/
        Map<String,Object> schedulingResultsMap = schedulingResultsService.queryDataTableActualUse(params);
        params.put("schedulingResultsMap",schedulingResultsMap);
        return commandExecutor.execute(new GetScheduleResultListCmd(params));
    }


    /**
     * 获得打卡数据
     * @param params
     * @return
     */
    @Override
    public List<Map<String, Object>> getClockInTime(Map<String, Object> params) {
        Map<String,Object> result = commandExecutor.execute(new GetClockInTimeListCmd(params));
        List<Map<String, Object>> resultList = (List<Map<String, Object>>)result.get("resultList");
        return resultList;
    }

    @Override
    public void recordItem(Map<String, Object> params) {
        commandExecutor.execute(new RecordDataCmd(params));
    }


    @Override
    public Map<String, Object> getNeedRecordClockInTime(List<ClockPointDTO> clcokInTimeData) {
        Map<String, Object> resultMap = Maps.newHashMap();
        int inIndex = 1;
        int outIndex = 1;
        int jcCloumns = 8;
        for (ClockPointDTO clockPointDTO : clcokInTimeData){
            if (!clockPointDTO.isRecord()){
                continue;
            }

            //当天打卡数据
            Map<String,Object> clcokInTime = clockPointDTO.getClockTime();
            //需要计算的班次打卡时间点
            String pointTime = clockPointDTO.getClassTime();
            //start：开始打卡时间点，end：结束打卡时间点
            ClockPointEnum pointType = clockPointDTO.getPointType();
            //empty:漏卡，equal:打卡时间和班次时间相等，before：打卡时间在班次时间之前，after：打卡时间在班次时间之后
            ClockPointEnum timeType = clockPointDTO.getTimeType();

            if (ClockPointEnum.START.equals(pointType)){
                //开始时间打卡
                if (outIndex-1>inIndex){
                    inIndex = outIndex;
                }
                String key = "j"+inIndex;
                String ckey = "c"+inIndex;
                if (!ClockPointEnum.EMPTY.equals(timeType) && clcokInTime != null){
                    String time = clcokInTime.get("signdate")+" "+clcokInTime.get("signtime");
                    String value = time;

                    String ctime = Util.null2String(resultMap.get(ckey));
                    if (ctime !=null && !ctime.equals("NULL") && !"".equals(ctime)){
                        if (DateUtil.getTime(value).compareTo(DateUtil.getTime(ctime)) > 0){
                            resultMap.put(key,"NULL");
                            inIndex++;
                            key = "j"+inIndex;
                        }
                    }
                    resultMap.put(key,value);
                }else {
                    resultMap.put(key,"NULL");
                }
                inIndex++;
            }else if (ClockPointEnum.END.equals(pointType)){

                //结束时间打卡
                if (inIndex-1>outIndex){
                    outIndex = inIndex-1;
                }
                String key = "c"+outIndex;
                String jkey = "j"+inIndex;
                if (!ClockPointEnum.EMPTY.equals(timeType) && clcokInTime != null){
                    String time = clcokInTime.get("signdate")+" "+clcokInTime.get("signtime");
                    String value = time;
                    String jtime = Util.null2String(resultMap.get(jkey));
                    if (jtime !=null && !jtime.equals("NULL") && !"".equals(jtime)){
                        if (DateUtil.getTime(value).compareTo(DateUtil.getTime(jtime)) < 0){
                            resultMap.put(key,"NULL");
                            outIndex++;
                            key = "c"+outIndex;
                        }
                    }
                    resultMap.put(key,value);
                }else {
                    resultMap.put(key,"NULL");
                }
                outIndex++;
            }

        }
        for (int i=1;i<=8;i++){
            String jkey = "j"+i;
            String ckey = "c"+i;
            if (resultMap.get(jkey) == null){
                resultMap.put(jkey,"NULL");
            }
            if (resultMap.get(ckey) == null){
                resultMap.put(ckey,"NULL");
            }
        }
        return resultMap;
    }

    /**
     * 获取打卡卡点
     * @param params
     * @return
     */
    @Override
    public List<ClockPointDTO> getClockInPointCmd(Map<String,Object> params) {
        Map<String,Object> resultMap = commandExecutor.execute(new GetClockInPointCmd(params));
        params.putAll(resultMap);
        resultMap = commandExecutor.execute(new AdjustByWorkOverTimeCmd(params));
        List<ClockPointDTO> clcokInPointList = (List<ClockPointDTO>)resultMap.get("clcokInPointList");
        clcokInPointList = clcokInPointList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.getClassTime()).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
        return clcokInPointList;
    }

    /**
     * 计算出勤时长
     * @param params
     * @return
     */
    @Override
    public double computeAttendanceDuration(Map<String, Object> params) {
        Map<String,Object> resultMap = commandExecutor.execute(new ComputeAttendanceDurationCmd(params));
        return Double.valueOf(resultMap.get("attendanceDuration").toString());
    }
}
