package weaver.interfaces.htsc.cus;

import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetTrans;
import weaver.general.BaseBean;
import weaver.general.GCONST;
import weaver.general.Util;
import weaver.interfaces.htsc.cus.entity.headquarters.HeadquartersFkspEntity;
import weaver.interfaces.htsc.cus.entity.headquarters.HeadquartersLcEntity;
import weaver.interfaces.htsc.cus.entity.headquarters.HeadquartersSplType;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import weaver.workflow.request.RequestManager;

/**
 * 总部付款审批链
 */
public class HeadquartersPaymentAction extends BaseBean implements Action {
  
  //基础表
  private static final String TABLE_SP = "uf_zbfkspl";
  //部门表
  private static final String TABLE_DEPARTMENT = "hrmdepartment";
  //部门自定义表
  private static final String TABLE_DEPARTMENT_DEFINED = "hrmdepartmentdefined";
  
  @Override
  public String execute(RequestInfo requestInfo) {
    try {
      //流程请求ID
      String requestId = Util.null2String(requestInfo.getRequestid());
      //主表
      String mainTable = Util.null2String(requestInfo.getRequestManager().getBillTableName());
      //本币付款明细表
      String dt8Table = mainTable + "_dt8";
      //外币付款明细表
      String dt9Table = mainTable + "_dt9";
      //查询主表数据
      String sql = String.format(
          "select id,szbm,ysgly,bmfzr,ejbmfzrlcsp,fyhjshlcsp,cwfzrlcsp,sxcwglcsp,fgldlcsp,zclcsp,ggfyqtfy,ngbmfgld,hjxxjeitxmf,sfxlxzcxshfcxf from %s where requestid = ?",
          mainTable);
      RecordSet rs = new RecordSet();
      rs.executeQuery(sql, requestId);
      while (rs.next()) {
        Map<String, Object> param = new HashMap<>();
        int mainId = Util.getIntValue(rs.getInt("id"));
        String ggfyqtfy = Util.null2String(rs.getString("ggfyqtfy"));
        //是否向联席主承销商划付承销费
        String sfxlxzcxshfcxf = Util.null2String(rs.getString("sfxlxzcxshfcxf"));
        //所在部门
        String szbm = Util.null2String(rs.getString("szbm"));
        String ngbmfgld = Util.null2String(rs.getString("ngbmfgld"));
        Set<String> ngbmfgldSet = new HashSet<>();
        if(StringUtils.isNotBlank(ngbmfgld)){
          ngbmfgldSet = new HashSet<>(Arrays.asList(ngbmfgld.split(",")));
        }
        HeadquartersLcEntity headquartersLcEntity = new HeadquartersLcEntity();
        headquartersLcEntity.setSzbm(Util.null2String(getSzbm(mainId, dt8Table, dt9Table)));
        headquartersLcEntity.setYsgly(Util.null2String(rs.getString("ysgly")));
        headquartersLcEntity.setBmfzr(Util.null2String(rs.getString("bmfzr")));
        headquartersLcEntity.setEjbmfzrlcsp(Util.null2String(rs.getString("ejbmfzrlcsp")));
        headquartersLcEntity.setFyhjshlcsp(Util.null2String(rs.getString("fyhjshlcsp")));
        headquartersLcEntity.setCwfzrlcsp(Util.null2String(rs.getString("cwfzrlcsp")));
        headquartersLcEntity.setSxcwglcsp(Util.null2String(rs.getString("sxcwglcsp")));
        headquartersLcEntity.setFgldlcsp(Util.null2String(rs.getString("fgldlcsp")));
        headquartersLcEntity.setZclcsp(Util.null2String(rs.getString("zclcsp")));
        //取主表合计金额作为审批链匹配金额 不再取明细单条数据
        headquartersLcEntity.setHjxxjeitxmf(Util.null2String(rs.getString("hjxxjeitxmf")));
        //公共费用选项
        headquartersLcEntity.setGgfyqtfy(Util.null2String(rs.getString("ggfyqtfy")));
        //获取dt8 dt9中对应的明细信息
        List<HeadquartersLcEntity> lcEntitiesWithDiffDetails = queryFysjcdbm(mainId,
            headquartersLcEntity, dt8Table, dt9Table);
        writeLog("lc details info: " + JSON.toJSONString(lcEntitiesWithDiffDetails));
        //获取审批链
        List<HeadquartersFkspEntity> fkspList = getFkspList(headquartersLcEntity, TABLE_SP);
        writeLog("query spllist:" + JSON.toJSONString(fkspList));
        Map<String, Set<String>> updateParams = new HashMap<>();
        if (CollectionUtils.isEmpty(updateParams.get("sxcwglcsp"))) {
          updateParams.put("sxcwglcsp", new HashSet<>());
        }
        if (CollectionUtils.isEmpty(updateParams.get("fgldlcsp"))) {
          updateParams.put("fgldlcsp", new HashSet<>());
        }
        if (CollectionUtils.isEmpty(updateParams.get("zclcsp"))) {
          updateParams.put("zclcsp", new HashSet<>());
        }
        if (CollectionUtils.isNotEmpty(lcEntitiesWithDiffDetails) &&
            CollectionUtils.isNotEmpty(fkspList)) {
          for (HeadquartersLcEntity lcEntityWithDiffDetails : lcEntitiesWithDiffDetails) {
            HeadquartersFkspEntity headquartersFkspEntity;
            Map<String, Set<String>> ParamTemp = new HashMap<>();
            headquartersFkspEntity = combineSpData(lcEntityWithDiffDetails, fkspList);
            writeLog("combine spl and lc" + JSON.toJSONString(headquartersFkspEntity));
            if (headquartersFkspEntity != null) {
              String fysjcdbm = headquartersLcEntity.getSzbm();
              setUpdateInfo(fysjcdbm, headquartersFkspEntity, ParamTemp);
              Set sxcwgTempSet = new HashSet<>(ParamTemp.get("sxcwglcsp"));
              sxcwgTempSet.remove("");
              Set fgldTempSet = new HashSet(ParamTemp.get("fgldlcsp"));
              fgldTempSet.remove("");
              Set zcTempSet = new HashSet(ParamTemp.get("zclcsp"));
              zcTempSet.remove("");
              updateParams.get("sxcwglcsp").addAll(sxcwgTempSet);
              updateParams.get("fgldlcsp").addAll(fgldTempSet);
              updateParams.get("zclcsp").addAll(zcTempSet);
            }
          }
        }
        if (updateParams.size() > 0) {
          if (!CollectionUtils.isEmpty(updateParams.get("sxcwglcsp"))) {
            param.put("sxcwglcsp", String.join(",", updateParams.get("sxcwglcsp")));
          }
          if (!CollectionUtils.isEmpty(updateParams.get("fgldlcsp"))) {
            param.put("fgldlcsp", String.join(",", updateParams.get("fgldlcsp")));
          }
          if (!CollectionUtils.isEmpty(updateParams.get("zclcsp"))) {
            param.put("zclcsp", String.join(",", updateParams.get("zclcsp")));
          }
        }
        if (param.size() > 0) {
          //处理更新数据 当首席财务和分管领导重复是 保留分管领导 去掉首席财务
          Set<String> sxcwgSet = new HashSet<>(Arrays.asList(
              ((String) (Objects.nonNull(param.get("sxcwglcsp")) ? param.get("sxcwglcsp") : ""))
                  .split(",")));
          Set<String> fgldSet = new HashSet<>(Arrays.asList(
              ((String) (Objects.nonNull(param.get("fgldlcsp")) ? param.get("fgldlcsp") : ""))
                  .split(",")));
          // for (String str : fgldSet) {
          //   if (sxcwgSet.contains(str)) {
          //     sxcwgSet.remove(str);
          //   }
          // }
          sxcwgSet = sxcwgSet.stream().filter(StringUtils::isNotBlank).collect(Collectors.toSet());
          
          //如果分管领导包含或等于韩臻聪，则总裁需为周易
          if (ggfyqtfy.equals("0")) {
            if (ngbmfgldSet.contains("13723")) {
              param.put("zclcsp", "22797");
            }
            if (ngbmfgldSet.contains("12016") && sxcwgSet.contains("12016")) {
              sxcwgSet.remove("12016");
            }
          } else if (ggfyqtfy.equals("1")) {
            if (fgldSet.contains("13723")) {
              param.put("zclcsp", "22797");
            }
            if (fgldSet.contains("12016") && sxcwgSet.contains("12016")) {
              sxcwgSet.remove("12016");
            }
            //公共费用为否1的情况下，且szbm = 670 且承销选是0，则不过分管领导节点
            if ("0".equals(sfxlxzcxshfcxf) && "670".equals(szbm)) {
              param.put("fgldlcsp", "");
            }
          }
          param.put("sxcwglcsp", String.join(",", sxcwgSet));
          updateMainTable(mainTable, mainId, param);
          writeLog("update main table, updateparam:" + JSON.toJSONString(param));
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
      requestInfo.getRequestManager().setMessageid("111d11111");
      requestInfo.getRequestManager().setMessagecontent("接口捕获异常，请联系管理员处理！");
      return Action.FAILURE_AND_CONTINUE;
    }
    return Action.SUCCESS;
  }
  
  /**
   * 获取费用实际承担部门
   *
   * @param mainId
   * @param headquartersLcEntity
   * @param dt8Table
   * @param dt9Table
   */
  private List<HeadquartersLcEntity> queryFysjcdbm(int mainId,
      HeadquartersLcEntity headquartersLcEntity, String dt8Table, String dt9Table) {
    List<HeadquartersLcEntity> lcEntitiesWithDiffDetails = new ArrayList<>();
    //同一流程有不同明细情况，在匹配审批链时，每个不同的明细都视作一条流程处理
    String sql8 = String.format("select fysjcdbm,jshjje from %s where mainid = ?", dt8Table);
    RecordSet rs8 = new RecordSet();
    rs8.executeQuery(sql8, mainId);
    while (rs8.next()) {
      HeadquartersLcEntity headquartersLcEntityTemp = new HeadquartersLcEntity();
      BeanUtils.copyProperties(headquartersLcEntity, headquartersLcEntityTemp);
      // headquartersLcEntityTemp.setHjxxjeitxmf((rs8.getString("jshjje")));
      headquartersLcEntityTemp.setFysjcdbm(rs8.getString("fysjcdbm"));
      lcEntitiesWithDiffDetails.add(headquartersLcEntityTemp);
    }
    String sql9 = String.format("select fysjcdbm,rmbje from %s where mainid = ?", dt9Table);
    RecordSet rs9 = new RecordSet();
    rs9.executeQuery(sql9, mainId);
    while (rs9.next()) {
      HeadquartersLcEntity headquartersLcEntityTemp = new HeadquartersLcEntity();
      BeanUtils.copyProperties(headquartersLcEntity, headquartersLcEntityTemp);
      // headquartersLcEntityTemp.setHjxxjeitxmf((rs9.getString("rmbje")));
      headquartersLcEntityTemp.setFysjcdbm(rs9.getString("fysjcdbm"));
      lcEntitiesWithDiffDetails.add(headquartersLcEntityTemp);
    }
    List<HeadquartersLcEntity> resut = lcEntitiesWithDiffDetails.stream().
        filter(item -> StringUtils.isNotBlank(item.getHjxxjeitxmf()) &&
                       Double.parseDouble(item.getHjxxjeitxmf()) > Double.valueOf("0"))
        .collect(Collectors.toList());
    return resut;
  }
  
  /**
   * 获取所有审批链
   *
   * @param headquartersLcEntity
   * @param clspTable
   * @return
   */
  private List<HeadquartersFkspEntity> getFkspList(HeadquartersLcEntity headquartersLcEntity,
      String clspTable) {
    List<HeadquartersFkspEntity> fkspList = new ArrayList<>();
    String sql = String.format(
        "select id,spllx,ngbm,jeqk,zxzfje,zdzfje,ejbmfzr,ysgly,yjbmfzr,fyhj,cwfzr,sxcwg,fgld,zc,fycdbm from %s ",
        clspTable);
    RecordSet rs = new RecordSet();
    rs.executeQuery(sql);
    while (rs.next()) {
      HeadquartersFkspEntity headquartersFkspEntity = new HeadquartersFkspEntity();
      headquartersFkspEntity.setId(Util.null2String(rs.getString("id")));
      headquartersFkspEntity.setSpllx(Util.null2String(rs.getString("spllx")));
      headquartersFkspEntity.setNgbm(Util.null2String(rs.getString("ngbm")));
      headquartersFkspEntity.setJeqk(Util.null2String(rs.getString("jeqk")));
      headquartersFkspEntity.setZxzfje(Util.null2String(rs.getString("zxzfje")));
      headquartersFkspEntity.setZdzfje(Util.null2String(rs.getString("zdzfje")));
      headquartersFkspEntity.setEjbmfzr(Util.null2String(rs.getString("ejbmfzr")));
      headquartersFkspEntity.setYsgly(Util.null2String(rs.getString("ysgly")));
      headquartersFkspEntity.setYjbmfzr(Util.null2String(rs.getString("yjbmfzr")));
      headquartersFkspEntity.setFyhj(Util.null2String(rs.getString("fyhj")));
      headquartersFkspEntity.setCwfzr(Util.null2String(rs.getString("cwfzr")));
      headquartersFkspEntity.setSxcwg(Util.null2String(rs.getString("sxcwg")));
      headquartersFkspEntity.setFgld(Util.null2String(rs.getString("fgld")));
      headquartersFkspEntity.setZc(Util.null2String(rs.getString("zc")));
      headquartersFkspEntity.setFycdbm(Util.null2String(rs.getString("fycdbm")));
      fkspList.add(headquartersFkspEntity);
    }
    return fkspList;
  }
  
  /**
   * 审批链匹配方法
   *
   * @param headquartersLcEntity
   * @param fkspList
   * @return
   */
  private HeadquartersFkspEntity combineSpData(HeadquartersLcEntity headquartersLcEntity,
      List<HeadquartersFkspEntity> fkspList) {
    String fysjcdbm = headquartersLcEntity.getFysjcdbm();
    String szbm = headquartersLcEntity.getSzbm();
    Set<String> szbmSet = Arrays.stream(szbm.split(",")).collect(Collectors.toSet());
    double je = Double.parseDouble(headquartersLcEntity.getHjxxjeitxmf());
    String ggfyqtfy = headquartersLcEntity.getGgfyqtfy();
    List<HeadquartersFkspEntity> tempList = fkspList;
    List<HeadquartersFkspEntity> amountList = new ArrayList<>();
    HeadquartersFkspEntity result = new HeadquartersFkspEntity();
    if (CollectionUtils.isNotEmpty(fkspList)) {
      for (HeadquartersFkspEntity headquartersFkspEntity : tempList) {
        if (!headquartersFkspEntity.getSpllx().equals(HeadquartersSplType.ZBTYFK)) {
          continue;
        }
        Set<String> fycdbmSet = new HashSet<>(
            Arrays.asList(headquartersFkspEntity.getFycdbm().split(",")));
        Set<String> ngbmSet = new HashSet<>(
            Arrays.asList(headquartersFkspEntity.getNgbm().split(",")));
        // 如果公共费用选是则不走虚拟部门审批链 选否才走虚拟部门审批链
        if ("1".equals(ggfyqtfy) && fycdbmSet.contains(fysjcdbm)) {
          result = headquartersFkspEntity;
          return result;
        } else {
          //费用承担部门不匹配，金额字段需要匹配
          if (StringUtils.isBlank(headquartersFkspEntity.getZxzfje()) &&
              StringUtils.isBlank(headquartersFkspEntity.getZdzfje())) {
            continue;
          }
          //最小预算等于合计,且存在区间取值
          if (StringUtils.isNotBlank(headquartersFkspEntity.getZxzfje()) &&
              StringUtils.isNotBlank(headquartersFkspEntity.getZdzfje()) &&
              Double.parseDouble(headquartersFkspEntity.getZxzfje()) == je) {
            if (Double.parseDouble(headquartersFkspEntity.getZdzfje()) > je) {
              amountList.add(headquartersFkspEntity);
              break;
            }
          }
          //最大预算等于合计,且符合取值条件
          //          if ((StringUtils.isBlank(headquartersFkspEntity.getZxzfje()) ||
          //               Double.parseDouble(headquartersFkspEntity.getZxzfje()) == 0.0) &&
          //              Double.parseDouble(headquartersFkspEntity.getZdzfje()) == je) {
          //            amountList.add(headquartersFkspEntity);
          //            break;
          //          }
          //金额为10万的情况下，匹配最小支付金额审批链
          if ((StringUtils.isBlank(headquartersFkspEntity.getZdzfje()) ||
               Double.parseDouble(headquartersFkspEntity.getZdzfje()) == 0.0) &&
              Double.parseDouble(headquartersFkspEntity.getZxzfje()) == je) {
            amountList.add(headquartersFkspEntity);
            break;
          }
        }
      }
      if (org.apache.commons.collections4.CollectionUtils.isEmpty(amountList)) {
        amountList = tempList.stream().filter(ce ->
            (StringUtils.isBlank(ce.getZdzfje()) || Double.parseDouble(ce.getZdzfje()) == 0.0) &&
            !StringUtils.isBlank(ce.getZxzfje()) && Double.parseDouble(ce.getZxzfje()) > je)
            .collect(Collectors.toList());
      }
      if (org.apache.commons.collections4.CollectionUtils.isEmpty(amountList)) {
        amountList = tempList.stream().filter(ce ->
            (StringUtils.isBlank(ce.getZxzfje()) || Double.parseDouble(ce.getZxzfje()) == 0.0) &&
            !StringUtils.isBlank(ce.getZdzfje()) && Double.parseDouble(ce.getZdzfje()) < je)
            .collect(Collectors.toList());
      }
      if (org.apache.commons.collections4.CollectionUtils.isEmpty(amountList)) {
        amountList = tempList.stream().filter(
            ce -> !StringUtils.isBlank(ce.getZxzfje()) && !StringUtils.isBlank(ce.getZdzfje()) &&
                  Double.parseDouble(ce.getZxzfje()) < je &&
                  Double.parseDouble(ce.getZdzfje()) > je).collect(Collectors.toList());
      }
      tempList = amountList.stream().filter(e -> {
        Set<String> ngbmSet = Arrays.stream(e.getNgbm().split(",")).collect(Collectors.toSet());
        Set<String> tempSet = new HashSet<>(ngbmSet);
        tempSet.retainAll(szbmSet);
        return CollectionUtils.isNotEmpty(tempSet);
      }).collect(Collectors.toList());
      if (!org.apache.commons.collections4.CollectionUtils.isEmpty(tempList)) {
        result = tempList.get(0);
      } else {
        writeLog("not found spl");
      }
    }
    return result;
  }
  
  /**
   * 更新主表字段
   *
   * @param tableName
   * @param mainId
   * @param param
   */
  private void updateMainTable(String tableName, int mainId, Map<String, Object> param) {
    RecordSetTrans rts = new RecordSetTrans();
    rts.setAutoCommit(false);
    String updateSql = " update " + tableName + " set ";
    String sqlWhere = " where id=" + mainId;
    Object[] valueArr = new Object[param.size()];
    int i = 0;
    for (Entry<String, Object> entry : param.entrySet()) {
      String key = entry.getKey();
      if (i == 0) {
        updateSql = String.format("%s%s=?", updateSql, key);
      } else {
        updateSql = String.format("%s, %s=?", updateSql, key);
      }
      valueArr[i] = entry.getValue();
      i++;
    }
    updateSql += sqlWhere;
    try {
      boolean result = rts.executeUpdate(updateSql, valueArr);
      if (result) {
        rts.commit();
      } else {
        writeLog("update main table failed");
      }
    } catch (Exception e) {
      rts.rollback();
      writeLog("update main table exception", e);
    }
  }
  
  private void setUpdateInfo(String szbm, HeadquartersFkspEntity headquartersFkspEntity,
      Map<String, Set<String>> updateParam) {
    String sxcwg = headquartersFkspEntity.getSxcwg();
    String fgld = headquartersFkspEntity.getFgld();
    String zc = headquartersFkspEntity.getZc();
    if (!updateParam.containsKey("sxcwglcsp")) {
      updateParam.put("sxcwglcsp", new HashSet<>());
    }
    if (!updateParam.containsKey("fgldlcsp")) {
      updateParam.put("fgldlcsp", new HashSet<>());
    }
    if (!updateParam.containsKey("zclcsp")) {
      updateParam.put("zclcsp", new HashSet<>());
    }
    if (StringUtils.isNotBlank(sxcwg)) {
      updateParam.get("sxcwglcsp").add(sxcwg);
    }
    if (StringUtils.isNotBlank(fgld)) {
      if (fgld.equals("0")) {
        Set<String> szbmSet = Arrays.stream(szbm.split(",")).collect(Collectors.toSet());
        for (String bm : szbmSet) {
          String fgldsp = getDeptLeaderByDeptId(bm, TABLE_DEPARTMENT_DEFINED);
          updateParam.get("fgldlcsp").add(fgldsp);
        }
      }
    }
    if (StringUtils.isNotBlank(zc)) {
      updateParam.get("zclcsp").add(zc);
    }
  }
  
  private String getDeptLeaderByDeptId(String id, String departmentdefinedTable) {
    String result = "";
    String sql = String
        .format("select deptleaders from %s where deptid = ?", departmentdefinedTable);
    RecordSet rs = new RecordSet();
    rs.executeQuery(sql, id);
    while (rs.next()) {
      result = Util.null2String(rs.getString("deptleaders"));
    }
    return result;
  }
  
  private String getSzbm(int mainId, String dt8Table, String dt9Table) {
    String szbm = "";
    Set<String> set = new HashSet<>();
    RecordSet rs = new RecordSet();
    String sql8 = String.format("select fysjcdbm from %s where mainid = ?", dt8Table);
    rs.executeQuery(sql8, mainId);
    while (rs.next()) {
      String temp = rs.getString("fysjcdbm");
      if (StringUtils.isNotBlank(temp) && StringUtils.isNotEmpty(temp)) {
        set.add(temp);
      }
    }
    String sql9 = String.format("select fysjcdbm from %s where mainid = ?", dt9Table);
    rs.executeQuery(sql9, mainId);
    while (rs.next()) {
      String temp = rs.getString("fysjcdbm");
      if (StringUtils.isNotBlank(temp) && StringUtils.isNotEmpty(temp)) {
        set.add(temp);
      }
    }
    if (CollectionUtils.isNotEmpty(set)) {
      szbm = String.join(",", set);
    }
    return szbm;
  }
  
  public static void main(String[] args) {
    GCONST.setRootPath("WEB-INF/");
    GCONST.setServerName("ecology");
    HeadquartersPaymentAction action = new HeadquartersPaymentAction();
    RequestInfo requestInfo = new RequestInfo();
    requestInfo.setRequestid("2879878");
    RequestManager requestManager = new RequestManager();
    //169环境主表180  171环境主表171
    requestManager.setBilltablename("formtable_main_171");
    requestInfo.setRequestManager(requestManager);
    action.execute(requestInfo);
    System.out.println("execute end");
  }
}
