package com.engine.kq.cmd.attendanceEvent;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.kq.biz.KQLeaveRulesBiz;
import com.engine.kq.biz.KQTimesArrayComInfo;
import com.engine.kq.biz.chain.duration.WorkHalfUnitSplitChain;
import com.engine.kq.biz.chain.shiftinfo.ShiftInfoBean;
import com.engine.kq.enums.KqSplitFlowTypeEnum;
import com.engine.kq.log.KQLog;
import com.engine.kq.util.KQDurationCalculatorUtil;
import com.engine.kq.wfset.util.SplitActionUtil;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;

/**
 * 销假校验事件
 */
public class CheckLeaveBackCmd extends AbstractCommonCommand<Map<String, Object>> {

	public CheckLeaveBackCmd(Map<String, Object> params, User user) {
		this.user = user;
		this.params = params;
	}

	@Override
	public Map<String, Object> execute(CommandContext commandContext) {
		Map<String, Object> retmap = new HashMap<String, Object>();
		try{
		  KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo();
      DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
      String resMap = Util.null2String(params.get("resMap"));
      int workflowid = Util.getIntValue(Util.null2String(params.get("workflowid")));
      int nodeid = Util.getIntValue(Util.null2String(params.get("nodeid")));
      int leaverequestid = Util.getIntValue(Util.null2String(params.get("leaverequestid")));
      int resourceId = Util.getIntValue(Util.null2String(params.get("resourceId")));
      JSONArray jsonArray = (JSONArray)JSON.parse(resMap);
      if(leaverequestid <= 0){
        //未选择请假流程
        retmap.put("status", "-1");
        retmap.put("message", SystemEnv.getHtmlLabelName(10000802,weaver.general.Util.getIntValue(user.getLanguage())));
        return retmap;
      }
      if(resourceId <= 0){
        //未选择销假人
        retmap.put("status", "-1");
        retmap.put("message", SystemEnv.getHtmlLabelName(10000802,weaver.general.Util.getIntValue(user.getLanguage())));
        return retmap;
      }
      if(jsonArray != null && !jsonArray.isEmpty()){
        Map<String, int[]> leavebackMap = new HashMap<>();
        //获取销假的数据
        getLeaveBacks(leaverequestid,leavebackMap,kqTimesArrayComInfo,resourceId);

        for(int i = 0 ; i < jsonArray.size() ; i++){
          JSONObject jsonObject = (JSONObject) jsonArray.get(i);
          String leavefromDate = Util.null2String(jsonObject.get("leavefromDate"));
          String leavefromTime = Util.null2String(jsonObject.get("leavefromTime"));
          String leavetoDate = Util.null2String(jsonObject.get("leavetoDate"));
          String leavetoTime = Util.null2String(jsonObject.get("leavetoTime"));
          String newLeaveType = Util.null2String(jsonObject.get("newLeaveType"));

          String fromDate = Util.null2String(jsonObject.get("fromDate"));
          String fromTime = Util.null2String(jsonObject.get("fromTime"));
          String toDate = Util.null2String(jsonObject.get("toDate"));
          String toTime = Util.null2String(jsonObject.get("toTime"));

          if(leavefromDate.length() == 0 || leavefromTime.length() ==0 ||
            leavetoDate.length() == 0 || leavetoTime.length() == 0){
            //请假信息有误
            retmap.put("status", "-1");
            retmap.put("message",  SystemEnv.getHtmlLabelName(10000802,weaver.general.Util.getIntValue(user.getLanguage())));
            return retmap;
          }

          if(fromDate.length() == 0 || fromTime.length() ==0 ||
              toDate.length() == 0 || toTime.length() == 0){
            //销假信息有误
            retmap.put("status", "-1");
            retmap.put("message",  SystemEnv.getHtmlLabelName(10000803,weaver.general.Util.getIntValue(user.getLanguage())));
            return retmap;
          }

          LocalDateTime leaveFromDateTime = LocalDateTime.parse(leavefromDate+" "+leavefromTime,datetimeFormatter);
          LocalDateTime leaveToDateTime = LocalDateTime.parse(leavetoDate+" "+leavetoTime,datetimeFormatter);

          LocalDateTime fromDateTime = LocalDateTime.parse(fromDate+" "+fromTime,datetimeFormatter);
          LocalDateTime toDateTime = LocalDateTime.parse(toDate+" "+toTime,datetimeFormatter);

          //销假区间要在请假区间内
          if((fromDateTime.isAfter(leaveFromDateTime) || fromDateTime.isEqual(leaveFromDateTime)) &&
              (fromDateTime.isBefore(leaveToDateTime) || fromDateTime.isEqual(leaveToDateTime)) &&
              (toDateTime.isAfter(leaveFromDateTime) || toDateTime.isEqual(leaveFromDateTime)) &&
              (toDateTime.isBefore(leaveToDateTime)  || toDateTime.isEqual(leaveToDateTime))){
            //这是满足条件的
          }else{
            //不在请假区间的
            retmap.put("status", "-1");
            retmap.put("message",  SystemEnv.getHtmlLabelName(505782, user.getLanguage()));
            return retmap;
          }
          boolean is_half_select = false;
          int minimumUnit = KQLeaveRulesBiz.getMinimumUnit(newLeaveType);
          int timeselection = KQLeaveRulesBiz.getTimeselection(newLeaveType);
          if(timeselection == 1){
            //下拉框
            if(minimumUnit == 2){
              is_half_select = true;
            }
          }
          //拆分销假流程
          List<Map<String,String>> splitLists = SplitActionUtil
              .getSplitList(fromDate,toDate,fromTime,toTime);
          if(is_half_select){
            splitLists = SplitActionUtil.getSplitHalfDayList(fromDate,toDate,fromTime,toTime);
          }
          String leaveBackDesc = fromDate+" "+fromTime+" - "+toDate+" "+toTime;

          boolean isDup = checkDuplicateBack(leavebackMap,splitLists,kqTimesArrayComInfo,retmap,leaveBackDesc,is_half_select,resourceId);
          if(!isDup){
            return retmap;
          }

        }
      }
      retmap.put("status", "1");
		}catch (Exception e) {
			retmap.put("status", "-1");
			retmap.put("message",  SystemEnv.getHtmlLabelName(382661,user.getLanguage()));
			writeLog(e);
		}
		return retmap;
	}

  /**
   * 获取消过假的数据
   * @param leaverequestid
   * @param leavebackMap
   * @param kqTimesArrayComInfo
   * @param resourceId
   */
  private void getLeaveBacks(int leaverequestid, Map<String, int[]> leavebackMap,
      KQTimesArrayComInfo kqTimesArrayComInfo, int resourceId) {
    RecordSet rs = new RecordSet();
    int[] initArrays = kqTimesArrayComInfo.getInitArr();
    String getLeaveBackSql = "select * from "+ KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" where leavebackrequestid=? and resourceId=? ";
    rs.executeQuery(getLeaveBackSql, leaverequestid,resourceId);
    while(rs.next()){
      String fromdate = rs.getString("fromdate");
      String fromtime = rs.getString("fromtime");
      String todate = rs.getString("todate");
      String totime = rs.getString("totime");
      //拆分的销假中间表里，开始时间少1分钟，结束时间多1分钟
      int fromIndex = kqTimesArrayComInfo.getArrayindexByTimes(fromtime);
      fromIndex = fromIndex + 1;
      int toIndex = kqTimesArrayComInfo.getArrayindexByTimes(totime);
      toIndex = toIndex - 1;
      if(fromIndex > toIndex){
        continue;
      }
      if(leavebackMap.get(fromdate) != null){
        int[] initArraysTmp = leavebackMap.get(fromdate);
        Arrays.fill(initArraysTmp, fromIndex, toIndex,1);
      }else{
        int[] initArras = new int[2048];
        initArras = initArrays.clone();
        Arrays.fill(initArras, fromIndex, toIndex,1);
        leavebackMap.put(fromdate, initArras);
      }
    }
  }

  /**
   * 校验是否重复销假 同一部分
   * @param leavebackMap 已经销过的假集合
   * @param splitLists 拆分的销假流程
   * @param kqTimesArrayComInfo
   * @param retmap
   * @param leaveBackDesc
   * @param is_half_select
   * @param resourceId
   */
  private boolean checkDuplicateBack(Map<String, int[]> leavebackMap,
      List<Map<String, String>> splitLists,
      KQTimesArrayComInfo kqTimesArrayComInfo, Map<String, Object> retmap,
      String leaveBackDesc, boolean is_half_select, int resourceId) {

    int splitCount = splitLists.size();
    for (int i = 0; i < splitCount; i++) {
      Map<String, String> splitMap = splitLists.get(i);
      String splitDate = Util.null2String(splitMap.get("splitDate"));
      String splitFromTime = Util.null2String(splitMap.get("fromTime"));
      String splitToTime = Util.null2String(splitMap.get("toTime"));
      if(is_half_select){
        int foreOrAfter = Util.getIntValue(Util.null2String(splitMap.get("foreOrAfter")));
//      下拉框选择
        ShiftInfoBean shiftInfoBean = KQDurationCalculatorUtil
            .getWorkTime(resourceId+"", splitDate,false);
        if(shiftInfoBean != null) {
          if (!shiftInfoBean.isIsfree()) {
            List<int[]> halfWorkIndex = shiftInfoBean.getHalfWorkIndex();
            if(halfWorkIndex != null && !halfWorkIndex.isEmpty()){
              int[] halfWorkIndexs = halfWorkIndex.get(0);
              int firstTimeIndex = halfWorkIndexs[0];//当天班次的最早时间 这个时间肯定不可能跨天的
              int middleTimeIndex = halfWorkIndexs[1];//当天班次的中间时间 这个时间可能会跨天
              int lastTimeIndex = halfWorkIndexs[2];//当天班次的最晚时间 这个时间也可能会跨天
              switch (foreOrAfter){
                case WorkHalfUnitSplitChain.fore_fore_index:
                  splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(firstTimeIndex);
                  splitToTime = kqTimesArrayComInfo.getTimesByArrayindex(middleTimeIndex);
                  break;
                case WorkHalfUnitSplitChain.fore_after_index:
                  splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(firstTimeIndex);
                  splitToTime = kqTimesArrayComInfo.getTimesByArrayindex(lastTimeIndex);
                  break;
                case WorkHalfUnitSplitChain.after_fore_index:
                  break;
                case WorkHalfUnitSplitChain.after_after_index:
                  splitFromTime = kqTimesArrayComInfo.getTimesByArrayindex(middleTimeIndex);
                  splitToTime = kqTimesArrayComInfo.getTimesByArrayindex(lastTimeIndex);
                  break;
                default:
                  break;
              }
            }
          }
        }
      }
      if(leavebackMap.get(splitDate) != null){
        int backstartIndex = kqTimesArrayComInfo.getArrayindexByTimes(splitFromTime);
        int backendIndex = kqTimesArrayComInfo.getArrayindexByTimes(splitToTime);

        int[] initArrays4Date = leavebackMap.get(splitDate);
        //1、指定日期下已消的时长
        int backCnt = kqTimesArrayComInfo.getCnt(initArrays4Date, 0, 2048, 1);
        //2、用本次销假的数据去覆盖
        Arrays.fill(initArrays4Date, backstartIndex,backendIndex,-1);
        int backCntNew = kqTimesArrayComInfo.getCnt(initArrays4Date, 0, 2048, 1);
        //3、如果原有的已消时长变了，说明被覆盖了
        if(backCnt != backCntNew){
          retmap.put("status", "-1");
          retmap.put("message",  leaveBackDesc+SystemEnv.getHtmlLabelName(505783, user.getLanguage()));
          return false;
        }
      }
    }
    return true;
  }

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

}
