package com.engine.kq.biz;

import com.alibaba.fastjson.JSONObject;
import com.engine.kq.cmd.attendanceButton.ButtonStatusEnum;
import com.engine.kq.entity.WorkTimeEntity;
import com.google.common.collect.Lists;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.engine.kq.enums.FlowReportTypeEnum;
import com.engine.kq.log.KQLog;
import weaver.common.DateUtil;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;

/**
 * 格式化自由工时数据
 */
public class KQFormatFreeData extends BaseBean{
  private static DecimalFormat df = new DecimalFormat("0.00");
  protected KQLog kqLog = new KQLog();

  /**
   *
   * @param userId
   * @param kqDate
   * @param workFlowInfo
   * @return
   */
  public List<List<Object>> format(String userId, String kqDate, Map<String,Object> workFlowInfo){
    List<List<Object>> lsParam = new ArrayList<>();
    List<Object> params = new ArrayList<>();
    try{
      int workMins = 0;
      String signInId = "";
      String signInDate = "";
      String signInTime = "";
      String signOutId = "";
      String signOutDate = "";
      String signOutTime = "";

      String temp_signInDate = "";
      String temp_signInTime = "";
      String temp_signOutDate = "";
      String temp_signOutTime = "";

      String cal_signInId = "";
      String cal_signInDate = "";
      String cal_signInTime = "";
      String cal_signOutId = "";
      String cal_signOutDate = "";
      String cal_signOutTime = "";

      int signMins = 0;
      int attendanceMins=0;
      String serialid = "";
      String groupid = "";
      int beLateMins = 0;
      int graveBeLateMins = 0;
      int leaveEarlyMins =0;
      int graveLeaveEarlyMins =0;
      int absenteeismMins =0;
      int leaveMins = 0;//请假时长
      int evectionMins = 0;//出差时长
      int outMins = 0;//公出时长
	   Map<String,Integer> leaveInfo = new HashMap<>();//请假信息
      Map<String,Object> otherinfo = new HashMap<>();//存一些用得到的信息

      KQWorkTime kqWorkTime = new KQWorkTime();
      KQTimesArrayComInfo kqTimesArrayComInfo = new KQTimesArrayComInfo();

      int workBeginIdx = 0;
      int beginIdx = 0;
      int endIdx = 0;
      String dateKey = userId +"|"+ kqDate;
      String nextDate = DateUtil.addDate(kqDate, 1);

      List<Object> workFlow = null;
      WorkTimeEntity workTime = kqWorkTime.getWorkTime(userId,kqDate);
      String signstart = "";
      String calmethod = "2";
      if(workTime!=null) {
        groupid = Util.null2String(workTime.getGroupId());
        signstart = Util.null2String(workTime.getSignStart());//签到开始时间
        workMins = Util.getIntValue(Util.null2String(workTime.getWorkMins()));//工作时长
        workBeginIdx = kqTimesArrayComInfo.getArrayindexByTimes(signstart);
        calmethod = Util.null2s(workTime.getCalmethod(),"1");//自由班制计算方式
      }
//      弹性工作制是否可以跨天
      boolean isFreezeAcross = KQSettingsBiz.is_freeAcross();

      int kqSize = 1440;
      if(isFreezeAcross){
        kqSize = kqTimesArrayComInfo.getIndexSize();
      }
      int[] dayMins = new int[kqSize];//一天所有分钟数

      if(workFlowInfo.get(dateKey)!=null){
        workFlow = (List<Object>)workFlowInfo.get(dateKey);
      }

      for(int j=0;workFlow!=null&&j<workFlow.size();j++) {
        Map<String, Object> data = (Map<String, Object>) workFlow.get(j);
        String flowType = Util.null2String(data.get("flowtype"));
        String newLeaveType = Util.null2String(data.get("newleavetype"));
        beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("begintime")));
        endIdx = kqTimesArrayComInfo.getArrayindexByTimes(Util.null2String(data.get("endtime")));
        if(flowType.equals(FlowReportTypeEnum.EVECTION.getFlowType())){
          Arrays.fill(dayMins, beginIdx, endIdx, 7);//出差抵扣时段标识 7
        }else if(flowType.equals(FlowReportTypeEnum.OUT.getFlowType())){
          Arrays.fill(dayMins, beginIdx, endIdx, 8);//公出抵扣时段标识 8
        }else{
          if (endIdx > beginIdx) {
            Arrays.fill(dayMins, beginIdx, endIdx, 5);//流程抵扣时段标识 5
            if(flowType.equalsIgnoreCase(FlowReportTypeEnum.LEAVE.getFlowType())){
              int tmpBeginIdx = beginIdx;
              int tmpEndIdx = endIdx;
              int val = 0;
              if(leaveInfo.get(newLeaveType)==null){
                leaveInfo.put(newLeaveType,val);
              }else{
                val = leaveInfo.get(newLeaveType);
              }
              if(beginIdx<workBeginIdx)tmpBeginIdx=workBeginIdx;
              if(tmpEndIdx>tmpBeginIdx){
                leaveInfo.put(newLeaveType,val+(tmpEndIdx-tmpBeginIdx));
              }
            }
          }
        }
      }

      String signBeginDateTime = kqDate + " "+ signstart+":00";
      String signEndDateTime = kqDate + " 23:59:59";
      if(isFreezeAcross){
        signEndDateTime = nextDate + " "+ signstart+":00";
      }
      String workBeginDateTime = "";
      String workEndDateTime = "";
      List<Object> lsCheckInfo = new KQFormatSignData().getSignInfoForAll(userId,signBeginDateTime,signEndDateTime,workBeginDateTime,workEndDateTime);

      if("2".equalsIgnoreCase(calmethod)){
        //成对出现
        if(!lsCheckInfo.isEmpty()) {
          if(lsCheckInfo.size()%2==1 && lsCheckInfo.size() > 1){
            lsCheckInfo.remove(lsCheckInfo.size()-1);
          }
        }
      }else{
        if(!lsCheckInfo.isEmpty()) {
          List<Object> tmplsCheckInfo = Lists.newArrayList();
          tmplsCheckInfo.add(lsCheckInfo.get(0));
          if(lsCheckInfo.size()>1) {
            tmplsCheckInfo.add(lsCheckInfo.get(lsCheckInfo.size() - 1));
          }
          lsCheckInfo.clear();
          lsCheckInfo.addAll(tmplsCheckInfo);
        }
      }

      for (int i = 0; i<lsCheckInfo.size(); i++) {//有签到签退才算出勤，漏签无法统计出勤时间
        Map<String, Object> checkInfo = (Map<String, Object>) lsCheckInfo.get(i);
        String signId = Util.null2String(checkInfo.get("signId"));
        String signDate = Util.null2String(checkInfo.get("signDate"));
        String signTime = Util.null2String(checkInfo.get("signTime"));
        if (signTime.length() > 8) {
          signTime = signTime.substring(0, 8);
        }

        //用于计算打卡时长
        if (checkInfo.get("signType").equals("1")) {//签到
          temp_signInDate = signDate;
          if(temp_signInDate.compareTo(kqDate) > 0){
            temp_signInTime = kqTimesArrayComInfo.turn24to48Time(signTime);
          }else{
            temp_signInTime = signTime;
          }
        } else if (checkInfo.get("signType").equals("2")) {//签退
          temp_signOutDate = signDate;
          if(temp_signOutDate.compareTo(kqDate) > 0){
            temp_signOutTime = kqTimesArrayComInfo.turn24to48Time(signTime);
          }else{
            temp_signOutTime = signTime;
          }
        }

        if (i==0 && checkInfo.get("signType").equals("1")) {//签到
          signInId = signId;
          signInDate = signDate;
          signInTime = signTime;
          if(temp_signInDate.compareTo(kqDate) > 0){
            temp_signInTime = kqTimesArrayComInfo.turn24to48Time(signTime);
          }else{
            temp_signInTime = signTime;
          }
        } else if (i==lsCheckInfo.size()-1&&checkInfo.get("signType").equals("2")) {//签退
          signOutId = signId;
          signOutDate = signDate;
          signOutTime = signTime;
        }

        if("2".equalsIgnoreCase(calmethod)){
          if(i%2==1){
            beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(temp_signInTime);
            endIdx = kqTimesArrayComInfo.getArrayindexByTimes(temp_signOutTime);
            if(endIdx>beginIdx) {
              Arrays.fill(dayMins, beginIdx, endIdx, 1);//工作时段标识 1
            }
          }
        }else{
          if(i == 0){
            cal_signInId = signId;
            cal_signInDate = signDate;
            cal_signInTime = signTime;
          }else {
            cal_signOutId = signId;
            cal_signOutDate = signDate;
            cal_signOutTime = signTime;
          }
        }
      }

      if("1".equalsIgnoreCase(calmethod)){
        beginIdx = kqTimesArrayComInfo.getArrayindexByTimes(cal_signInTime);
        endIdx = kqTimesArrayComInfo.getArrayindexByTimes(cal_signOutTime);
        if(cal_signInDate.compareTo(kqDate) > 0){
          beginIdx = kqTimesArrayComInfo.turn24to48TimeIndex(beginIdx);
        }
        if(cal_signOutDate.compareTo(kqDate) > 0){
          endIdx = kqTimesArrayComInfo.turn24to48TimeIndex(endIdx);
        }
        if(endIdx>beginIdx) {
          Arrays.fill(dayMins, beginIdx, endIdx, 1);//工作时段标识 1
        }
        signInId = cal_signInId;
        signInDate = cal_signInDate;
        signInTime = cal_signInTime;
        signOutId = cal_signOutId;
        signOutDate = cal_signOutDate;
        signOutTime = cal_signOutTime;
      }

      int workFlowMins = 0;
      for(int i=workBeginIdx;i<kqSize;i++) {
        switch(dayMins[i]){
          case 1://出勤分钟数
            attendanceMins++;
            break;
          case 5:
            leaveMins++;//请假分钟数
            break;
          case 7:
            evectionMins++;
            break;
          case 8:
            outMins++;
            break;
          default:
            break;
        }
      }

      //计算实际出勤时间(打卡、出差、公出算出勤)
      signMins = attendanceMins;
      attendanceMins = attendanceMins+evectionMins+outMins;
      if(attendanceMins>workMins)attendanceMins=workMins;

      absenteeismMins = workMins - attendanceMins-leaveMins;
      if(absenteeismMins<0){
        absenteeismMins=0;
      }

      if (workTime.getIsExclude()) {//无需考勤人员没有异常状态
        attendanceMins = workMins;
        beLateMins = 0;
        graveBeLateMins = 0;
        leaveEarlyMins = 0;
        graveLeaveEarlyMins = 0;
        absenteeismMins = 0;
      }

      params.add(userId);
      params.add(kqDate);
      params.add(groupid.length() == 0 ? null : groupid);
      params.add(serialid.length() == 0 ? null : serialid);
      params.add(0);
      params.add(null);
      params.add(null);
      params.add(null);
      params.add(null);
      params.add(workMins);
      params.add(signInDate);
      params.add(signInTime);
      params.add(signInId.length() == 0 ? null : signInId);
      params.add(signOutDate);
      params.add(signOutTime);
      params.add(signOutId.length() == 0 ? null : signOutId);
      params.add(signMins);
      params.add(attendanceMins);
      params.add(beLateMins);
      params.add(graveBeLateMins);
      params.add(leaveEarlyMins);
      params.add(graveLeaveEarlyMins);
      params.add(absenteeismMins);
      params.add(null);
      params.add(leaveMins);
      params.add(JSONObject.toJSONString(leaveInfo));
      params.add(evectionMins);
      params.add(outMins);
      params.add(null);
      params.add(JSONObject.toJSONString(otherinfo));
      lsParam.add(params);
    }catch (Exception e){
      writeLog(e);
      kqLog.info(e);
    }
    return lsParam;
  }
}
