package com.engine.kq.wfset.util;

import com.alibaba.fastjson.JSON;
import com.engine.kq.biz.KQAttProcSetComInfo;
import com.engine.kq.biz.KQExitRulesBiz;
import com.engine.kq.biz.KQFlowActiontBiz;
import com.engine.kq.biz.KQFormatBiz;
import com.engine.kq.biz.KQFormatData;
import com.engine.kq.biz.KQTravelRulesBiz;
import com.engine.kq.cmd.attendanceEvent.GetProcessChangeTypeCmd;
import com.engine.kq.enums.DurationTypeEnum;
import com.engine.kq.enums.KqSplitFlowTypeEnum;
import com.engine.kq.log.KQLog;
import com.engine.kq.wfset.bean.ProcessChangeSplitBean;
import com.engine.kq.wfset.bean.SplitBean;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
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.hrm.resource.ResourceComInfo;

public class KQFlowProcessChangeUtil {
  private KQLog kqLog = new KQLog();

  public static boolean processChangeCheck(RecordSet rs1, String requestId_rs, Map<String, String> result) {
    String resourceId = Util.null2s(rs1.getString("resourceId"), "");
    String changerequestid = Util.null2s(rs1.getString("changerequestid"), "");
    String detail_attendancefromDate = Util.null2s(rs1.getString("detail_attendancefromDate"), "");
    String detail_attendancefromTime = Util.null2s(rs1.getString("detail_attendancefromTime"), "");
    String detail_attendancetoDate = Util.null2s(rs1.getString("detail_attendancetoDate"), "");
    String detail_attendancetoTime = Util.null2s(rs1.getString("detail_attendancetoTime"), "");
    boolean canProcessChange = canProcessChange(resourceId,changerequestid, detail_attendancefromDate,
        detail_attendancefromTime, detail_attendancetoDate, detail_attendancetoTime);
    if(!canProcessChange){
      result.put("status", "-1");
      result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005328,weaver.general.ThreadVarLanguage.getLang())+","+weaver.systeminfo.SystemEnv.getHtmlLabelName(383337,weaver.general.ThreadVarLanguage.getLang())+"");
      return false;
    }
    return true;
  }

  public static boolean canProcessChange(String resourceId, String changerequestid,
      String attendancefromDate, String attendancefromTime, String attendancetoDate,
      String attendancetoTime) {

    Map<String, Object> params = new HashMap<>();
    params.put("resourceId", resourceId);
    params.put("requestid", changerequestid);
    params.put("isAll", "1");
    GetProcessChangeTypeCmd processChangeTypeCmd = new GetProcessChangeTypeCmd(params, new User(1));
    Map<String, Object> retmaps = processChangeTypeCmd.execute(null);
    if(!retmaps.isEmpty()) {
      if (retmaps.containsKey("process_type") && retmaps.containsKey("process_tablename")) {
        int process_type = Util.getIntValue(Util.null2String(retmaps.get("process_type")));
        String sql = "";
        if(KqSplitFlowTypeEnum.EVECTION.getFlowtype() == process_type){
          sql = "select * from "+KqSplitFlowTypeEnum.EVECTION.getTablename()+" where status='1' and requestid=? and resourceid=? "
              + "  and fromdatedb=? and fromtimedb=? and todatedb=? and totimedb=? ";
        }else if(KqSplitFlowTypeEnum.OUT.getFlowtype() == process_type){
          sql = "select * from "+KqSplitFlowTypeEnum.OUT.getTablename()+" where status='1' and requestid=? and resourceid=? "
              + " and fromdatedb=? and fromtimedb=? and todatedb=? and totimedb=? ";
        }
        if(sql.length() > 0){
          RecordSet rs = new RecordSet();
          rs.executeQuery(sql, changerequestid,resourceId,attendancefromDate,attendancefromTime,attendancetoDate,attendancetoTime);
          if(rs.next()){
            return false;
          }
        }
      }
    }
    return true;
  }
  /**
   * 拆分销假流程数据 生成数据到splitBeans和backsplitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQProcessChangeAction(Map<String, String> sqlMap,
      List<SplitBean> splitBeans, DateTimeFormatter datetimeFormatter, int workflowId,
      int requestId, ResourceComInfo rci) throws Exception{

    KQFlowActiontBiz kqFlowActiontBiz = new KQFlowActiontBiz();
    return kqFlowActiontBiz.handleAction(sqlMap,splitBeans, datetimeFormatter, workflowId,requestId, rci,DurationTypeEnum.PROCESSCHANGE);
  }

  public static void bean4ProcessChange(String prefix, RecordSet rs1, SplitBean splitBean) {
    String resourceId = Util.null2s(rs1.getString("resourceId"), "");
    String changerequestid = Util.null2s(rs1.getString("changerequestid"), "");
    String changetype = Util.null2s(rs1.getString("changetype"), "");

    String detail_attendancefromDate = Util.null2s(rs1.getString("detail_attendancefromDate"), "");
    String detail_attendancefromTime = Util.null2s(rs1.getString("detail_attendancefromTime"), "");
    String detail_attendancetoDate = Util.null2s(rs1.getString("detail_attendancetoDate"), "");
    String detail_attendancetoTime = Util.null2s(rs1.getString("detail_attendancetoTime"), "");
    String detail_attendanceduration = Util.null2s(rs1.getString("detail_attendanceduration"), "");
    ProcessChangeSplitBean processChangeSplitBean = new ProcessChangeSplitBean();
    processChangeSplitBean.setFromdatedb(detail_attendancefromDate);
    processChangeSplitBean.setFromtimedb(detail_attendancefromTime);
    processChangeSplitBean.setTodatedb(detail_attendancetoDate);
    processChangeSplitBean.setTotimedb(detail_attendancetoTime);
    processChangeSplitBean.setDurationDB(detail_attendanceduration);
    processChangeSplitBean.setProcessType(changetype);
    splitBean.setProcessChangeSplitBean(processChangeSplitBean);

    splitBean.setLeavebackrequestid(changerequestid);
    Map<String, Object> params = new HashMap<>();
    params.put("resourceId", resourceId);
    params.put("requestid", changerequestid);
    params.put("isAll", "1");
    GetProcessChangeTypeCmd processChangeTypeCmd = new GetProcessChangeTypeCmd(params, new User(1));
    Map<String, Object> retmaps = processChangeTypeCmd.execute(null);
    if(!retmaps.isEmpty()) {
      if (retmaps.containsKey("process_type") && retmaps.containsKey("process_tablename")) {
        int process_type = Util.getIntValue(Util.null2String(retmaps.get("process_type")));
        if(KqSplitFlowTypeEnum.EVECTION.getFlowtype() == process_type){
          String minimumUnit = Util.null2s(Util.null2String(KQTravelRulesBiz.getMinimumUnit()),"-1");
          String computingMode = Util.null2s(Util.null2String(KQTravelRulesBiz.getComputingMode()),"-1");
          splitBean.setDurationrule(minimumUnit);
          splitBean.setComputingMode(computingMode);
          splitBean.setDurationTypeEnum(DurationTypeEnum.EVECTION);
        }else if(KqSplitFlowTypeEnum.OUT.getFlowtype() == process_type){
          String minimumUnit = Util.null2s(Util.null2String(KQExitRulesBiz.getMinimumUnit()),"-1");
          String computingMode = Util.null2s(Util.null2String(KQExitRulesBiz.getComputingMode()),"-1");
          splitBean.setDurationrule(minimumUnit);
          splitBean.setComputingMode(computingMode);
          splitBean.setDurationTypeEnum(DurationTypeEnum.OUT);
        }
      }
    }
  }

  /**
   * 考勤变更流程拆分表处理
   * @param splitBeans
   * @param result
   * @param isUpgrade
   * @param requestId
   * @throws Exception
   */
  public void handleSplitFLowActionData4ProcessChange(
      List<SplitBean> splitBeans, Map<String, String> result, boolean isUpgrade, int requestId) throws Exception{

    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    RecordSet rs2 = new RecordSet();

    //是否是撤销
    boolean isDrawBack = false;
    List<String> formateList = new ArrayList<>();
    List<List> params = new ArrayList<List>();
    List<String> before_updateSql = new ArrayList<>();
    List<String> updateSql = new ArrayList<>();
    String change_tablename = "";
    //变更前的流程区间也需要格式化考勤报表的
    List<String> process_dates = new ArrayList<>();

    String changedrequestid = "";
    for(SplitBean bean : splitBeans){
      //被变更流程
      changedrequestid = bean.getLeavebackrequestid();
      ProcessChangeSplitBean processChangeSplitBean = bean.getProcessChangeSplitBean();
      String process_fromdatedb = processChangeSplitBean.getFromdatedb();
      String process_fromtimedb = processChangeSplitBean.getFromtimedb();
      String process_todatedb = processChangeSplitBean.getTodatedb();
      String process_totimedb = processChangeSplitBean.getTotimedb();
      String process_durationdb = processChangeSplitBean.getDurationDB();
      String processType = processChangeSplitBean.getProcessType();
      String process_key = bean.getResourceId()+"_"+process_fromdatedb+"_"+process_todatedb;
      if(!process_dates.contains(process_key)){
        process_dates.add(process_key);
      }
      if("1".equalsIgnoreCase(processType)){
        isDrawBack = true;
      }
      if(bean.getDurationTypeEnum() == DurationTypeEnum.EVECTION){
        change_tablename = KqSplitFlowTypeEnum.EVECTION.getTablename();
      }else if(bean.getDurationTypeEnum() == DurationTypeEnum.OUT){
        change_tablename = KqSplitFlowTypeEnum.OUT.getTablename();
      }
      if(!isDrawBack){
        getProcessChangeParams(bean,params,formateList,updateSql,change_tablename);
      }

      String updateLeaveSql = "";
      String before_updateLeaveSql = "";
      if(rs1.getDBType().equalsIgnoreCase("oracle")) {
        before_updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid='',status='0' where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
            +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
        updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid=nvl(leavebackrequestid,'')||','||"+bean.getRequestId()+",status='1' where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
            +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
      }
      else if(rs1.getDBType().equalsIgnoreCase("postgresql")) {
        before_updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid='',status='0' where "
                + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
                +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
        updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid=nvl(leavebackrequestid,'')||','||"+bean.getRequestId()+",status='1' where "
                + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
                +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
      }
      else if((rs1.getDBType()).equalsIgnoreCase("mysql")){
        before_updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid='',status='0' where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
            +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
        updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid=concat(ifnull(leavebackrequestid,''),',',"+bean.getRequestId()+"),status='1' where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
            +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
      }else {
        before_updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid='',status='0' where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
            +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
        updateLeaveSql = "update "+ change_tablename+" set leavebackrequestid=isnull(leavebackrequestid,'')+',"+bean.getRequestId()+"'"+",status='1' where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and fromdatedb='"+process_fromdatedb+"' "
            +" and fromtimedb='"+process_fromtimedb+"'"+" and todatedb='"+process_todatedb+"'"+" and totimedb='"+process_totimedb+"'";
      }
      if(!updateSql.contains(updateLeaveSql)){
        updateSql.add(updateLeaveSql);
      }
      if(!before_updateSql.contains(before_updateLeaveSql)){
        before_updateSql.add(before_updateLeaveSql);
      }

    }
    if(change_tablename.length() > 0){
      boolean isOk = true;
      if(!isDrawBack && !params.isEmpty()){
        //先根据requestid删除中间表里的数据，再做啥插入操作
        String delSql = "delete from "+change_tablename+" where requestid = "+requestId;
        rs2.executeUpdate(delSql);
        String backbatchSql = "insert into "+change_tablename+" (subcompanyid,departmentid,jobtitle,requestid,workflowid,usedetail,dataid,detailid,resourceid,fromdate,fromtime,todate,totime,newleavetype,durationdb,duration,durationrule,status,belongDate,D_Mins,serialid,tablenamedb,fromdatedb,fromtimedb,todatedb,totimedb,leavebackrequestid,changeType)"+
            " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";
        isOk = rs1.executeBatchSql(backbatchSql, params);
      }
      if(isOk){
        boolean isUpOk = false;
        for(String before_up_sql : before_updateSql){
          kqLog.info("考勤变更流程 重复归档流程记录sql handleSplitFLowActionData4ProcessChange before_up_sql:"+before_up_sql);
          isUpOk = rs.executeUpdate(before_up_sql);
          kqLog.info("考勤变更流程 重复归档流程记录执行情况 handleSplitFLowActionData4ProcessChange isUpOk:"+isUpOk);
        }
        if(isUpOk){
          for(String up_sql : updateSql){
            kqLog.info("考勤变更流程 记录sql handleSplitFLowActionData4ProcessChange up_sql:"+up_sql);
            isUpOk = rs.executeUpdate(up_sql);
            kqLog.info("考勤变更流程 记录执行情况 handleSplitFLowActionData4ProcessChange isUpOk:"+isUpOk);
          }
        }
        if(changedrequestid.length() > 0){
          handle_flow_deduct_card(changedrequestid,change_tablename);
        }
        kqLog.info("handleSplitFLowActionData4ProcessChange:formateList:"+formateList);
        for(String format: formateList){
          String[] formats = format.split("_");
          kqLog.info("handleSplitFLowActionData4ProcessChange:formats:"+ JSON.toJSONString(formats));
          new KQFormatData().formatKqDate(formats[0],formats[1]);
        }
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        for(String dates : process_dates){
          String[] datesArr = dates.split("_");
          if(datesArr.length == 3){
            String resourceid = datesArr[0];
            String fromDate = datesArr[1];
            String toDate = datesArr[2];
            LocalDate localFromDate = LocalDate.parse(fromDate);
            LocalDate localToDate = LocalDate.parse(toDate);
            LocalDate preFromDate = localFromDate.minusDays(1);
            LocalDate nextToDate = localToDate.plusDays(1);
            long betweenDays = nextToDate.toEpochDay() - preFromDate.toEpochDay();
            for (int i = 0; i <= betweenDays; i++) {
              LocalDate curLocalDate = preFromDate.plusDays(i);
              String date = curLocalDate.format(dateFormatter);
              kqLog.info("handleSplitFLowActionData4ProcessChange:formats changed:resourceid:"+ resourceid+":date:"+date);
              new KQFormatData().formatKqDate(resourceid,date);
            }
          }
        }
      }else{
        result.put("status", "-1");
        result.put("message", (""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005410,weaver.general.ThreadVarLanguage.getLang())+"requestId:"+requestId));
        kqLog.info("handleSplitFLowActionData4ProcessChange考勤变更流程保存失败：requestId:"+requestId);
        return ;
      }
    }else{
      result.put("status", "-1");
      result.put("message", (""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005410,weaver.general.ThreadVarLanguage.getLang())+"requestId:"+requestId));
      kqLog.info("handleSplitFLowActionData4ProcessChange考勤变更流程保存失败：requestId:"+requestId);
      return ;
    }
  }

  /**
   * 出差变更完了之后被变更的流程如果之前开启了流程抵扣打卡也需要被变更掉
   * @param changedrequestid
   * @param change_tablename
   */
  public void handle_flow_deduct_card(String changedrequestid, String change_tablename) {
    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    String workflowid = "";
    String sql = "select * from workflow_requestbase where requestid=? ";
    rs.executeQuery(sql,changedrequestid);
    if(rs.next()){
      workflowid = rs.getString("workflowid");
    }
    if(workflowid.length() > 0){
      KQAttProcSetComInfo kqAttProcSetComInfo = new KQAttProcSetComInfo();
      String flow_deduct_card = Util.null2String(kqAttProcSetComInfo.getFlow_deduct_card(workflowid));
      String kqType = Util.null2String(kqAttProcSetComInfo.getkqType(workflowid));
      kqLog.info("KQFlowProcessChangeUtil handle_flow_deduct_card:flow_deduct_card:"+ flow_deduct_card+":workflowid:"+workflowid+":changedrequestid:"+changedrequestid);
      sql = "select * from "+ change_tablename+" where 1=1 and (status is null or status<>1) and requestid=?  ";
      rs.executeQuery(sql,changedrequestid);
      if("1".equalsIgnoreCase(flow_deduct_card)){
        String del_card_sql = "delete from kq_flow_deduct_card where requestid=? ";
        boolean isDone = rs1.executeUpdate(del_card_sql,changedrequestid);
        if(isDone){
          List<SplitBean> splitBeans = new ArrayList<>();
          while (rs.next()){
            SplitBean splitBean = new SplitBean();
            splitBean.setResourceId(rs.getString("resourceid"));
            splitBean.setBelongDate(rs.getString("belongdate"));
            splitBean.setFromDate(rs.getString("fromdate"));
            splitBean.setFromTime(rs.getString("fromtime"));
            splitBean.setToDate(rs.getString("todate"));
            splitBean.setToTime(rs.getString("totime"));
            splitBeans.add(splitBean);
          }
          if(!splitBeans.isEmpty()){
            new KQFlowActiontBiz().do_flow_deduct_card(splitBeans, kqType, Util.getIntValue(changedrequestid));
          }
        }
      }

    }
  }

  private void getProcessChangeParams(SplitBean bean, List<List> params,
      List<String> formateList, List<String> updateSql, String change_tablename) {
    List<Object> beanParams =  new ArrayList<Object>();
    beanParams.add(bean.getSubcompanyid());
    beanParams.add(bean.getDepartmentid());
    beanParams.add(bean.getJobtitle());
    beanParams.add(bean.getRequestId());
    beanParams.add(bean.getWorkflowId());
    beanParams.add(bean.getUsedetail());
    beanParams.add(bean.getDataId());
    beanParams.add(bean.getDetailId());
    beanParams.add(bean.getResourceId());
    beanParams.add(bean.getFromDate());
    beanParams.add(bean.getFromTime());
    beanParams.add(bean.getToDate());
    beanParams.add(bean.getToTime());
    beanParams.add(bean.getNewLeaveType());
    beanParams.add(bean.getDurationDB());
    beanParams.add(Util.null2s(bean.getDuration(),"0"));
    beanParams.add(bean.getDurationrule());
    beanParams.add(bean.getStatus());
    beanParams.add(bean.getBelongDate());
    beanParams.add(bean.getD_Mins());
    beanParams.add(bean.getSerialid());
    beanParams.add(bean.getTablenamedb());
    beanParams.add(bean.getFromdatedb());
    beanParams.add(bean.getFromtimedb());
    beanParams.add(bean.getTodatedb());
    beanParams.add(bean.getTotimedb());
    beanParams.add(bean.getLeavebackrequestid());
    if(bean.getDurationTypeEnum() == DurationTypeEnum.EVECTION){
      beanParams.add("1");
    }else if(bean.getDurationTypeEnum() == DurationTypeEnum.OUT){
      beanParams.add("2");
    }else{
      beanParams.add("");
    }
    String format = bean.getResourceId()+"_"+bean.getBelongDate();
    formateList.add(format);

    params.add(beanParams);
  }
}
