package com.engine.kq.biz.chain.duration;

import com.alibaba.fastjson.JSON;
import com.engine.kq.biz.KQSettingsBiz;
import com.engine.kq.biz.KQShiftRuleInfoBiz;
import com.engine.kq.biz.KQTimesArrayComInfo;
import com.engine.kq.biz.chain.cominfo.HalfShiftComIndex;
import com.engine.kq.biz.chain.cominfo.ShiftInfoCominfoBean;
import com.engine.kq.biz.chain.shiftinfo.ShiftInfoBean;
import com.engine.kq.enums.DurationTypeEnum;
import com.engine.kq.log.KQLog;
import com.engine.kq.util.KQDurationCalculatorUtil;
import com.engine.kq.wfset.bean.SplitBean;
import com.engine.kq.wfset.util.SplitActionUtil;
import com.engine.kq.wfset.util.SplitSelectSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import weaver.general.Util;

/**
 * 工作时长 按整天计算
 */
public class WorkWholeUnitSplitChain extends WorkDurationChain {

  public static KQLog kqLog = new KQLog();

  public WorkWholeUnitSplitChain(List<SplitBean> splitBeans) {
    super(splitBeans);
  }

  @Override
  public void handleDuration(SplitBean splitBean) {
    String durationrule = splitBean.getDurationrule();
    if("4".equalsIgnoreCase(durationrule)){
      getSplitDurationBean(splitBean);
    }
  }

  @Override
  public void getSplitDurationBean(SplitBean splitBean){
    SplitActionUtil splitActionUtil = new SplitActionUtil();

    String resourceid = splitBean.getResourceId();
    String fromDate = splitBean.getFromdatedb();
    String toDate = splitBean.getTodatedb();
    String fromTime = splitBean.getFromtimedb();
    String toTime = splitBean.getTotimedb();
    DurationTypeEnum durationTypeEnum = splitBean.getDurationTypeEnum();
    if(!(fromTime.equalsIgnoreCase(SplitSelectSet.daylong_start))){
      return;
    }
    if(!(toTime.equalsIgnoreCase(SplitSelectSet.daylong_end))){
      return;
    }

    KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo();
    //获取对应人员和对应日期下的工作时段
    List<Map<String,String>> splitLists = SplitActionUtil.getSplitDayList(fromDate,toDate);

    if(!splitLists.isEmpty()) {
      KQTimesArrayComInfo arrayComInfo = new KQTimesArrayComInfo();
      for (int i = 0; i < splitLists.size(); i++) {
        Map<String, String> splitMap = splitLists.get(i);
        String splitDate = Util.null2String(splitMap.get("splitDate"));
        ShiftInfoBean shiftInfoBean = KQDurationCalculatorUtil.getWorkTime(resourceid, splitDate,false);
        splitBean.setBelongDate(splitDate);
        boolean shouldLog = true;
        if(durationTypeEnum == DurationTypeEnum.COMMON_CAL){
          shouldLog = false;
        }
        if(shouldLog){
          kqLog.info("doSerialSplitList:"+ (splitBean != null ? JSON.toJSONString(splitBean):null));
        }

        if(shiftInfoBean != null){
          if(!shiftInfoBean.isIsfree()){
            //先计算下时长
            splitBean.setWorkmins(shiftInfoBean.getWorkmins());
            List<int[]> halfWorkIndex = shiftInfoBean.getHalfWorkIndex();
            List<int[]> shift_halfWorkIndex = Lists.newArrayList();
            if(!halfWorkIndex.isEmpty()){
              List<int[]> workLongTimeIndex = shiftInfoBean.getWorkLongTimeIndex();
              if(workLongTimeIndex.size() == 1){
                if(workLongTimeIndex.size() == 1){
//                根据个性化设置获取到真实的半天班次
                  get_shift_wholeWorkIndex_by_rule(shift_halfWorkIndex,shiftInfoBean,halfWorkIndex,splitBean.getResourceId(),arrayComInfo);
                }
              }
              if(!shift_halfWorkIndex.isEmpty()){
                splitWholetoBean(splitBean,splitDate, shift_halfWorkIndex, arrayComInfo);
              }else{
                splitWholetoBean(splitBean,splitDate, halfWorkIndex, arrayComInfo);
              }
            }
          }else{
            int freeWorkMins = Util.getIntValue(shiftInfoBean.getFreeWorkMins());
            splitBean.setWorkmins(freeWorkMins);
            String freeSignStart = shiftInfoBean.getFreeSignStart();
            String freeSignMiddle = shiftInfoBean.getFreeSignMiddle();
            String freeSignEnd = shiftInfoBean.getFreeSignEnd();
            if(freeSignStart.length() > 0){
              List<int[]> halfWorkIndex = new ArrayList<>();
              int[] halfWorkIndexs = new int[3];
              halfWorkIndexs[0]=arrayComInfo.getArrayindexByTimes(freeSignStart);//当天班次的最早时间 这个时间肯定不可能跨天的
              halfWorkIndexs[1]=arrayComInfo.getArrayindexByTimes(freeSignMiddle);//当天班次的中间时间 这个时间可能会跨天
              halfWorkIndexs[2]=arrayComInfo.getArrayindexByTimes(freeSignEnd);//当天班次的最晚时间 这个时间也可能会跨天
              halfWorkIndex.add(halfWorkIndexs);
              splitWholetoBean(splitBean,splitDate, halfWorkIndex, arrayComInfo);
            }
          }
        }else{
          String computingMode = splitBean.getComputingMode();
          if("2".equalsIgnoreCase(computingMode)){
            String filterholidays = splitBean.getFilterholidays();
            boolean is_filterholidays = splitActionUtil.check_filterholidays(filterholidays,resourceid,splitDate,-1);
            if(is_filterholidays){
              continue;
            }
            splitNaturalWhole(splitBean,splitDate);
          }
        }
      }
    }
  }

  /**
   * 根据个性化设置获取到真实的整天班次
   * @param shift_halfWorkIndex
   * @param shiftInfoBean
   * @param halfWorkIndex
   * @param resourceId
   * @param arrayComInfo
   */
  public void get_shift_wholeWorkIndex_by_rule(List<int[]> shift_halfWorkIndex,
      ShiftInfoBean shiftInfoBean, List<int[]> halfWorkIndex, String resourceId,
      KQTimesArrayComInfo arrayComInfo) {
    boolean is_flow_humanized = KQSettingsBiz.is_flow_humanized();
    if(!is_flow_humanized){
      return ;
    }

    List<String> real_allLongWorkTime = Lists.newArrayList();
    List<String> allLongWorkTime = shiftInfoBean.getAllLongWorkTime();
    CollectionUtils.addAll(real_allLongWorkTime,new Object[allLongWorkTime.size()]);
    Collections.copy(real_allLongWorkTime, allLongWorkTime);

    //个性化设置只支持一次打卡的
    Map<String,String> shifRuleMap = Maps.newHashMap();
    KQShiftRuleInfoBiz.getShiftRuleInfo(shiftInfoBean,resourceId,shifRuleMap);
    if(!shifRuleMap.isEmpty()){
      if(shifRuleMap.containsKey("shift_beginworktime")){
        String shift_beginworktime = Util.null2String(shifRuleMap.get("shift_beginworktime"));
        if(shift_beginworktime.length() > 0){
          real_allLongWorkTime.set(0,shift_beginworktime);
        }
      }
      if(shifRuleMap.containsKey("shift_endworktime")){
        String shift_endworktime = Util.null2String(shifRuleMap.get("shift_endworktime"));
        if(shift_endworktime.length() > 0){
          real_allLongWorkTime.set(1,shift_endworktime);
        }
      }
      if(!real_allLongWorkTime.isEmpty()){
        int[] shift_halfWorkIndex_arr = new int[halfWorkIndex.get(0).length];
        shift_halfWorkIndex_arr[0] = arrayComInfo.getArrayindexByTimes(real_allLongWorkTime.get(0));
        shift_halfWorkIndex_arr[1] = halfWorkIndex.get(0)[1];
        shift_halfWorkIndex_arr[2] = arrayComInfo.getArrayindexByTimes(real_allLongWorkTime.get(real_allLongWorkTime.size()-1));
        shift_halfWorkIndex.add(shift_halfWorkIndex_arr);
      }
    }
  }

  /**
   * 针对非自然日整天的拆分
   * @param splitBean
   * @param splitDate
   */
  private void splitNaturalWhole(SplitBean splitBean, String splitDate) {
    String fromDate = splitDate;
    String toDate = splitDate;
    String splitFromTime = SplitSelectSet.daylong_start;
    String splitToTime = SplitSelectSet.daylong_end;
    String duration = "1.0";

    splitBean.setFromDate(fromDate);
    splitBean.setFromTime(splitFromTime);
    splitBean.setToDate(toDate);
    splitBean.setToTime(splitToTime);
    splitBean.setDuration(duration);

    SplitBean newsplitBean = new SplitBean();
    //然后把bean重新赋值下，根据拆分后的时间
    BeanUtils.copyProperties(splitBean, newsplitBean);
    splitBeans.add(newsplitBean);
  }

  /**
   * 单独针对整天规则的 拆分流程数据
   * 理论上是需要先把整天的工作时段拆分
   * 根据拆分后的工作时段，再进行拆分
   * @param splitBean
   * @param splitDate
   * @param halfWorkIndex
   * @param arrayComInfo
   */
  private void splitWholetoBean(SplitBean splitBean,String splitDate,List<int[]> halfWorkIndex,KQTimesArrayComInfo arrayComInfo){

    String fromDate = splitDate;
    String toDate = splitDate;

    int[] halfWorkIndexs = halfWorkIndex.get(0);
    int firstTimeIndex = halfWorkIndexs[0];//当天班次的最早时间 这个时间肯定不可能跨天的
    int lastTimeIndex = halfWorkIndexs[2];//当天班次的最晚时间 这个时间也可能会跨天
    //整天的话，跨天只有可能是最晚下班时间跨天
    String splitFromTime = arrayComInfo.getTimesByArrayindex(firstTimeIndex);
    String splitToTime = arrayComInfo.getTimesByArrayindex(lastTimeIndex);
    boolean isAcross = lastTimeIndex > 1440;
    String duration = "1.0";
    int workmins = splitBean.getWorkmins();

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    //跨天的话需要得到跨天的日期
    LocalDate localDateAcross = LocalDate.parse(splitDate).plusDays(1);

    if(isAcross){
      toDate = localDateAcross.format(dateFormatter);
    }

    splitBean.setFromDate(fromDate);
    splitBean.setFromTime(splitFromTime);
    splitBean.setToDate(toDate);
    splitBean.setToTime(splitToTime);
    splitBean.setDuration(duration);
    splitBean.setD_Mins(workmins*Util.getDoubleValue(duration));

    SplitBean newsplitBean = new SplitBean();
    //然后把bean重新赋值下，根据拆分后的时间
    BeanUtils.copyProperties(splitBean, newsplitBean);
    splitBeans.add(newsplitBean);

  }

}
