package com.engine.kq.wfset.util;

import com.alibaba.fastjson.JSON;
import com.engine.kq.biz.KQBalanceOfLeaveBiz;
import com.engine.kq.biz.KQFlowActiontBiz;
import com.engine.kq.biz.KQFormatBiz;
import com.engine.kq.biz.KQFormatData;
import com.engine.kq.biz.KQLeaveRulesBiz;
import com.engine.kq.biz.KQLeaveRulesComInfo;
import com.engine.kq.enums.DurationTypeEnum;
import com.engine.kq.enums.KqSplitFlowTypeEnum;
import com.engine.kq.log.KQLog;
import com.engine.kq.wfset.bean.SplitBean;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;

public class KQFlowLeaveBackUtil {
  private static KQLog kqLog = new KQLog();

  /**
   * 拆分销假流程数据 生成数据到splitBeans和backsplitBeans
   * @param sqlMap
   * @param splitBeans
   * @param datetimeFormatter
   * @param workflowId
   * @param requestId
   * @param rci
   * @return
   * @throws Exception
   */
  public Map<String,String> handleKQLeaveBackAction(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.LEAVEBACK);

  }
  /**
   * 销假流程和请假流程相似 单独需要赋值的数据
   * @param prefix
   * @param rs1
   * @param splitBean
   */
  public static void bean4LeaveBack(String prefix, RecordSet rs1, SplitBean splitBean) {
    String leaverequestid = Util.null2s(rs1.getString("leaverequestid"), "");
    String newLeaveType = Util.null2s(rs1.getString(prefix+"newLeaveType"), "");
    String minimumUnit = Util.null2s(Util.null2String(KQLeaveRulesBiz.getMinimumUnit(newLeaveType)),"-1");
    String computingMode = Util.null2s(Util.null2String(KQLeaveRulesBiz.getComputingMode(newLeaveType)),"-1");

    splitBean.setLeavebackrequestid(leaverequestid);
    splitBean.setNewLeaveType(newLeaveType);
    splitBean.setDurationrule(minimumUnit);
    splitBean.setComputingMode(computingMode);
    if("2".equalsIgnoreCase(computingMode)){
      //只有自然日 请假才有这个排除节假日、休息日的功能
      splitBean.setFilterholidays(KQLeaveRulesBiz.getFilterHolidays(newLeaveType));
    }
    if(newLeaveType.length() > 0){
      KQLeaveRulesComInfo kqLeaveRulesComInfo = new KQLeaveRulesComInfo();
      String conversion = kqLeaveRulesComInfo.getConversion(newLeaveType);
      splitBean.setConversion(conversion);
    }
  }



  /**
   * 销假流程特有的校验事件
   * @param rs1
   * @param datetimeFormatter
   * @param prefix
   * @param localFromDateTime
   * @param localToDateTime
   * @param result
   * @return
   */
  public static boolean leaveBackCheck(RecordSet rs1, DateTimeFormatter datetimeFormatter, String prefix,
      LocalDateTime localFromDateTime, LocalDateTime localToDateTime,
      Map<String, String> result) {

    String leavefromDate = Util.null2s(rs1.getString(prefix+"leavefromDate"), "");
    String leavetoDate = Util.null2s(rs1.getString(prefix+"leavetoDate"), "");
    String leavefromTime = Util.null2s(rs1.getString(prefix+"leavefromTime"), "");
    String leavetoTime = Util.null2s(rs1.getString(prefix+"leavetoTime"), "");
    String leaveduration = Util.null2s(rs1.getString(prefix+"leaveduration"), "");

    LocalDateTime localleaveFromDateTime = LocalDateTime.parse(leavefromDate+" "+leavefromTime,datetimeFormatter);
    LocalDateTime localleaveToDateTime = LocalDateTime.parse(leavetoDate+" "+leavetoTime,datetimeFormatter);

    //销假区间要在请假区间内
    if((localFromDateTime.isAfter(localleaveFromDateTime) || localFromDateTime.isEqual(localleaveFromDateTime)) &&
        (localFromDateTime.isBefore(localleaveToDateTime) || localFromDateTime.isEqual(localleaveToDateTime)) &&
        (localToDateTime.isAfter(localleaveFromDateTime) || localToDateTime.isEqual(localleaveFromDateTime)) &&
        (localToDateTime.isBefore(localleaveToDateTime)  || localToDateTime.isEqual(localleaveToDateTime))){
      //这是满足条件的
    }else{
      //不在请假区间的
      result.put("status", "-1");
      result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005407,weaver.general.ThreadVarLanguage.getLang())+"");
      return false;
    }
    return true;
  }
  /**
   *
   * @param splitBeans
   * @param result
   * @param isUpgrade 是否是升级，升级的话不需要处理假期余额数据
   * @param requestId
   * @throws Exception
   */
  public void handleSplitFLowActionData4LeaveBack(
      List<SplitBean> splitBeans, Map<String, String> result, boolean isUpgrade, int requestId) throws Exception{

    boolean isBackOk = buildLeaveBackData(splitBeans,requestId);
    if(isBackOk){
      if(!isUpgrade){
        //根据销假数据回填带薪数据
        reBuildBalance(splitBeans);
      }

    }else{
      result.put("status", "-1");
      result.put("message", ""+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005408,weaver.general.ThreadVarLanguage.getLang())+":"+weaver.systeminfo.SystemEnv.getHtmlLabelName(10005409,weaver.general.ThreadVarLanguage.getLang())+"");
      return ;
    }
  }

  /**
   * 销假数据拆分记录
   * @param backsplitBeans
   * @param requestId
   * @return
   */
  public boolean buildLeaveBackData(List<SplitBean> backsplitBeans, int requestId){
    RecordSet rs = new RecordSet();
    RecordSet rs1 = new RecordSet();
    RecordSet rs2 = new RecordSet();

    List<String> formateList = new ArrayList<>();
    String backbatchSql = "insert into "+ KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" (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)"+
        " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";
    List<List> params = new ArrayList<List>();
    List<String> updateSql = new ArrayList<>();

    for(SplitBean bean : backsplitBeans){
      List<Object> beanParams =  new ArrayList<Object>();
      if(bean.getD_Mins() > 0 && bean.getWorkmins() > 0 && bean.getD_Mins() == bean.getWorkmins()){
        //如果销假时长就是一条的工作时长
        String whole_day_sql = "select * from  "+KqSplitFlowTypeEnum.LEAVE.getTablename()+" where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and belongdate='"+bean.getBelongDate()+"' order by fromdate,fromtime";
        rs1.executeQuery(whole_day_sql);
        int i = 0 ;
        while (rs1.next()){
          if(i == 0){
            bean.setFromDate(rs1.getString("fromdate"));
            bean.setFromTime(rs1.getString("fromtime"));
          }
          bean.setToDate(rs1.getString("todate"));
          bean.setToTime(rs1.getString("totime"));
          i++;
        }
      }
      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());
      String format = bean.getResourceId()+"_"+bean.getBelongDate();
      formateList.add(format);

      params.add(beanParams);

      String updateLeaveSql = "";
      if(rs1.getDBType().equalsIgnoreCase("oracle")) {
        updateLeaveSql = "update "+ KqSplitFlowTypeEnum.LEAVE.getTablename()+" set leavebackrequestid=nvl(leavebackrequestid,'')||','||"+bean.getRequestId()+" where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and belongdate='"+bean.getBelongDate()+"'";
      }else if((rs1.getDBType()).equalsIgnoreCase("mysql")){
        updateLeaveSql = "update "+ KqSplitFlowTypeEnum.LEAVE.getTablename()+" set leavebackrequestid=concat(ifnull(leavebackrequestid,''),',',"+bean.getRequestId()+") where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and belongdate='"+bean.getBelongDate()+"'";
      }else {
        updateLeaveSql = "update "+ KqSplitFlowTypeEnum.LEAVE.getTablename()+" set leavebackrequestid=isnull(leavebackrequestid,'')+',"+bean.getRequestId()+"'"+" where "
            + " requestid="+bean.getLeavebackrequestid()+" and resourceid="+bean.getResourceId()+" and belongdate='"+bean.getBelongDate()+"'";
      }
      updateSql.add(updateLeaveSql);
    }
    if(!params.isEmpty()){
      //先根据requestid删除中间表里的数据，再做啥插入操作
      String delSql = "delete from "+KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" where requestid = "+requestId;
      rs2.executeUpdate(delSql);
      boolean isOk = rs1.executeBatchSql(backbatchSql, params);
      if(isOk){
        for(String up_sql : updateSql){
          kqLog.info("销假记录sql buildLeaveBackData up_sql:"+up_sql);
          boolean isUpOk = rs.executeUpdate(up_sql);
          kqLog.info("销假记录执行情况 buildLeaveBackData isUpOk:"+isUpOk);
        }
        KQFormatData kqFormatData = new KQFormatData();
        kqLog.info("handleSplitFLowActionData4LeaveBack:formateList:"+formateList);
        for(String format: formateList){
          String[] formats = format.split("_");
          kqLog.info("handleSplitFLowActionData4LeaveBack:formats:"+ JSON.toJSONString(formats));
          new KQFormatData().formatKqDate(formats[0],formats[1]);
        }
        return true;
      }else{
        return false;
      }
    }else{
      return false;
    }
  }

  /**
   * 根据销假数据回填带薪数据
   * @param backsplitBeans 销假数据
   * @return
   */
  public static void reBuildBalance(List<SplitBean> backsplitBeans) throws Exception{
    for(SplitBean splitBean : backsplitBeans){
      String requestid = splitBean.getRequestId();
      String resourceId = splitBean.getResourceId();
      String newLeaveType = splitBean.getNewLeaveType();
      String duration = splitBean.getDuration();
      String durationrule = splitBean.getDurationrule();
      String fromdatedb = splitBean.getFromdatedb();
      kqLog.info("销假返还:resourceId:"+resourceId+":duration:"+duration+":newLeaveType:"+newLeaveType+":durationrule:"+durationrule+":requestid:"+requestid+":fromdatedb:"+fromdatedb);
      KQBalanceOfLeaveBiz.reduceUsedAmount(resourceId, fromdatedb, newLeaveType, duration, "",requestid);
    }
  }
}
