package com.engine.htsc.subpayment.service.impl;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.core.impl.Service;
import com.engine.htsc.branchpayment.enums.OperateMsg;
import com.engine.htsc.branchpayment.pojo.UfCash;
import com.engine.htsc.branchpayment.service.impl.BranchBudgetCommandFactory;
import com.engine.htsc.branchpayment.service.impl.BranchCostDTOFactory;
import com.engine.htsc.branchpayment.utils.BranchBizUtil;
import com.engine.htsc.payment.pojo.CostAccountDto;
import com.engine.htsc.payment.service.BudgetCommand;
import com.engine.htsc.payment.util.BizUtils;
import com.engine.htsc.payment.util.PayUtil;
import com.engine.htsc.subpayment.service.SubPaymentService;
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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class SubPaymentServiceImpl extends Service implements SubPaymentService {

  @Override
  public Map<String, Object> queryOverBudget(Map<String, Object> params) throws Exception {
    Map<String, Object> apidatas = new HashMap<>();
    RecordSet rs = new RecordSet();
    HTUtil ht = new HTUtil();
    rs.writeLog("====进入GetBudgetCmd");
    rs.writeLog("====入参@" + JSON.toJSONString(params));
    String deptCode = Util.null2String(params.get("deptid")); //资金是直接传的部门code
    String Bgitem = Util.null2String(params.get("Bgitem")); //预算编码
    String BgPeriod = Util.null2String(params.get("BgPeriod")); //日期
    DepartmentComInfo dc = new DepartmentComInfo();
    Map<String,Object> param = new HashMap<>();
    param.put("deptNum", deptCode);
    param.put("deptType", getDeptTypeCode(deptCode));
    param.put("Bgitem", Bgitem);
    param.put("BgPeriod", BgPeriod.split(" ")[0]);
    rs.writeLog("====getBudget入参@" + JSON.toJSONString(param));
    String datas = ht.getBudget(param);
    rs.writeLog("====getBudget返回值@" + datas);
    apidatas.put("datas", datas);
    return apidatas;
  }

  @Override
  public String queryReiPlace(String ngr) throws Exception {
    RecordSet rs = new RecordSet();
    String sql = "select FIELD0 from cus_fielddata where id=? and scope = 'HrmCustomFieldByInfoType' and scopeid = '1'";
    rs.executeQuery(sql, ngr);
    String bxd = "";
    if (rs.next()) {
      bxd = Util.null2String(rs.getString("FIELD0"));
    }
    if (bxd.equals("")) {
      throw new Exception(String.format("拟稿人(%s), 没有报销地", ngr));
    }
    if (bxd.equals("深圳市")) {
      return "0";
    }
    if (bxd.equals("上海市")) {
      return "1";
    }
    if (bxd.equals("北京市")) {
      return "2";
    }
    if (bxd.equals("南京市")) {
      return "3";
    } else {
      throw new Exception(String.format("拟稿人(%s), 报销地(%s), 没有对应code", ngr, bxd));
    }
  }

  @Override
  public Map<String, String> queryBankInfoByUid(String uid) throws Exception {
    ResourceComInfo rc = new ResourceComInfo();
    RecordSet rs = new RecordSet();
    String workCode = rc.getWorkcode(uid);
    Assert.notBlank(workCode, "没有对应工号");

    Map<String, String> res = new HashMap<>();
    String sql = "select a.YXKH,a.SS,a.khx,b.YXMC,a.MODEDATACREATEDATE||' '||a.MODEDATACREATETIME as dates from uf_lhclyxxx a join uf_khh b on a.khx = b.lxh where KHR=? order by DATES desc";
    rs.executeQuery(sql, workCode);
    String bankCard = "";
    String bankName = "";
    String ss = "";
    String bankId = "";
    if (rs.next()) {
      rs.writeLog(String.format("queryBankInfoByWorkCode KHR:%s;", workCode));
      bankCard = Util.null2String(rs.getString("YXKH"));
      bankName = Util.null2String(rs.getString("YXMC"));
      ss = Util.null2String(rs.getString("SS"));
      bankId = Util.null2String(rs.getString("khx"));
    }
    res.put("bankCard", bankCard);
    res.put("bankName", bankName);
    res.put("ss", ss);
    res.put("bankID", bankId);
    return res;
  }

  @Override
  public Map<String, String> doPaymentByBatchId(String ids) throws Exception {
    Assert.notBlank(ids, "同步预算数据id为空");

    RecordSet rs = new RecordSet();
    rs.writeLog(String.format("同步付款数据， ids: %s", ids));

    BranchBizUtil biz = new BranchBizUtil();
    HTUtil ht = new HTUtil();
    List<UfCash> ufCashList = biz.getUfCashList(ids, BranchBizUtil.ZGS);

    Map<String, String> resp = new HashMap<>();
    for (UfCash cash : ufCashList) {
      if ("2".equals(cash.getFkzt())) {
        resp.put(cash.getrMark(), "流程已废弃,无法付款");
        continue;
      }
      //预算
      BudgetCommand command = BranchBudgetCommandFactory.getBudgetCommand4Sub(cash.getType());
      try {
        String finish = Objects.requireNonNull(command).finish(cash.getRid());
        resp.put(cash.getrMark(), OperateMsg.BUDGET_SUCCESS.getMsg("返回值：" + finish));
        //更新预算状态
        if ("F1001".equalsIgnoreCase(finish)) {
          biz.updateBudgetStatus(cash.getId(), "1", BranchBizUtil.ZGS);
        }
      } catch (Exception e) {
        rs.writeLog(e);
        resp.put(cash.getrMark(), String.join(",",
                OperateMsg.BUDGET_FAIL.getMsg("异常消息：" + e.getMessage()),
                OperateMsg.PAY_FAIL.getMsg()));
        throw new Exception("预算执行失败，抛出异常：" + e.getMessage());
      }

      //核算
      try {
        CostAccountDto costAccountDto = BranchCostDTOFactory.getCostDTOByType4Sub(cash.getRid(), cash.getType());
        String costAccountDtoJsonStr = JSON.toJSONString(costAccountDto);
        @SuppressWarnings("unchecked")
        Map<String, Object> costDtoMap = JSONObject.parseObject(costAccountDtoJsonStr);
        rs.writeLog(String.format("核算入参，%s", costDtoMap));
        String response = ht.saveFydj(costDtoMap);
        if ("success".equalsIgnoreCase(response)) {
          resp.put(cash.getrMark(), OperateMsg.PAY_SUCCESS.getMsg());
          //更新核算状态
          biz.updateCostStatus(cash.getId(), cash.getRid(), BranchBizUtil.ZGS);
          //更新合同信息
          PayUtil.updatePaymentInfoToHuaTai(cash.getRid());
        } else {
          resp.put(cash.getrMark(), String.join(",", OperateMsg.BUDGET_SUCCESS.getMsg(),
                  OperateMsg.ACCOUNTING_FAIL.getMsg("返回值：" + response),
                  OperateMsg.PAY_FAIL.getMsg()));
        }
      } catch (Exception e) {
        rs.writeLog(e);
        resp.put(cash.getrMark(), String.join(",", OperateMsg.BUDGET_SUCCESS.getMsg(),
                OperateMsg.ACCOUNTING_FAIL.getMsg("异常消息：" + e.getMessage()),
                OperateMsg.PAY_FAIL.getMsg()));
      }

    }

    return resp;
  }

  @Override
  public Map<String, String> doBudgetByBatchId(String ids, String isDiscard) throws Exception {
    Assert.notBlank(ids, "同步预算数据id为空");
    Assert.notBlank(isDiscard, "同步预算状态为空");

    RecordSet rs = new RecordSet();
    rs.writeLog(String.format("同步预算数据，ids: %s; discard:%s, (-1为废弃)", ids, isDiscard));

    BranchBizUtil biz = new BranchBizUtil();
    List<UfCash> ufCashList = biz.getUfCashList(ids, BranchBizUtil.ZGS);

    Map<String, String> resp = new HashMap<>();
    for (UfCash uf : ufCashList) {
      if ("2".equals(uf.getFkzt())) {
        resp.put(uf.getrMark(), "流程已废弃,无法付款");
        continue;
      }
      BudgetCommand command = BranchBudgetCommandFactory.getBudgetCommand4Sub(uf.getType());
      try {
        String finish = "";
        if ("1".equals(isDiscard)) {
          finish = Objects.requireNonNull(command).finish(uf.getRid());
          resp.put(uf.getrMark(), OperateMsg.BUDGET_SUCCESS.getMsg("返回值：" + finish));
        } else if ("-1".equals(isDiscard)) {
          finish = Objects.requireNonNull(command).reject(uf.getRid());
          resp.put(uf.getrMark(), OperateMsg.BUDGET_CANCEL_SUCCESS.getMsg("返回值：" + finish));
          //废弃后更新发票关联关系: uf_pjxxgl 浪潮
          BizUtils bizUtils = new BizUtils();
          bizUtils.cancelInvLink(uf.getRid());
        }
        //更新预算状态
        if ("F1001".equalsIgnoreCase(finish)) {
          biz.updateBudgetStatus(uf.getId(), isDiscard, BranchBizUtil.ZGS);
        }
      } catch (Exception e) {
        rs.writeLog(e);
        resp.put(uf.getrMark(), OperateMsg.BUDGET_FAIL.getMsg("异常消息：" + e.getMessage()));
      }

    }
    return resp;
  }

  @Override
  public Map<String, String> doAccountByBatchId(String ids) throws Exception {
    Assert.notBlank(ids, "同步核算id为空");

    RecordSet rs = new RecordSet();
    HTUtil ht = new HTUtil();
    rs.writeLog(String.format("同步核算数据ids：%s", ids));

    BranchBizUtil biz = new BranchBizUtil();
    List<UfCash> ufCashList = biz.getUfCashList(ids, BranchBizUtil.ZGS);

    Map<String, String> resp = new HashMap<>();
    for (UfCash uf : ufCashList) {
      if ("2".equals(uf.getFkzt())) {
        resp.put(uf.getrMark(), "流程已废弃,无法付款");
        continue;
      }
      try {
        CostAccountDto costAccountDto = BranchCostDTOFactory.getCostDTOByType4Sub(uf.getRid(), uf.getType());
        String costAccountDtoJsonStr = JSON.toJSONString(costAccountDto);
        @SuppressWarnings("unchecked")
        Map<String, Object> costDtoMap = JSONObject.parseObject(costAccountDtoJsonStr);
        rs.writeLog(String.format("核算入参，%s", costDtoMap));
        String response = ht.saveFydj(costDtoMap);
        if ("success".equalsIgnoreCase(response)) {
          resp.put(uf.getrMark(), OperateMsg.ACCOUNTING_SUCCESS.getMsg());
          //更新核算状态
          biz.updateCostStatus(uf.getId(), uf.getRid(), BranchBizUtil.ZGS);
          //更新合同信息
          PayUtil.updatePaymentInfoToHuaTai(uf.getRid());
        } else {
          resp.put(uf.getrMark(), OperateMsg.ACCOUNTING_FAIL.getMsg("返回值：" + response));
        }
      } catch (Exception e) {
        rs.writeLog(e);
        resp.put(uf.getrMark(), OperateMsg.ACCOUNTING_FAIL.getMsg("异常消息：" + e.getMessage()));
      }
    }
    return resp;
  }

  @Override
  public String updateManualPaymentStatus(String rids) {
    BranchBizUtil bizUtil = new BranchBizUtil();
    return bizUtil.updateManualPaymentStatus(rids, BranchBizUtil.ZGS);
  }

  private String getDeptTypeCode(String deptCode) {
    String code = "";
    String sql = "SELECT FBBH FROM UF_ZJBMB uz WHERE BMBH = ?";
    RecordSet rs = new RecordSet();
    rs.executeQuery(sql, deptCode);
    if (rs.next()) {
      code = rs.getString("FBBH");
    }
    return code;
  }

}
