package com.jeequan.jeepay.thirdparty.channel.lklspay;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.applyment.LklspayApplymentInfo;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.model.params.lklspay.LklspayIsvParams;
import com.jeequan.jeepay.core.model.rqrs.mch.ChannelMchRq;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.rqrs.settle.ChannelSettleRq;
import com.jeequan.jeepay.db.entity.BankBranchLkl;
import com.jeequan.jeepay.db.entity.SettleInfo;
import com.jeequan.jeepay.service.mapper.BankBranchLklMapper;
import com.jeequan.jeepay.thirdparty.channel.AbstractMchApiService;
import com.jeequan.jeepay.thirdparty.channel.lklpay.utils.LklpayConst;
import com.jeequan.jeepay.thirdparty.channel.lklspay.model.LklMercInfoConn;
import com.jeequan.jeepay.thirdparty.channel.lklspay.model.LklPayMethod;
import com.jeequan.jeepay.thirdparty.channel.lklspay.model.LklTkReqMethod;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * TODO
 *
 * @author crystal
 * @date 2023/12/4 10:47
 */
@Service
@Slf4j
public class LklspayMchApiService extends AbstractMchApiService<LklspayIsvParams> {

    @Autowired
    private ConfigContextQueryService configContextQueryService;

    @Autowired
    private Configuration configuration;

    @Autowired
    private BankBranchLklMapper bankBranchLklMapper;

    @Override
    public String getIfCode() {
        return CS.IF_CODE.LKLSPAY;
    }

    private String getEndDate(String endDate) {
        if ("长期".equals(endDate)) {
            return "2099-12-31";
        }

        return endDate;
    }

    private LklMercInfoConn getLklData(LklspayApplymentInfo applymentInfo, LklspayIsvParams isvParams) {
        LklMercInfoConn mercInfo = new LklMercInfoConn();
        mercInfo.setUserNo(Long.parseLong(isvParams.getUserNo()));
        mercInfo.setEmail("18062761507@163.com");
        mercInfo.setBusiCode(LklpayConst.BIZ_CODE_SCAN);

        if (com.jeequan.jeepay.core.entity.MchApplyment.MERCHANT_TYPE_PERSONAL == applymentInfo.getMerchantType()) {
            mercInfo.setMerType("TP_PERSONAL");
            mercInfo.setMerRegName(applymentInfo.getMchFullName());
        } else {
            mercInfo.setMerType("TP_MERCHANT");
            mercInfo.setMerRegName(applymentInfo.getMchFullName());
        }

        mercInfo.setMerName(applymentInfo.getMchShortName());
        mercInfo.setMerAddr(applymentInfo.getAddress());

        mercInfo.setProvinceCode(applymentInfo.getMchAreaCode().getString(0));
        mercInfo.setCityCode(applymentInfo.getMchAreaCode().getString(1));
        mercInfo.setCountyCode(applymentInfo.getMchAreaCode().getString(2));

        if (1 != applymentInfo.getMerchantType()) {
            // 非小微商户提交营业执照信息
            mercInfo.setLicenseName(applymentInfo.getMchFullName());
            mercInfo.setLicenseNo(applymentInfo.getLicenseNo());
            mercInfo.setLicenseDtStart(applymentInfo.getLicenseEffectBegin());
            mercInfo.setLicenseDtEnd(getEndDate(applymentInfo.getLicenseEffectEnd()));
        }
        // 接口的经纬度字段是反的
        mercInfo.setLatitude(applymentInfo.getLatitude());
        mercInfo.setLongtude(applymentInfo.getLongtude());
        mercInfo.setSource("APP");

        Assert.notNull(applymentInfo.getMccCode(), "缺少mcc编码信息");
        String[] mccInfo = applymentInfo.getMccCode().split("_");
        if (mccInfo.length != 2) {
            throw new BizException("mcc数据异常");
        }
        mercInfo.setBusinessContent(mccInfo[0]);
        mercInfo.setLarName(applymentInfo.getIdcardName());
        mercInfo.setLarIdType("01");
        mercInfo.setLarIdCard(applymentInfo.getIdcardNo());
        mercInfo.setLarIdCardStart(applymentInfo.getIdcardEffectBegin());
        mercInfo.setLarIdCardEnd(getEndDate(applymentInfo.getIdcardEffectEnd()));
        mercInfo.setContactMobile(applymentInfo.getContactPhone());
        mercInfo.setContactName(applymentInfo.getContactName());

        BankBranchLkl bankCodeLkl = bankBranchLklMapper.selectByContactLine(applymentInfo.getOpenningBankCode());
        Assert.notNull(bankCodeLkl, "未获取到支行信息，请重新选择支行信息");

        mercInfo.setOpenningBankCode(bankCodeLkl.getContactLine());
        mercInfo.setOpenningBankName(bankCodeLkl.getBranchName());
        mercInfo.setClearingBankCode(bankCodeLkl.getClearNo());

        Assert.notNull(applymentInfo.getSettAccountBankBranchAreaCode(), "缺少支行地区编码信息");
        Assert.notNull(applymentInfo.getSettAccountBankBranchAreaName(), "缺少支行地区信息");
        mercInfo.setSettleProvinceCode(applymentInfo.getSettAccountBankBranchAreaCode().getString(0));
        mercInfo.setSettleProvinceName(applymentInfo.getSettAccountBankBranchAreaName().getString(0));
        mercInfo.setSettleCityCode(applymentInfo.getSettAccountBankBranchAreaCode().getString(1));
        mercInfo.setSettleCityName(applymentInfo.getSettAccountBankBranchAreaName().getString(1));
        mercInfo.setAccountNo(applymentInfo.getSettAccountNo());
        mercInfo.setAccountName(applymentInfo.getSettAccountName());
        mercInfo.setAccountType(applymentInfo.getSettAccType());
        mercInfo.setAccountIdType("01");
        mercInfo.setAccountIdCard(applymentInfo.getSettAccountIdcardNo());
        mercInfo.setAccountIdDtStart(applymentInfo.getSettAccountIdcardEffectBegin());
        mercInfo.setAccountIdDtEnd(getEndDate(applymentInfo.getSettAccountIdcardEffectEnd()));

        mercInfo.setBizContent(getFeeInfo(applymentInfo, isvParams));
        mercInfo.setSettleType(applymentInfo.getSettleType());
        mercInfo.setSettlementType("AUTOMATIC");

        return mercInfo;
    }

    public static String convertRate(BigDecimal rate) {
        return rate == null ? null : String.valueOf(rate.multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP));
    }

    private LklMercInfoConn.BizContent getFeeInfo(LklspayApplymentInfo applymentInfo, LklspayIsvParams isvParams) {
        Map<String, LklMercInfoConn.Fee> map = new HashMap<>();

        List<PaywayFee> paywayFeeList = applymentInfo.getPaywayFeeList();

        for (PaywayFee paywayFee : paywayFeeList) {
            boolean isYsfLevelFee = (paywayFee.getWayCode().startsWith("YSF_") || paywayFee.getWayCode().startsWith("UP_"))
                    && PaywayFee.FEE_TYPE_LEVEL.equals(paywayFee.getFeeType())
                    && CollUtil.isNotEmpty(paywayFee.getLevelList());
            if (isYsfLevelFee) {
                // 借记卡费率
                PaywayFee paywayFeeDebitCard = paywayFee.getLevelList().get(0);
                map.put("YSF_DISCOUNT_DEBIT_FEE", new LklMercInfoConn.Fee("YSF_DISCOUNT_DEBIT_FEE", convertRate(paywayFeeDebitCard.getFeeRate()), null));

                PaywayFee paywayFee2DebitCard = paywayFee.getLevelList().get(1);
                double topFee2 = (double) paywayFee2DebitCard.getMaxFee() / 100L;
                map.put("DEBIT_CARD", new LklMercInfoConn.Fee("DEBIT_CARD", 0.5d, 20d));
            }

            PaywayFee creditCardPaywayFee = paywayFee.getCreditCardPaywayFee();
            if (creditCardPaywayFee != null && CollUtil.isNotEmpty(creditCardPaywayFee.getLevelList()) && (CollUtil.isNotEmpty(creditCardPaywayFee.getLevelList()))) {
                PaywayFee paywayFeeCrebitCard = creditCardPaywayFee.getLevelList().get(0);
                map.put("YSF_DISCOUNT_CREDIT_FEE", new LklMercInfoConn.Fee("YSF_DISCOUNT_CREDIT_FEE", convertRate(paywayFeeCrebitCard.getFeeRate()), null));

                PaywayFee paywayFee2CrebitCard = creditCardPaywayFee.getLevelList().get(1);
                map.put("CREDIT_CARD", new LklMercInfoConn.Fee("CREDIT_CARD", convertRate(paywayFee2CrebitCard.getFeeRate()), null));

            }

            if (paywayFee.getWayCode().startsWith("WX_")) {
                map.put("WECHAT", new LklMercInfoConn.Fee("WECHAT", convertRate(paywayFee.getFeeRate()), null));
            }


            if (paywayFee.getWayCode().startsWith("ALI_")) {
                map.put("ALIPAY", new LklMercInfoConn.Fee("ALIPAY", convertRate(paywayFee.getFeeRate()), null));
            }

            if (CS.PAY_WAY_CODE.D0.equals(paywayFee.getWayCode())) {
                // D0费率
                double d0Rate = Double.parseDouble(convertRate(paywayFee.getFeeRate()));
                // 扫码d0费率
                map.put("SCAN_PAY_SECOND", new LklMercInfoConn.Fee("SCAN_PAY_SECOND", d0Rate, null));
                // 刷卡D0费率
                map.put("CARD_SECOND", new LklMercInfoConn.Fee("CARD_SECOND", d0Rate, null));
            }

            if (CS.PAY_WAY_CODE.SCAN.equals(paywayFee.getWayCode())) {
                // 线上费率
                map.put("WECHAT", new LklMercInfoConn.Fee("WECHAT", convertRate(paywayFee.getFeeRate()), null));
                map.put("ALIPAY", new LklMercInfoConn.Fee("ALIPAY", convertRate(paywayFee.getFeeRate()), null));

                // 借记卡费率
                // 银联借记卡，云闪付优惠费率，1000以下的交易费率
                map.put("YSF_DISCOUNT_DEBIT_FEE", new LklMercInfoConn.Fee("YSF_DISCOUNT_DEBIT_FEE", convertRate(paywayFee.getFeeRate()), null));

                // 银联费率有银联费率模版限制，写死，一般不用作实际交易
                map.put("DEBIT_CARD", new LklMercInfoConn.Fee("DEBIT_CARD", 0.5d, 20d));
                // 银联贷记卡，云闪付优惠费率，1000以下的交易费率
                map.put("YSF_DISCOUNT_CREDIT_FEE", new LklMercInfoConn.Fee("YSF_DISCOUNT_CREDIT_FEE", convertRate(paywayFee.getFeeRate()), null));
                map.put("CREDIT_CARD", new LklMercInfoConn.Fee("CREDIT_CARD", 0.6d, null));
            }
        }

        LklMercInfoConn.BizContent bizContent = new LklMercInfoConn.BizContent();

        String[] mccInfo = applymentInfo.getMccCode().split("_");
        bizContent.setMcc(mccInfo[1]);
        // 25为B2B收银台 13位专业扫码
        bizContent.setActivityId(LklpayConst.ACTIVITY_ID_WECHAT_PAY);
        bizContent.setTermNum("1");
        bizContent.setFees(new HashSet<>(map.values()));

        return bizContent;
    }

    private File writeHtml(Template template, LklspayApplymentInfo lklspayApplymentInfo, LklspayIsvParams isvParams) throws IOException, TemplateException {
        Map<String, Object> param = new HashMap<>();
        Map<String, Object> fee = new HashMap<>();

        LklMercInfoConn lklData = getLklData(lklspayApplymentInfo, isvParams);
        fee.put("customerName", Optional.ofNullable(lklData.getContactName()).orElse(""));
        param.put("fee", fee);
        param.put("licenseNo", Optional.ofNullable(lklData.getLicenseNo()).orElse(""));
        param.put("legalName", Optional.ofNullable(lklData.getLarName()).orElse(""));
        param.put("licenseName", Optional.ofNullable(lklData.getLicenseName()).orElse(""));
        param.put("identityNo", Optional.ofNullable(lklData.getLarIdCard()).orElse(""));
        param.put("address", lklData.getMerAddr());
        param.put("receiveDetail", Optional.ofNullable(lklData.getMerAddr()).orElse(""));
        param.put("identityNoExpire", Optional.ofNullable(getEndDate(lklData.getLicenseDtEnd())).orElse(""));
        param.put("accountName", Optional.ofNullable(lklData.getAccountName()).orElse(""));
        param.put("accountIdCard", Optional.ofNullable(lklData.getAccountIdCard()).orElse(""));
        param.put("accountNo", Optional.ofNullable(lklData.getAccountNo()).orElse(""));
        param.put("accountIdDtEnd", Optional.ofNullable(getEndDate(lklData.getAccountIdDtEnd())).orElse(""));
        param.put("bankName", Optional.ofNullable(lklData.getOpenningBankName()).orElse(""));
        param.put("mail", Optional.ofNullable(lklData.getEmail()).orElse(""));
        param.put("contactManName", Optional.ofNullable(lklData.getContactName()).orElse(""));
        param.put("channelType", Optional.ofNullable(lklData.getMerType()).orElse(""));
        param.put("phone", Optional.ofNullable(lklData.getContactMobile()).orElse(""));
        param.put("agencyName", "拉卡拉");
        param.put("width", "600px");
        param.put("tbTitleWidth", "60px");
        param.put("tbConWidth", "60px");

        String fileName = UUID.randomUUID().toString();
        File htmlFile = new File(FileUtil.getTmpDir(), fileName + ".html");
        FileWriter sw = new FileWriter(htmlFile);
        log.info("生成协议html, 地址:{}, 参数:{} ", htmlFile.getAbsolutePath(), param);
        template.process(param, sw);

        return htmlFile;
    }

    private static File createAgreementPicture(File htmlFile) throws IOException {
        File outputFile = new File(FileUtil.getTmpDir(), htmlFile.getName() + ".jpg");
        log.info("生成图片开始, HTML地址 {}, 图片地址:{}", htmlFile.getAbsolutePath(), outputFile.getAbsolutePath());
        /**
         * 生成图片说明，需要在服务器上安装需要的字体，等线字体即可，可在windows系统字体库中获得
         * 将字体放在服务器/usr/share/fonts/myfonts目录中，
         * 运行 sudo fc-cache -f -v 命令 即可刷新字体缓存
         */
        String commandProcess = "wkhtmltoimage  --width  400  --quality  94  " + htmlFile.getPath() + "  " + outputFile.getPath();
        log.info("协议执行Process command:{}", commandProcess);
        long startTime = System.currentTimeMillis();   //获取开始时间
        Process process = Runtime.getRuntime().exec(commandProcess);
        try {
            int exitVal = process.waitFor();
            log.info("协议html转换png结果:{}", exitVal);
        } catch (InterruptedException e) {
            log.info("协议html转换png错误", e);
            Thread.currentThread().interrupt();
            throw new IOException(e);
        }
        long endTime = System.currentTimeMillis(); //获取结束时间
        log.info("程序运行时间： " + (endTime - startTime) + "ms");
        log.info("生成图片结束,地址: {}", outputFile.getPath());
        Thumbnails.of(outputFile).scale(1).outputQuality(0.9).toFile(outputFile);
        return outputFile;
    }

    public MchApplyment submitMchInfo(MchApplyment mchApplyment) {
        MchApplyment result = new MchApplyment();
        result.setApplyId(mchApplyment.getApplyId());

        String channelVar1 = mchApplyment.getChannelVar1();
        Type type = new TypeReference<Set<LklMercInfoConn.Attachment>>() {
        }.getType();
        Set<LklMercInfoConn.Attachment> attachments = JSON.parseObject(channelVar1, type);

        LklspayApplymentInfo applymentInfo = JSON.parseObject(mchApplyment.getApplyDetailInfo(), LklspayApplymentInfo.class);
        LklspayIsvParams isvParams = ((LklspayIsvParams) configContextQueryService.queryIsvParams(mchApplyment.getIsvNo(), mchApplyment.getIfCode()));

        LklMercInfoConn lklData = getLklData(applymentInfo, isvParams);

        lklData.setAttchments(attachments);

        JSONObject resp = LklspayKit.applymentRequest(LklTkReqMethod.AUDIT, isvParams, (JSONObject) JSON.toJSON(lklData));
        String status = resp.getString("status");
        String customerNo = resp.getString("merchantNo");
        if (status.equals("WAIT_AUDI")) {
            result.setState(com.jeequan.jeepay.core.entity.MchApplyment.STATE_AUDITING);
            result.setChannelApplyNo(customerNo);
        }

        // 进件响应参数
        result.setSettlementType(applymentInfo.getSettleType());
        result.setState(com.jeequan.jeepay.core.entity.MchApplyment.STATE_AUDITING);

        return result;
    }

    public MchApplyment uploadImg(MchApplyment mchApplyment) {
        MchApplyment result = new MchApplyment();
        result.setApplyId(mchApplyment.getApplyId());

        File agreementPicture;

        LklspayApplymentInfo applymentInfo = JSON.parseObject(mchApplyment.getApplyDetailInfo(), LklspayApplymentInfo.class);
        Assert.notNull(applymentInfo.getAreaName(), "经营地区名称[areaName]不能为空");
        Assert.isFalse(applymentInfo.getAreaName().isEmpty(), "经营地区名称[areaName]不能为空");
        LklspayIsvParams isvParams = ((LklspayIsvParams) configContextQueryService.queryIsvParams(mchApplyment.getIsvNo(), mchApplyment.getIfCode()));

        try {
            Template template = configuration.getTemplate("lkltkpay/indexHTKWECHAT_PAY.html.ftl");
            File file = writeHtml(template, applymentInfo, isvParams);
            agreementPicture = createAgreementPicture(file);
        } catch (Exception e) {
            log.info("创建拉卡拉汇拓客协议图片失败", e);
            throw new BizException("创建拉卡拉汇拓客协议图片失败, " + e.getMessage());
        }

        Set<LklMercInfoConn.Attachment> attachments = new HashSet<>();
        uploadRequest(attachments, "AGREE_MENT", agreementPicture, isvParams);
        uploadRequest(attachments, "SHOP_OUTSIDE_IMG", applymentInfo.getStoreOuterImg(), isvParams);
        uploadRequest(attachments, "SHOP_INSIDE_IMG", applymentInfo.getStoreInnerImg(), isvParams);
        uploadRequest(attachments, "CHECKSTAND_IMG", applymentInfo.getStoreCashierImg(), isvParams);
        uploadRequest(attachments, "ID_CARD_FRONT", applymentInfo.getIdcard1Img(), isvParams);
        uploadRequest(attachments, "ID_CARD_BEHIND", applymentInfo.getIdcard2Img(), isvParams);

        if (applymentInfo.getMerchantType() != com.jeequan.jeepay.core.entity.MchApplyment.MERCHANT_TYPE_PERSONAL) {
            uploadRequest(attachments, "BUSINESS_LICENCE", applymentInfo.getLicenseImg(), isvParams);

            if (com.jeequan.jeepay.core.entity.MchApplyment.SETT_ACCOUNT_TYPE_PERSONAL.equals(applymentInfo.getSettAccountType())) {
                uploadRequest(attachments, "BANK_CARD", applymentInfo.getSettAccountLicenseImg(), isvParams);
            }

            if (com.jeequan.jeepay.core.entity.MchApplyment.SETT_ACCOUNT_TYPE_CORPORATE.equals(applymentInfo.getSettAccountType())) {
                uploadRequest(attachments, "OPENING_PERMIT", applymentInfo.getCompanyAccountLicenseImg(), isvParams);
            }
        }

        if (!"1".equals(applymentInfo.getIsLegalInfo())) {
            uploadRequest(attachments, "SETTLE_ID_CARD_FRONT", applymentInfo.getSettAccountIdcard1Img(), isvParams);
            uploadRequest(attachments, "SETTLE_ID_CARD_BEHIND", applymentInfo.getSettAccountIdcard2Img(), isvParams);
            uploadRequest(attachments, "LETTER_OF_AUTHORIZATION", applymentInfo.getLetterOfAuthorizationImg(), isvParams);
        } else {
            uploadRequest(attachments, "SETTLE_ID_CARD_FRONT", applymentInfo.getIdcard1Img(), isvParams);
            uploadRequest(attachments, "SETTLE_ID_CARD_BEHIND", applymentInfo.getIdcard2Img(), isvParams);
        }

        result.setState(MchApplyment.STATE_AUDITING_WAIT);
        result.setRemainStep((byte) 1);

        result.setChannelVar1(JSON.toJSONString(attachments));

        return result;
    }

    public void uploadRequest(Set<LklMercInfoConn.Attachment> attachmentList, String key, File file, LklspayIsvParams isvParams) {
        attachmentList.add(getAttachment(isvParams, file, key));
    }

    public void uploadRequest(Set<LklMercInfoConn.Attachment> attachmentList, String key, String imgUrl, LklspayIsvParams isvParams) {
        // 下载文件
        LklMercInfoConn.Attachment attach = getAttachment(isvParams, imgUrl, key);
        attachmentList.add(attach);
    }

    private static LklMercInfoConn.Attachment getAttachment(LklspayIsvParams isvParams, File file, String imgType) {
        JSONObject imgUploadResult = LklspayKit.uploadRequest(isvParams, file, imgType);
        LklMercInfoConn.Attachment attachmentItem = new LklMercInfoConn.Attachment();
        attachmentItem.setId(imgUploadResult.getString("url"));
        attachmentItem.setType(imgType);
        return attachmentItem;
    }

    private static LklMercInfoConn.Attachment getAttachment(LklspayIsvParams isvParams, String fileUrl, String imgType) {
        JSONObject imgUploadResult = LklspayKit.uploadRequest(isvParams, fileUrl, imgType);
        LklMercInfoConn.Attachment attachmentItem = new LklMercInfoConn.Attachment();
        attachmentItem.setId(imgUploadResult.getString("url"));
        attachmentItem.setType(imgType);
        return attachmentItem;
    }

    @Override
    public boolean preCheck() {
        return true;
    }

    /**
     * mchRq
     *
     * @param applyment
     * @param mchRq
     * @return
     */
    @Override
    public ChannelRetMsg appidAndPath(MchApplyment applyment, ChannelMchRq mchRq) {
        preWxParamsCheck(mchRq);
        JSONObject bizData = new JSONObject();
        bizData.put("merCupNo", applyment.getChannelMchNo());
        if (ChannelMchRq.Type.PATH.getType().equals(mchRq.getType())) {
            bizData.put("confType", "JSAPI_PATH");
            bizData.put("jsapiPath", mchRq.getJsapiPath());
        } else {
            bizData.put("subAppid", mchRq.getAppid());
            bizData.put("confType", "SUB_APPID");
        }
        bizData.put("subMchId", mchRq.getSubMchNo());
        LklspayIsvParams isvParams = (LklspayIsvParams) configContextQueryService.queryIsvParams(applyment);
        JSONObject result = LklspayKit.reqMch(LklPayMethod.Api.WECHAT_PARAMS_CONFIG_URL, isvParams, bizData);
        return ChannelRetMsg.confirmSuccess(null);
    }

    /**
     * 校验拉卡拉微信参数配置
     *
     * @param mchRq
     */
    private void preWxParamsCheck(ChannelMchRq mchRq) {
        if (StringUtils.isEmpty(mchRq.getSubMchNo())) {
            throw new BizException("调用拉卡拉配置微信参数接口失败，缺失微信子商户号[subMchNo]参数");
        }
    }

    /**
     * 拉卡拉查询结算信息接口
     *
     * @param settleRq
     * @param isvParams
     * @return
     */
    @Override
    public List<JSONObject> querySettleInfo(ChannelSettleRq settleRq, String isvNo, LklspayIsvParams isvParams) {
        super.preSettleCheck(settleRq);
        if (StringUtils.isBlank(settleRq.getMercNo())) {
            throw new BizException("缺失商户号");
        }
        JSONObject bizData = new JSONObject();
        bizData.put("merchantNo", settleRq.getMercNo());
        bizData.put("startDate", DateUtil.format(settleRq.getStartDate(), DatePattern.PURE_DATE_PATTERN));
        bizData.put("endDate", DateUtil.format(settleRq.getEndDate(), DatePattern.PURE_DATE_PATTERN));
        bizData.put("page", settleRq.getPage());
        bizData.put("size", settleRq.getSize());
        JSONObject respData = LklspayKit.reqSettle(LklPayMethod.Api.SETTLE_QUERY, bizData, isvParams);
        JSONArray resultList = respData.getJSONArray("respData");
        if(resultList.isEmpty()){
            return null;
        }
        //拉卡拉只支持单商户结算记录查询
        List<JSONObject> result = new ArrayList<>(1);
        for (Object item:resultList) {
            JSONObject respBizData = (JSONObject)item;
            JSONObject stlData = new JSONObject();
            stlData.put("billNo", respBizData.getString("payRecordId"));
            stlData.put("accountName", respBizData.getString("accountName"));
            stlData.put("accountNo", respBizData.getString("accountNo"));
            stlData.put("bankName", respBizData.getString("accountBranchBank"));
            stlData.put("channelState", respBizData.getString("chnlRespCode"));
            stlData.put("remark", respBizData.getString("chnlRespMsg"));
            String stlAmt = respBizData.getString("transferMoneyAmount");
            if (StringUtils.isNotBlank(stlAmt)) {
                boolean val = stlAmt.contains(",");
                if (val) {
                    stlAmt = stlAmt.replace(",", "");
                }
                stlData.put("settleAmt", new BigDecimal(stlAmt).multiply(BigDecimal.valueOf(100)));
            }
//            String feeAmt = respBizData.getString("feeAmt");
//            if (StringUtils.isNotBlank(feeAmt)) {
//                boolean val = feeAmt.contains(",");
//                if (val) {
//                    feeAmt = feeAmt.replace(",", "");
//                }
//                long fee = new BigDecimal(feeAmt).multiply(BigDecimal.valueOf(100)).longValue();
//                if( fee > 0L){
//                    stlData.put("fee",fee);
//                }
//            }
            String payDate = respBizData.getString("transferMoneyDate");
            stlData.put("settleDate", payDate);
            stlData.put("settleTime", payDate + " " + respBizData.getString("transferMoneyTime"));
            SettleState state = SettleState.getVal(respBizData.getString("transferMoneyStatus"));
            switch (state) {
                case PAY_SUCCESS:
                    stlData.put("state", SettleInfo.SUCCESS);
                    break;
                case PAY_FAIL:
                    stlData.put("state", SettleInfo.FAIL);
                    break;
                case PAY_PROGRESS:
                    stlData.put("state", SettleInfo.PROGRESS);
                    break;
                case PAY_EZ:
                    stlData.put("state", SettleInfo.OTHER);
                    break;
                default:
                    stlData.put("state", SettleInfo.WAIT);
                    break;
            }
            stlData.put("channelState", state.getState());
            stlData.put("extra", respBizData.toString());
            result.add(stlData);
        }
        return result;
    }

    @Getter
    @AllArgsConstructor
    public enum SettleState {

        PAY_INIT("00", "初始登记"),

        PAY_PROGRESS("01", "付款中"),

        PAY_SUCCESS("02", "付款成功"),

        PAY_FAIL("03", "付款失败"),

        PAY_EZ("EZ", "状态未明"),

        PAY_AUDIT("07", "审核中");

        private final String state;

        private final String desc;

        public static SettleState getVal(String state) {
            SettleState[] values = values();
            for (SettleState val : values) {
                if (val.getState().equals(state)) {
                    return val;
                }
            }
            return PAY_INIT;
        }
    }
}
