package com.hfkj.channel.saas;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.channel.saas.config.SaasConfig;
import com.hfkj.channel.saas.utils.GenerateAgreementUtil;
import com.hfkj.channel.saas.utils.RSAUtil;
import com.hfkj.channel.saas.utils.SaasCommon;
import com.hfkj.channel.saas.utils.SaasMerRequest;
import com.hfkj.common.exception.BaseException;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.HttpsUtils;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.*;
import com.hfkj.model.MerBasisModel;
import com.hfkj.service.*;
import com.hfkj.sysenum.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;

/**
 * 公共
 * @className: SasaCommon
 * @author: HuRui
 * @date: 2023/4/4
 **/
@Component
public class SaasMerService {

    @Resource
    private BsMerContractRecordService merContractRecordService;

    @Resource
    private BsMerContractRecordMsgService merContractRecordMsgService;

    @Resource
    private BsMerService merService;

    @Resource
    private BsStoreService storeService;

    @Resource
    private BsIndustryService industryService;

    @Resource
    private BsMerRateService merRateService;
    @Resource
    private BsMerRateApplyService merRateApplyService;
    @Resource
    private BsMerSettleAcctApplyService merSettleAcctApplyService;

    @Resource
    private BsMerPlatformNoService merPlatformNoService;

    @Resource
    private BsPlatformService platformService;

    @Resource
    private BsMerAttachService merAttachService;

    @Resource
    private CommonService commonService;

    @Resource
    private SaasCommon saasCommon;

    @Resource
    private SaasMerRequest saasMerRequest;

    /**
     * 商户进件
     * @param merId
     * @throws Exception
     */
    public void addMer(Long merId) {
        String resStr = "";
        String reqStr = "";
        BsMerPlatformNo platform = null;

        // 增加进件记录
        BsMerContractRecord record = new BsMerContractRecord();
        record.setMerId(merId);
        record.setPlatformType(PlatformTypeEnum.type1.getNumber());
        record.setOrderNo(System.currentTimeMillis()+"");
        record.setStatus(1);
        merContractRecordService.insertRecord(record);

        MerBasisModel basisModel = merService.getMerDetail(merId);
        try {
            platform = merPlatformNoService.getPlatformNo(merId, PlatformTypeEnum.type1, null);
            if (platform != null) {
                platform.setStatus(MerPlatformNoStatusEnum.status0.getNumber());
                merPlatformNoService.editMerPlatformNo(platform);
            }
            BsPlatform currentPlatform = platformService.getCurrentPlatform();
            platform = new BsMerPlatformNo();
            platform.setCompanyId(basisModel.getCompanyId());
            platform.setAgentId(basisModel.getAgentId());
            platform.setMerId(basisModel.getId());
            platform.setMerNo(basisModel.getMerNo());
            platform.setPlatformType(PlatformTypeEnum.type1.getNumber());
            platform.setStatus(MerPlatformNoStatusEnum.status2.getNumber());
            platform.setCurrentPlatform(currentPlatform.getPlatformType().equals(PlatformTypeEnum.type1.getNumber()));
            merPlatformNoService.editMerPlatformNo(platform);

            SecRegion province = commonService.getRegionsById(basisModel.getMerRegion().getProvinceCode());
            if (province == null || StringUtils.isBlank(province.getSaasCode())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户地址未配置正确，请联系客服！");
            }
            SecRegion city = commonService.getRegionsById(basisModel.getMerRegion().getCityCode());
            if (city == null || StringUtils.isBlank(city.getSaasCode())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户地址未配置正确，请联系客服！");
            }
            SecRegion area = commonService.getRegionsById(basisModel.getMerRegion().getAreaCode());
            if (area == null || StringUtils.isBlank(area.getSaasCode())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户地址未配置正确，请联系客服！");
            }
            // 经营内容
            BsIndustry industry = industryService.getDetailById(basisModel.getMerIndustry().getChildId());
            if (industry == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到经营范围");
            }
            Map<String,Object> body = new HashMap<>();
            body.put("userNo",basisModel.getOrgNo());
            body.put("email", basisModel.getRegEmail());
            body.put("busiCode", "WECHAT_PAY");
            body.put("merRegName", basisModel.getMerName());
            body.put("merType", basisModel.getMerType().equals(MerTypeEnum.status2.getNumber())?"TP_MERCHANT":"TP_PERSONAL");
            body.put("merName", basisModel.getMerName());
            body.put("merAddr", SaasMerService.dislodge(basisModel.getMerRegion().getAddress()));
            body.put("provinceCode", province.getSaasCode());
            body.put("cityCode", city.getSaasCode());
            body.put("countyCode", area.getSaasCode());
            body.put("licenseName", basisModel.getMerName());

            // 小微商户可不传营业执照信息
            if (!basisModel.getMerType().equals(MerTypeEnum.status3.getNumber())) {
                body.put("licenseNo", basisModel.getBlisNo());
                body.put("licenseDtStart", basisModel.getBlisPeriodStart().replace("年", "-").replace("月", "-").replace("日", ""));
                if (basisModel.getBlisPeriodType().equals(2)) {
                    body.put("licenseDtEnd", "长期有效");
                } else {
                    body.put("licenseDtEnd", basisModel.getBlisPeriodEnd().replace("年", "-").replace("月", "-").replace("日", ""));
                }
            }

            // 法人信息
            body.put("larName", basisModel.getLarName());
            body.put("larIdType", "01");
            body.put("larIdCard", basisModel.getLarIdCard());
            body.put("larIdCardStart", basisModel.getLarIdCardPeriodStart().replace(".", "-"));
            if (basisModel.getLarIdCardPeriodType().equals(2)) {
                Calendar larIdCardEnd = Calendar.getInstance();
                larIdCardEnd.set(Calendar.YEAR, 2099);
                larIdCardEnd.set(Calendar.MONTH, 11);
                larIdCardEnd.set(Calendar.DATE , 31);
                body.put("larIdCardEnd", DateUtil.date2String(larIdCardEnd.getTime(), "yyyy-MM-dd"));
            } else {
                body.put("larIdCardEnd", basisModel.getLarIdCardPeriodEnd().replace(".", "-"));
            }
            body.put("contactMobile", basisModel.getRegPhone());
            body.put("contactName", basisModel.getRegName());


             /** --------- 结算信息---------- **/
            SecRegion settleProvince = commonService.getRegionsById(basisModel.getMerSettleAcct().getOpenningBankProvinceCode());
            if (settleProvince == null || StringUtils.isBlank(settleProvince.getSaasCode())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "结算地区未配置正确，请联系客服！");
            }
            SecRegion settleCity = commonService.getRegionsById(basisModel.getMerSettleAcct().getOpenningBankCityCode());
            if (settleCity == null || StringUtils.isBlank(settleCity.getSaasCode())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "结算地区未配置正确，请联系客服！");
            }
            body.put("openningBankCode", basisModel.getMerSettleAcct().getOpenningBankCode());
            body.put("openningBankName", basisModel.getMerSettleAcct().getOpenningBankName());
            body.put("clearingBankCode", basisModel.getMerSettleAcct().getClearingBankCode());
            body.put("settleProvinceCode", settleProvince.getSaasCode());
            body.put("settleProvinceName", basisModel.getMerSettleAcct().getOpenningBankProvinceName());
            body.put("settleCityCode", settleCity.getSaasCode());
            body.put("settleCityName", basisModel.getMerSettleAcct().getOpenningBankCityName());
            body.put("accountNo", basisModel.getMerSettleAcct().getBankCardNo());
            body.put("accountName", basisModel.getMerSettleAcct().getBankName());

            if (basisModel.getMerSettleAcct().getSettleType().equals(MerSettleType.status1.getNumber())) {
                body.put("accountType", "57");
            } else {
                body.put("accountType", "58");
            }
            body.put("accountIdCard", basisModel.getMerSettleAcct().getSettleIdCardNo());

            // 非法人结算
            if (basisModel.getMerSettleAcct().getSettleType().equals(MerSettleType.status3.getNumber())) {
                body.put("accountIdType", "01");
                body.put("accountName", basisModel.getMerSettleAcct().getSettleIdCardName());
                body.put("accountIdDtStart", basisModel.getMerSettleAcct().getSettleIdCardPeriodStart().replace(".", "-"));
                if (basisModel.getMerSettleAcct().getSettleIdPeriodType().equals(2)) {
                    Calendar accountIdDtEnd = Calendar.getInstance();
                    accountIdDtEnd.set(Calendar.YEAR, 2099);
                    accountIdDtEnd.set(Calendar.MONTH, 11);
                    accountIdDtEnd.set(Calendar.DATE , 31);
                    body.put("accountIdDtEnd", DateUtil.date2String(accountIdDtEnd.getTime(), "yyyy-MM-dd"));
                } else {
                    body.put("accountIdDtEnd", basisModel.getMerSettleAcct().getSettleIdCardPeriodEnd().replace(".", "-"));
                }
            }
            /** --------- 结算信息---------- **/
            Map<String,Object> bizContent = new HashMap<>();
            bizContent.put("termNum", "1");

            Map<String, Object> feesMap;
            List<Map<String,Object>> feesMapList = new ArrayList<>();
            // 商户费率
            List<BsMerRate> rateList = merRateService.getRateListByMerId(merId);
            for (BsMerRate rate : rateList) {
                feesMap = new HashMap<>();
                feesMap.put("feeCode", rate.getRateSaasTypeCode());
                feesMap.put("feeValue", rate.getRatePct());
                if (StringUtils.isNotBlank(rate.getExt1())) {
                    feesMap.put("topFee", rate.getExt1());
                }
                feesMapList.add(feesMap);
            }
            bizContent.put("fees", feesMapList);
            bizContent.put("mcc", basisModel.getMerMccCode());
            bizContent.put("activityId", SaasConfig.activityId);

            Map<String,Object> attchMap;
            List<Map<String,Object>> attchMapList = new ArrayList<>();

            List<BsMerAttach> attachList = merAttachService.getAttachListByMer(merId, PlatformTypeEnum.type0, null);
            for (BsMerAttach attach : attachList) {
                attchMap = new HashMap<>();
                MerAttachType attachType = MerAttachType.getDataByNumber(attach.getType());
                if (attachType == null || StringUtils.isBlank(attachType.getLklSaasCode())) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的附件类型");
                }
                attchMap.put("type", attachType.getLklSaasCode());
                attchMap.put("id", saasCommon.fileUpload(new File(CommonSysConst.getSysConfig().getFile_url() +"/"+ attach.getFileUrl()), attachType.getLklSaasCode(), "0").getString("url"));
                attchMapList.add(attchMap);
            }

            // 协议
            attchMap = new HashMap<>();
            attchMap.put("type", MerAttachType.type11.getLklSaasCode());
            attchMap.put("id", saasCommon.fileUpload(new File(CommonSysConst.getSysConfig().getFile_url() +"/"+ generateAddContract(basisModel)), MerAttachType.type11.getLklSaasCode(), "0").getString("url"));
            attchMapList.add(attchMap);

            body.put("bizContent", bizContent);
            body.put("attchments", attchMapList);
            body.put("businessContent", basisModel.getMerIndustry().getChildName());
            body.put("latitude", "0.0");
            body.put("longtude", "0.0");
            body.put("source", "H5");
            body.put("settleType", "D1");
            body.put("settlementType", "AUTOMATIC");
            saasMerRequest.addMerchant(body);

            Map<String,Object> header = new HashMap<>();
            header.put("Authorization", "bearer " + saasCommon.getToken());

            JSONObject responseBody = HttpsUtils.doPost(SaasConfig.requestMerRegistrationCommonUrl+"merchant", body, header);
            reqStr =  JSONObject.toJSONString(body);
            resStr = responseBody.toJSONString();
            System.out.println("body：" + reqStr);
            System.out.println("response：" + responseBody);
            if (responseBody == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请求进件失败");
            }
            if (StringUtils.isBlank(responseBody.getString("state"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("message"));
            }
            if (!responseBody.getString("state").equals("1")) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请求进件失败");
            }
            platform.setStatus(MerPlatformNoStatusEnum.status2.getNumber());
            platform.setPlatformNo(responseBody.getString("merchantNo"));
            merPlatformNoService.editMerPlatformNo(platform);

            // 增加进件记录消息
            BsMerContractRecordMsg recordMsg = new BsMerContractRecordMsg();
            recordMsg.setOrderNo(record.getOrderNo());
            recordMsg.setType(1);
            recordMsg.setRequestContent(JSONObject.toJSONString(body));
            recordMsg.setResponseCode(responseBody.getString("state"));
            recordMsg.setResponseMsg(null);
            recordMsg.setResponseContent(responseBody.toJSONString());
            merContractRecordMsgService.insertRecordMsg(recordMsg);

        } catch (BaseException baseException) {
            if (basisModel.getMerStatus().intValue() != MerStatusEnum.status4.getNumber().intValue()) {
                basisModel.setMerStatus(MerStatusEnum.status4.getNumber());
                merService.editMer(basisModel);
            }

            platform.setStatus(MerPlatformNoStatusEnum.status3.getNumber());
            platform.setSuggestionReject(baseException.getErrorMsg());
            merPlatformNoService.editMerPlatformNo(platform);

            record.setStatus(3);
            merContractRecordService.updateRecord(record);

            // 增加进件记录消息
            BsMerContractRecordMsg recordMsg = new BsMerContractRecordMsg();
            recordMsg.setOrderNo(record.getOrderNo());
            recordMsg.setType(1);
            recordMsg.setRequestContent(reqStr);
            recordMsg.setResponseCode("REJECT");
            recordMsg.setResponseContent(resStr);
            recordMsg.setResponseMsg(baseException.getErrorMsg());
            merContractRecordMsgService.insertRecordMsg(recordMsg);

        } catch (Exception e) {
            if (basisModel.getMerStatus().intValue() != MerStatusEnum.status4.getNumber().intValue()) {
                basisModel.setMerStatus(MerStatusEnum.status4.getNumber());
                merService.editMer(basisModel);
            }

            platform.setStatus(MerPlatformNoStatusEnum.status3.getNumber());
            platform.setSuggestionReject("进件失败！未知错误");
            merPlatformNoService.editMerPlatformNo(platform);

            record.setStatus(3);
            merContractRecordService.updateRecord(record);

            // 增加进件记录消息
            BsMerContractRecordMsg recordMsg = new BsMerContractRecordMsg();
            recordMsg.setOrderNo(record.getOrderNo());
            recordMsg.setType(1);
            recordMsg.setRequestContent(reqStr);
            recordMsg.setResponseCode("REJECT");
            recordMsg.setResponseContent(resStr);
            recordMsg.setResponseMsg("进件失败！未知错误");
            merContractRecordMsgService.insertRecordMsg(recordMsg);
        }
    }

    /**
     * 修改结算信息
     * @param applyId 申请id
     * @return
     */
    public JSONObject updateSettleApply(Long applyId) {
        // 结算申请
        BsMerSettleAcctApply merSettleAcctApply = merSettleAcctApplyService.getApplyById(applyId);
        if (merSettleAcctApply == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的结算申请");
        }
        // 平台商户
        BsMerPlatformNo merPlatformNo = merPlatformNoService.getPlatformNo(merSettleAcctApply.getMerId(), PlatformTypeEnum.type1);
        if (merPlatformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到平台商户号");
        }

        Map<String,Object> param = new HashMap<>();
        param.put("accountKind", merSettleAcctApply.getSettleType().equals(MerSettleType.status1.getNumber())?"57":"58");
        param.put("accountName", merSettleAcctApply.getSettleIdCardName());
        param.put("accountNo", merSettleAcctApply.getBankCardNo());
        param.put("bankName", merSettleAcctApply.getOpenningBankName());
        param.put("bankNo", merSettleAcctApply.getOpenningBankCode());
        param.put("clearingBankNo", merSettleAcctApply.getClearingBankCode());
        param.put("identityNo", merSettleAcctApply.getSettleIdCardNo());
        param.put("settleCityCode", merSettleAcctApply.getOpenningBankCityCode());
        param.put("settleCityName", merSettleAcctApply.getOpenningBankCityName());
        param.put("settleCountyCode", merSettleAcctApply.getOpenningBankAreaCode());
        param.put("settleCountyName", merSettleAcctApply.getOpenningBankAreaName());
        param.put("settleProvinceCode", merSettleAcctApply.getOpenningBankProvinceCode());
        param.put("settleProvinceName", merSettleAcctApply.getOpenningBankProvinceName());

        List<Map<String, Object>> attachmentsMapList = new ArrayList<>();
        Map<String, Object> attachmentsMap;
        attachmentsMap = new HashMap<>();

        if (StringUtils.isNotBlank(merSettleAcctApply.getBankCardImg())) {
            attachmentsMap.put("imgType", "BANK_CARD");
            attachmentsMap.put("imgPath", saasCommon.fileUpload(new File(CommonSysConst.getSysConfig().getFile_url() +"/"+ merSettleAcctApply.getBankCardImg()), "BANK_CARD", "0").getString("url"));
            attachmentsMapList.add(attachmentsMap);
        } else if (StringUtils.isNotBlank(merSettleAcctApply.getOpenningBankLicenseUrl())) {
            attachmentsMap = new HashMap<>();
            attachmentsMap.put("imgType", "OPENING_PERMIT");
            attachmentsMap.put("imgPath", saasCommon.fileUpload(new File(CommonSysConst.getSysConfig().getFile_url() +"/"+ merSettleAcctApply.getOpenningBankLicenseUrl()), "OPENING_PERMIT", "0").getString("url"));
            attachmentsMapList.add(attachmentsMap);
        }

        if (StringUtils.isNotBlank(merSettleAcctApply.getCommissionImg())) {
            attachmentsMap = new HashMap<>();
            attachmentsMap.put("imgType", "OTHERS");
            attachmentsMap.put("imgPath", saasCommon.fileUpload(new File(CommonSysConst.getSysConfig().getFile_url() +"/"+ merSettleAcctApply.getCommissionImg()), "OTHERS", "0").getString("url"));
            attachmentsMapList.add(attachmentsMap);
        }

        param.put("attachments", attachmentsMapList);

        Map<String,Object> header = new HashMap<>();
        header.put("Authorization", "bearer " + saasCommon.getUpdateToken());

        JSONObject responseObj = HttpsUtils.doPost(SaasConfig.requestMerUrl + "channel/customer/update/settle/" + merPlatformNo.getPlatformNo(), param, header);
        System.out.println("body：" + JSONObject.toJSONString(param));
        System.out.println("response：" + responseObj.toJSONString());
        if (responseObj == null || !responseObj.getString("message").equals("SUCCESS")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseObj.getString("message"));
        }
        merSettleAcctApply.setApplyNo(responseObj.getString("reviewRelatedId"));
        merSettleAcctApplyService.editData(merSettleAcctApply);
        return responseObj;
    }


    /**
     * 进件复议
     * @return
     */
    public JSONObject reconsider(Long merId) throws Exception {
        BsMer mer = merService.getMer(merId);
        if (mer == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户信息");
        }
        if (!mer.getMerStatus().equals(MerStatusEnum.status4.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户状态不处于审核驳回状态，无法复议");
        }
        mer.setCompleteStatus(MerCompleteStatusEnum.status1.getNumber());
        mer.setMerStatus(MerStatusEnum.status3.getNumber());
        merService.editMer(mer);

        List<BsStore> storeList = storeService.getStoreByMerId(merId, StoreCreateTypeEnum.type1);
        storeList.get(0).setAloneSettle(false);
        storeList.get(0).setStatus(StoreStatusEnum.status3.getNumber());
        storeService.editStore(storeList.get(0));

        // 平台
        BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(merId, PlatformTypeEnum.type1);
        if (platformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户未提交过进件");
        }
        String responseObj = reconsiderSubmit(platformNo.getPlatformNo());

        String orderNo = System.currentTimeMillis()+"";
        // 增加进件记录
        BsMerContractRecord record = new BsMerContractRecord();
        record.setMerId(merId);
        record.setPlatformType(PlatformTypeEnum.type1.getNumber());
        record.setOrderNo(orderNo);
        record.setContractId(responseObj);
        record.setStatus(1);
        merContractRecordService.insertRecord(record);

        // 增加进件记录消息
        BsMerContractRecordMsg recordMsg = new BsMerContractRecordMsg();
        recordMsg.setOrderNo(orderNo);
        recordMsg.setType(1);
        recordMsg.setRequestContent(platformNo.getPlatformNo());
        recordMsg.setResponseCode(null);
        recordMsg.setResponseMsg(null);
        recordMsg.setResponseContent(responseObj);
        merContractRecordMsgService.insertRecordMsg(recordMsg);
        return new JSONObject();
    }

    /**
     * 进件复议提交
     * @return
     */
    public String reconsiderSubmit(String customerNo) throws Exception {
        Map<String,Object> param = new HashMap<>();
        param.put("customerNo", customerNo);

        Map<String,Object> header = new HashMap<>();
        header.put("Authorization", "bearer " + saasCommon.getToken());

        JSONObject obj = new JSONObject();
        obj.put("data", Base64.encodeBase64String(RSAUtil.encryptByPrivateKey(JSONObject.toJSONString(param).getBytes(), Base64.decodeBase64(RSAUtil.PRIVATE_KEY))));

        JSONObject responseObj = HttpsUtils.doPost(SaasConfig.requestMerUrl + "open/merchant/reconsider/submit", obj, header);
        System.out.println("请求地址：" + SaasConfig.requestMerUrl + "open/merchant/reconsider/submit");
        System.out.println("body：" + JSONObject.toJSONString(param));
        System.out.println("response：" + responseObj.toJSONString());
        if (responseObj == null || !responseObj.getString("code").equals("000000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseObj.getString("message"));
        }
        return new String(RSAUtil.decryptByPublicKey(Base64.decodeBase64(responseObj.getString("data")), Base64.decodeBase64(RSAUtil.PUBLIC_KEY)));

    }

    /**
     * 修改费率
     * @param merRateApplyId 申请id
     * @return
     */
    public JSONObject updateFeeApply(Long merRateApplyId) {
        // 修改费率申请
        BsMerRateApply rateApply = merRateApplyService.getRateApplyById(merRateApplyId);
        if (rateApply == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未知的申请");
        }
        // 平台商户
        BsMerPlatformNo merPlatformNo = merPlatformNoService.getPlatformNo(rateApply.getMerId(), PlatformTypeEnum.type1);
        if (merPlatformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到平台商户号");
        }
        Map<String,Object> param = new HashMap<>();
        param.put("productCode", "PAPER_CODE");
        param.put("settlementType", "AUTOMATIC");
        // 商户费率
        List<Map<String, Object>> feesMapList = new ArrayList<>();
        Map<String, Object> feesMap;
        List<BsMerRateApplyDetail> rateList = merRateApplyService.getRateApplyDetailListByApply(rateApply.getId());
        for (BsMerRateApplyDetail rate : rateList) {
            feesMap = new HashMap<>();
            feesMap.put("fee", rate.getRatePct());
            feesMap.put("feeType", rate.getRateSaasTypeCode());
            if (StringUtils.isNotBlank(rate.getExt1())) {
                feesMap.put("topFee", rate.getExt1());
            }
            feesMapList.add(feesMap);
        }
        param.put("fees", feesMapList);

        Map<String,Object> header = new HashMap<>();
        header.put("Authorization", "bearer " + saasCommon.getUpdateToken());

        JSONObject responseObj = HttpsUtils.doPost(SaasConfig.requestMerUrl + "channel/customer/update/fee/" + merPlatformNo.getPlatformNo(), param, header);
        System.out.println("商户号：" + merPlatformNo.getPlatformNo() + "      " + merPlatformNo.getCupNo());
        System.out.println("body：" + JSONObject.toJSONString(param));
        System.out.println("response：" + responseObj.toJSONString());
        if (responseObj == null || !responseObj.getString("message").equals("SUCCESS")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseObj.getString("message"));
        }
        rateApply.setApplyNo(responseObj.getString("reviewRelatedId"));
        merRateApplyService.editData(rateApply);
        return responseObj;
    }

    /**
     * 修改费率
     * @param merId 申请id
     * @return
     */
    public JSONObject updateFee(Long merId) {
        // 平台商户
        BsMerPlatformNo merPlatformNo = merPlatformNoService.getPlatformNo(merId, PlatformTypeEnum.type1);
        if (merPlatformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到平台商户号");
        }
        Map<String,Object> param = new HashMap<>();
        param.put("productCode", "PAPER_CODE");
        param.put("settlementType", "AUTOMATIC");
        // 商户费率
        List<Map<String, Object>> feesMapList = new ArrayList<>();
        Map<String, Object> feesMap;
        List<BsMerRate> rateList = merRateService.getRateListByMerId(merId);
        for (BsMerRate rate : rateList) {
            feesMap = new HashMap<>();
            feesMap.put("fee", rate.getRatePct());
            feesMap.put("feeType", rate.getRateSaasTypeCode());
            if (StringUtils.isNotBlank(rate.getExt1())) {
                feesMap.put("topFee", rate.getExt1());
            }
            feesMapList.add(feesMap);
        }
        param.put("fees", feesMapList);

        Map<String,Object> header = new HashMap<>();
        header.put("Authorization", "bearer " + saasCommon.getUpdateToken());

        JSONObject responseObj = HttpsUtils.doPost(SaasConfig.requestMerUrl + "channel/customer/update/fee/" + merPlatformNo.getPlatformNo(), param, header);
        System.out.println("商户号：" + merPlatformNo.getPlatformNo() + "      " + merPlatformNo.getCupNo());
        System.out.println("body：" + JSONObject.toJSONString(param));
        System.out.println("response：" + responseObj.toJSONString());
        if (responseObj == null || !responseObj.getString("message").equals("SUCCESS")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseObj.getString("message"));
        }
        merPlatformNo.setExt1(responseObj.getString("reviewRelatedId"));
        merPlatformNoService.editMerPlatformNo(merPlatformNo);
        return responseObj;
    }

    /**
     * 查询费率
     * @param merId 申请id
     * @return
     */
    public JSONObject queryFee(Long merId) {
        // 平台商户
        BsMerPlatformNo merPlatformNo = merPlatformNoService.getPlatformNo(merId, PlatformTypeEnum.type1);
        if (merPlatformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到平台商户号");
        }
        Map<String,Object> param = new HashMap<>();
        param.put("productCode", "WECHAT_PAY");

        Map<String,Object> header = new HashMap<>();
        header.put("Authorization", "bearer " + saasCommon.getUpdateToken());

        String doSaasGet = HttpsUtils.doSaasGet(SaasConfig.requestMerUrl + "channel/customer/update/fee/" + merPlatformNo.getPlatformNo(), param, header, true);
        JSONObject responseObj = JSONObject.parseObject(doSaasGet);
        System.out.println("商户号：" + merPlatformNo.getPlatformNo() + "      " + merPlatformNo.getCupNo());
        System.out.println("body：" + JSONObject.toJSONString(param));
        System.out.println("response：" + responseObj.toJSONString());
        if (responseObj == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseObj.getString("message"));
        }
        return responseObj;
    }

    /**
     * 查询修改审核
     * @param reviewRelatedId  回执id
     * @return
     */
    public JSONObject updateReview(String reviewRelatedId) {
        try {
            Map<String,Object> param = new HashMap<>();
            param.put("reviewRelatedId", reviewRelatedId);

            Map<String,Object> header = new HashMap<>();
            header.put("Authorization", "bearer " + saasCommon.getUpdateToken());

            String result = HttpsUtils.doSaasGet(SaasConfig.requestMerUpdateUrl+"customer/update/review", param, header, true);
            return JSONObject.parseObject(result);

        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
    }

    /**
     * 查询商户结算
     * @param customerNo
     * @return
     */
    public JSONObject getMerSettle(String customerNo) {
        try {
            Map<String,Object> param = new HashMap<>();
            param.put("customerNo", customerNo);

            Map<String,Object> header = new HashMap<>();
            header.put("Authorization", "bearer " + saasCommon.getUpdateToken());
            String result = HttpsUtils.doSaasGet(SaasConfig.requestMerUrl+"channel/customer/update/settle", param, header, false);
            return JSONObject.parseObject(result);

        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
    }

    /**
     * 查询银行地区编码
     * @param customerNo
     * @return
     */
    public JSONObject merchantInfo(String customerNo) {
        try {
            Map<String,Object> param = new HashMap<>();
            param.put("customerNo", customerNo);

            Map<String,Object> header = new HashMap<>();
            header.put("Authorization", "bearer " + saasCommon.getToken());

            JSONObject obj = new JSONObject();
            obj.put("data", Base64.encodeBase64String(RSAUtil.encryptByPrivateKey(JSONObject.toJSONString(param).getBytes(), Base64.decodeBase64(RSAUtil.PRIVATE_KEY))));

            JSONObject responseObj = HttpsUtils.doPost(SaasConfig.requestMerUrl + "open/merchant/info", obj, header);
            System.out.println(responseObj.toJSONString());
            if (responseObj == null || !responseObj.getString("code").equals("000000")) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseObj.getString("message"));
            }
            return JSONObject.parseObject(new String(RSAUtil.decryptByPublicKey(Base64.decodeBase64(responseObj.getString("data")), Base64.decodeBase64(RSAUtil.PUBLIC_KEY))));

        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
    }

    /**
     * 地址去除省、市
     * @param str
     * @return
     */
    public static String dislodge(String str) {
        char[] chars = str.toCharArray();
// oP: '省' 的偏移, oC: '市' 的偏移, oR: "自治区" 的偏移
        int oP = -1, oC = -1, oR = -1;
        char ch;
        for (int i = 0; i < chars.length; i++) {
            ch = chars[i];
            // 一般来说 '省' 的位置会比 '市' 早出现
            if (ch == '省') {
                oP = i;
            } else if (ch == '市') {
                oC = i;
                // 找到 '市' 后就可以跳出循环了
                break;
            } else if (ch == '自'
                    && i + 2 < chars.length
                    && chars[i + 1] == '治'
                    && chars[i + 2] == '区') {
                // "自治区" 出现的几率挺小
                oR = i + 2;
            }
        }

        if (oC != -1) {
            str = str.substring(oC + 1);
        } else if (oP != -1) {
            str = str.substring(oP + 1);
        } else if (oR != -1) {
            str = str.substring(oR + 1);
        }

        return str;
    }

    /**
     * 生成进件协议
     * @param merDetail
     * @return
     */
    public static String generateAddContract(MerBasisModel merDetail) {
        try {
            Configuration cfg = new Configuration();
            cfg.setDirectoryForTemplateLoading(new File(CommonSysConst.getSysConfig().getFile_url(), "template"));
            Template template = cfg.getTemplate("indexHTKWECHAT_PAY.html");

            Map<String,Object> param = new HashMap<>();
            param.put("width", "100%");
            param.put("tbTitleWidth", "120px");
            param.put("tbConWidth", "100px");

            Map<String,Object> fee = new HashMap<>();
            fee.put("customerName", merDetail.getBlisName());
            param.put("fee", fee);

            // 执照信息
            if (merDetail.getMerType().equals(MerTypeEnum.status3.getNumber())) {
                param.put("licenseNo", "");
                param.put("legalName", "");
                param.put("licenseName", "");
                param.put("identityNo", "");
                param.put("address", "") ;
                param.put("identityNoExpire", "");
                param.put("receiveDetail", "");

            } else {
                param.put("licenseNo", merDetail.getBlisNo());
                param.put("legalName", merDetail.getLarName());
                param.put("licenseName", merDetail.getBlisName());
                param.put("identityNo", merDetail.getLarIdCard());
                param.put("address", merDetail.getMerRegion().getProvinceName()+merDetail.getMerRegion().getCityName()+merDetail.getMerRegion().getAreaName()) ;
                param.put("identityNoExpire", merDetail.getLarIdCardPeriodStart() + " —— " + merDetail.getLarIdCardPeriodEnd());
                param.put("receiveDetail", merDetail.getMerRegion().getAddress());
            }

            // 结算信息
            param.put("accountName", merDetail.getMerSettleAcct().getBankName());
            param.put("accountIdCard", merDetail.getMerSettleAcct().getSettleIdCardNo());
            param.put("accountNo", merDetail.getMerSettleAcct().getBankCardNo());
            param.put("accountIdDtEnd", merDetail.getMerSettleAcct().getSettleIdCardPeriodStart() + " —— " + merDetail.getMerSettleAcct().getSettleIdCardPeriodEnd());
            param.put("bankName", merDetail.getMerSettleAcct().getOpenningBankName());

            // 商户信息
            param.put("licenseName", merDetail.getBlisName());
            param.put("mail", merDetail.getRegEmail());
            param.put("contactManName", merDetail.getRegName());
            param.put("phone", merDetail.getRegPhone());
            param.put("channelType", merDetail.getMerIndustry().getChildName());
            param.put("receiveDetail", merDetail.getStoreModel().getStoreRegion().getAddress());
            param.put("agencyName", "重庆惠付科技有限公司");

            return GenerateAgreementUtil.createAgreementPicture(merDetail.getId(),GenerateAgreementUtil.writeHtml(merDetail.getId(),template, param));

        } catch (Exception e) {
            return null;
        }
    }
}
