package com.engine.htsc.financialadjustment.util;

import cn.hutool.core.lang.Assert;
import com.engine.htsc.payment.pojo.*;
import com.engine.htsc.payment.util.PayUtil;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.interfaces.htsc.cus.HTUtil;

import java.util.*;


/**
 * utils for financial adjust work flow
 */
public final class BizUtil {

  //联合,总部预算表和会计表
  private static final String LH_YSB = "uf_lhkmpz";
  private static final String LH_KJB = "uf_lhkjkmpz";
  private static final String ZB_YSB = "uf_kmpz";
  private static final String ZB_KJB = "uf_kjkmpz";

  /**
   * 获取财务调整流程核算数据p
   *
   * @return CostAccountDto
   */
  public static CostAccountDto getAdjustCost(String rid, String lb) throws Exception {
    RecordSet rs = new RecordSet();
    rs.writeLog("获取财务调整流程核算数据 requestid:" + rid);
    String tablename = PayUtil.getTbNameByRid(rid);
    CostAccountDto accountDto = new CostAccountDto();
    try {
      DepartmentComInfo dc = new DepartmentComInfo();
      ResourceComInfo rc = new ResourceComInfo();
      String sql = "SELECT t1.ID,t1.NGR,t1.SZBM,t1.LCBH,t1.RZRQ,t2.REQUESTNAME FROM " + tablename + " t1\n" +
          "LEFT JOIN WORKFLOW_REQUESTBASE t2\n" +
          "ON t1.REQUESTID = t2.REQUESTID \n" +
          "WHERE t1.REQUESTID = ?";
      rs.executeQuery(sql, rid);
      String mid = "";
      if (rs.next()) {
        String person = Util.null2String(rs.getString("NGR"));
        String dept = Util.null2String(rs.getString("SZBM"));
        String requestMark = Util.null2String(rs.getString("LCBH"));
        String title = Util.null2String(rs.getString("REQUESTNAME"));
        String entryDate = Util.null2String(rs.getString("RZRQ"));
        mid = Util.null2String(rs.getString("ID"));

        accountDto.setElectronicBill("");
        accountDto.setType(lb); //总部付款费用核算
        accountDto.setBz2("0");
        accountDto.setNgrDept(dc.getDepartmentmark(dept));
        accountDto.setNgrDeptCode(dc.getDepartmentCode(dept));
        accountDto.setNgrName(rc.getWorkcode(person));
        accountDto.setRequestMark(requestMark);
        accountDto.setRequestId(requestMark); //djid传流程编码,流程id总部不需要
        accountDto.setAttachmentNum("");
        accountDto.setLocationName("");
        accountDto.setTitle(title);
        accountDto.setCurrency("RMB");
        accountDto.setCreateDate(entryDate);
        accountDto.setReimbursementWay("");
        accountDto.setPayOrderNo(requestMark); //总部付款付款单号直接传流程编码
      }

      sql = "SELECT SFRHJZ,FYCDR,FYCDBM,JE,SFCYS,JDFX,YSKM,HJKM FROM " + tablename + "_DT2 WHERE MAINID = ?";
      rs.executeQuery(sql, mid);
      List<KjDetail> kjs = new ArrayList<>();
      List<PayDetail> pays = new ArrayList<>();
      while (rs.next()) {
        String entryKj = Util.null2String(rs.getString("SFRHJZ"));
        String debtPerson = Util.null2String(rs.getString("FYCDR"));
        String debtDept = Util.null2String(rs.getString("FYCDBM"));
        String amount = Util.null2String(rs.getString("JE"));
        String overBudget = Util.null2String(rs.getString("SFCYS"));
        String doc = Util.null2String(rs.getString("JDFX")); //计帐方向
        String budgetItem = nvl(Util.null2String(rs.getString("YSKM")));
        String accountItem = nvl(Util.null2String(rs.getString("HJKM")));
        //入会计帐为是才写记录
        if ("1".equals(entryKj)) {
          KjDetail kj = new KjDetail();
          BudgetData budgetData = new BudgetData();
          budgetData.setRelationCode(accountItem);
          budgetData.setItemCode(budgetItem);
          budgetData.setItemName(getYsName(budgetItem, "1"));
          SubjectData subjectData = new SubjectData();
          subjectData.setItemCode(accountItem);
          subjectData.setItemName(getKjName(accountItem, "1"));
          kj.setBudgetData(budgetData); //预算科目
          kj.setSubjectData(subjectData); //会计科目
          kj.setExpenseDeptCode(dc.getDepartmentCode(debtDept));
          kj.setExpenseDept(dc.getDepartmentmark(debtDept));
          kj.setExpenseBadge("");
          kj.setExpensePerson(rc.getLastname(debtPerson));
          kj.setPriceRMB(amount);
          kj.setMoney(amount);
          kj.setProjectCode("");
          kj.setProject("");
          kj.setReason(doc); // 0:借 1:贷 对应saveFj 1:借 2:贷 (财务调整不使用reason作为关键字段,设置为借贷方做业务判断)
          kjs.add(kj);

        }
      }
      accountDto.setKjDetails(kjs);
      accountDto.setPayDetails(pays);
    } catch (Exception e) {
      rs.writeLog("catch exception:" + e.getMessage());
    }
    return accountDto;
  }

  /**
   * 获取财务调整核预算数据
   *
   * @param status 预算状态, 3预占,1实占
   * @return budgetDTO
   */
  public static BudgetDTO getAdjustBudget(String rid, String status) throws Exception {
    RecordSet rs = new RecordSet();
    rs.writeLog("获取财务调整核预算数据 requestid:" + rid + "; status:" + status);
    BudgetDTO budgetDTO = new BudgetDTO();
    String tbNameByRid = PayUtil.getTbNameByRid(rid);
    String mid = "";
    try {
      ResourceComInfo rc = new ResourceComInfo();
      String sql = String.format("SELECT t1.ID,t1.REQUESTID,t1.LCBH,t1.NGR,t1.RZRQ,t2.REQUESTNAME,t2.REQUESTMARK FROM %s t1\n" +
          "LEFT JOIN WORKFLOW_REQUESTBASE t2\n" +
          "ON t1.REQUESTID = t2.REQUESTID \n" +
          "WHERE t1.REQUESTID = ?", tbNameByRid);
      rs.executeQuery(sql, rid);
      if (rs.next()) {
        budgetDTO.setBillNum(Util.null2String(rs.getString("REQUESTID")));
        budgetDTO.setBizDate(Util.null2String(rs.getString("RZRQ")));
        budgetDTO.setBillStatus(status);
        budgetDTO.setBillName(Util.null2String(rs.getString("LCBH")));
        budgetDTO.setBillTitle(Util.null2String(rs.getString("REQUESTNAME")));
        budgetDTO.setPesonName(rc.getLastname(rs.getString("NGR")));
        mid = Util.null2String(rs.getString("ID")); //明细外键
      }
    } catch (Exception e) {
      rs.writeLog("获取财务调整预算主表数据 catch exception:" + e.getMessage());
      return null;
    }

    try {
      DepartmentComInfo dc = new DepartmentComInfo();
      List<BudgetList> budgetItems = new ArrayList<>();
      String sql = String.format("SELECT SFRHJZ,FYCDR,FYCDBM,JE,SFCYS,JDFX,YSKM,HJKM FROM %s WHERE MAINID = ?", tbNameByRid + "_DT2");
      rs.executeQuery(sql, mid);
      String uuid = UUID.randomUUID().toString();
      int i = 1;
      while (rs.next()) {
        String debtDept = Util.null2String(rs.getString("FYCDBM"));
        String amount = Util.null2String(rs.getString("JE"));
        String budgetCode = Util.null2String(rs.getString("YSKM"));
        String superBudgetCodeLh = "";
        if (budgetDTO.getBillName().contains("联合")) {
          superBudgetCodeLh = PayUtil.getSuperBudgetCode(nvl(budgetCode));
        } else {
          superBudgetCodeLh = PayUtil.getSuperBudgetCodeLh(nvl(budgetCode));
        }
        BudgetList budgetList = new BudgetList();
        budgetList.setAmount(amount);
        budgetList.setNoTaxAmount(amount);
        budgetList.setTaxAmount("0.00");
        budgetList.setBgElement("0101");
        budgetList.setBillEntryID(uuid + "#" + i);
        budgetList.setDeptNum(dc.getDepartmentCode(debtDept));
        budgetList.setItemEntryNum(nvl(budgetCode));
        budgetList.setBgItem(superBudgetCodeLh);
        budgetList.setBgITElement(superBudgetCodeLh);
        budgetItems.add(budgetList);
        i++;
      }
      budgetDTO.setList(budgetItems);
      return budgetDTO;
    } catch (Exception e) {
      rs.writeLog("获取财务调整明细表数据 catch exception:" + e.getMessage());
      return null;
    }
  }

  /**
   * get project browser by code
   */
  public static Map<String, String> getProjectBrowserByCode(String userCode, String projectCode) {
    Map<String, String> res = new HashMap<>();
    HTUtil htUtil = new HTUtil();
    Map<String, Object> info = htUtil.getProjectInfoByCode(userCode, projectCode);
    if (info.containsKey("id")) {
      res.put("value", Util.null2String(info.get("id")));
      res.put("name", Util.null2String(info.get("name")));
    } else {
      res.put("value", "");
      res.put("name", "");
    }
    return res;
  }

  /**
   * get dept id by dept code
   */
  public static Map<String, String> getDidByCode(String deptCode) throws Exception {
    RecordSet rs = new RecordSet();
    Map<String, String> res = new HashMap<>();
    rs.executeQuery("SELECT h.ID,h.DEPARTMENTMARK FROM HRMDEPARTMENT h WHERE h.DEPARTMENTCODE = ?", deptCode);
    if (rs.next()) {
      res.put("value", Util.null2String(rs.getString("ID")));
      res.put("name", Util.null2String(rs.getString("DEPARTMENTMARK")));
      return res;
    } else {
      throw new IllegalArgumentException("deptCode not exist, deptCode: " + deptCode);
    }
  }


  /**
   * get employee id by work code
   */
  public static Map<String, String> getUidByWc(String wc) throws Exception {
    RecordSet rs = new RecordSet();
    Map<String, String> res = new HashMap<>();
    rs.executeQuery("SELECT h.ID,h.LASTNAME FROM HRMRESOURCE h WHERE h.WORKCODE =?", wc);
    if (rs.next()) {
      res.put("value", Util.null2String(rs.getString("ID")));
      res.put("name", Util.null2String(rs.getString("LASTNAME")));
      return res;
    } else {
      throw new IllegalArgumentException("workcode not exist, workcode: " + wc);
    }
  }

  /**
   * get budget jsonObject by code and type
   *
   * @param budgetCode 预算code
   * @param type       0:总部 1:联合
   */
  public static Map<String, String> getBudgetObj(String budgetCode, String type) throws Exception {
    Assert.notBlank(budgetCode, "budgetCode can not be empty");
    RecordSet rs = new RecordSet();
    Map<String, String> res = new HashMap<>();
    String budgetTable = "";
    if ("0".equals(type)) {
      budgetTable = ZB_YSB;
    } else if ("1".equals(type)) {
      budgetTable = LH_YSB;
    } else {
      throw new IllegalArgumentException("type not match: 0:总部 1:联合");
    }
    rs.writeLog(String.format("get budget specialObj ,budgetCode: %s; zb or lh: %s; budgetTable: %s",
        budgetCode, type, budgetTable));
    rs.executeQuery(String.format("SELECT YSKMMC FROM %s WHERE YSKMBM = ? ", budgetTable), budgetCode);
    if (rs.next()) {
      res.put("value", budgetCode);
      res.put("name", Util.null2String(rs.getString("YSKMMC")));
      return res;
    } else {
      throw new Exception("budget code " + budgetCode + " not exist");
    }
  }

  /**
   * get account jsonObject by code and type
   */
  public static Map<String, String> getAccountObj(String accountCode, String type) throws Exception {
    Assert.notBlank(accountCode, "accountCode can not be empty");
    RecordSet rs = new RecordSet();
    Map<String, String> res = new HashMap<>();
    String accountTable = "";
    if ("0".equals(type)) {
      accountTable = ZB_KJB;
    } else if ("1".equals(type)) {
      accountTable = LH_KJB;
    } else {
      throw new IllegalArgumentException("type not match: 0:总部 1:联合");
    }
    rs.writeLog(String.format("get account specialObj ,accountCode: %s; zb or lh: %s; accountTable: %s",
        accountCode, type, accountTable));
    rs.executeQuery(String.format("SELECT HJKMMC FROM %s WHERE HJKMBM = ? ", accountTable), accountCode);
    if (rs.next()) {
      res.put("value", accountCode);
      res.put("name", Util.null2String(rs.getString("HJKMMC")));
      return res;
    } else {
      throw new Exception("account code " + accountCode + " not exist");
    }

  }

  /**
   * 科目截断
   *
   * @return 预算科目或会计科目
   */
  private static String nvl(String codeWithLine) {
    if (codeWithLine.contains("_")) {
      return codeWithLine.split("_")[1];
    }
    return "";
  }

  /**
   * 获取预算名称
   *
   * @param ysCode 预算code
   * @param lhOrZb 1代表联合
   * @return 名称
   */
  public static String getYsName(String ysCode, String lhOrZb) {
    RecordSet rs = new RecordSet();
    String tableName = ZB_YSB;
    if ("1".equals(lhOrZb)) {
      tableName = LH_YSB;
    }
    rs.executeQuery("SELECT YSKMMC FROM " + tableName + " WHERE YSKMBM = ?", ysCode);
    if (rs.next()) {
      return Util.null2String(rs.getString("YSKMMC"));
    } else {
      return "";
    }
  }

  public static String getKjName(String ysCode, String lhOrZb) {
    RecordSet rs = new RecordSet();
    String tableName = ZB_KJB;
    if ("1".equals(lhOrZb)) {
      tableName = LH_KJB;
    }
    rs.executeQuery("SELECT HJKMMC FROM " + tableName + " WHERE HJKMBM = ?", ysCode);
    if (rs.next()) {
      return Util.null2String(rs.getString("HJKMMC"));
    } else {
      return "";
    }
  }

}
