package com.jeequan.jeepay.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.model.RateConfigSimple;
import com.jeequan.jeepay.service.mapper.RateConfigMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;

/**
 * 采用新的费率配置模式
 *
 * @author deng
 * @since 2024-05-06
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RateConfigV2Service extends ServiceImpl<RateConfigMapper, RateConfig> {

    private final RateConfigService rateConfigService;
    private final AgentInfoService agentInfoService;
    private final MchInfoService mchInfoService;
    private final IsvInfoService isvInfoService;
    private final PayInterfaceDefineService payInterfaceDefineService;
    private final TransferInterfaceDefineService transferInterfaceDefineService;
    private final SysConfigService sysConfigService;
    private final MchInfoConverter infoConverter;
    private final TransactionTemplate transactionTemplate;

    /**
     * 根据infoType和infoId获取到对应的费率数据合集, 包含infoId的上限费率
     *
     * @return 费率信息
     */
    public List<RateConfigSimple> getRankFeeList(String isvNo, String infoType, String infoId,
                                                 String ifCode, Integer range, String mccCode, String identityNo) {
        List<RateConfigSimple> result = new ArrayList<>();

        if (infoType.equalsIgnoreCase(CS.SYS_ROLE_TYPE.ISV)) {
            return getIsvRankFeeList(isvNo, ifCode, range, mccCode);
        }

        if (infoType.equalsIgnoreCase(CS.SYS_ROLE_TYPE.AGENT)) {
            return getAgentRankFeeList(isvNo, infoId, ifCode, range, mccCode, identityNo);
        }

        if (infoType.equalsIgnoreCase(CS.SYS_ROLE_TYPE.MCH)) {
            return getMchRankFeeList(isvNo, infoId, ifCode, range, mccCode, identityNo);
        }

        return result;
    }

    public RateConfigSimple getIsvRateConfig(IsvInfoEntity isvInfo, String ifCode, String ifName, Integer range, String mccCode, boolean transfer) {
        String isvNo = isvInfo.getIsvNo();
        RateConfigSimple isvRateConfig = new RateConfigSimple();
        isvRateConfig.setIsvNo(isvNo);
        isvRateConfig.setIsvName(isvInfo.getIsvName());
        isvRateConfig.setIfCode(ifCode);
        isvRateConfig.setIfName(ifName);
        isvRateConfig.setRange(range);
        isvRateConfig.setMccCode(mccCode);
        isvRateConfig.setInfoType(CS.SYS_ROLE_TYPE.ISV);
        isvRateConfig.setInfoId(isvInfo.getIsvNo());
        isvRateConfig.setInfoName(ifName);

        Map<String, PaywayFee> paywayFeeMap = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByIsvCost(isvNo), CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setSelf(paywayFeeMap);

        // 下级代理默认费率
        Map<String, PaywayFee> agentDef = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(isvNo), CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setSubAgentDef(agentDef);

        Map<String, PaywayFee> maxFeeMap = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(isvNo), CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setMchMax(maxFeeMap);

        return isvRateConfig;
    }

    /**
     * 获取服务商费率信息
     */
    public RateConfigSimple getAgentRateConfig(IsvInfoEntity isvInfo, String ifCode, String ifName, String agentNo, Integer range, String mccCode, boolean transfer) {
        String isvNo = isvInfo.getIsvNo();

        RateConfigSimple isvRateConfig = new RateConfigSimple();
        isvRateConfig.setIsvNo(isvNo);
        isvRateConfig.setIsvName(isvInfo.getIsvName());
        isvRateConfig.setIfCode(ifCode);
        isvRateConfig.setIfName(ifName);
        isvRateConfig.setRange(range);
        isvRateConfig.setMccCode(mccCode);
        isvRateConfig.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
        isvRateConfig.setInfoId(agentNo);
        AgentInfo agentInfo = agentInfoService.getById(agentNo);
        isvRateConfig.setInfoName(agentInfo.getAgentName());

        Map<String, PaywayFee> paywayFeeMap = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(agentNo), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setSelf(paywayFeeMap);

        // 下级代理默认费率
        Map<String, PaywayFee> agentDef = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(agentNo), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setSubAgentDef(agentDef);
        // 下级商户默认费率
        Map<String, PaywayFee> mchDef = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchDef(agentNo), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setSubMchDef(mchDef);

        Map<String, PaywayFee> maxFeeMap = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(agentNo), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setMchMax(maxFeeMap);

        return isvRateConfig;
    }

    /**
     * 获取商户费率信息
     */
    public RateConfigSimple getMchRateConfig(IsvInfoEntity isvInfo, String ifCode, String ifName, String agentNo, String mchNo, Integer range, String mccCode, boolean transfer) {
        String isvNo = isvInfo.getIsvNo();
        RateConfigSimple isvRateConfig = new RateConfigSimple();
        isvRateConfig.setIsvNo(isvNo);
        isvRateConfig.setIsvName(isvInfo.getIsvName());
        isvRateConfig.setIfCode(ifCode);
        isvRateConfig.setIfName(ifName);
        isvRateConfig.setRange(range);
        isvRateConfig.setMccCode(mccCode);
        isvRateConfig.setInfoType(CS.SYS_ROLE_TYPE.MCH);
        isvRateConfig.setInfoId(mchNo);
        MchInfo mchInfo = mchInfoService.getById(mchNo);
        isvRateConfig.setInfoName(mchInfo.getMchName());

        Map<String, PaywayFee> paywayFeeMap = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchApp(mchNo), CS.SYS_ROLE_TYPE.MCH, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setSelf(paywayFeeMap);

        // 上级服务商的默认商户费率
        Map<String, PaywayFee> agentDef = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchDef(agentNo), CS.SYS_ROLE_TYPE.MCH, ifCode, range, mccCode, isvNo, transfer);
        isvRateConfig.setSelfDef(agentDef);

        return isvRateConfig;
    }

    /**
     * 只返回渠道商的费率
     */
    public List<RateConfigSimple> getIsvRankFeeList(String isvNo, String ifCode, Integer range, String mccCode) {
        IsvInfoEntity isvInfo = isvInfoService.getById(isvNo);
        Assert.notNull(isvInfo, "未知的渠道商号【isvNo】");
        PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
        TransferInterfaceDefineEntity transferInterfaceDefine = transferInterfaceDefineService.getByCode(ifCode);

        String ifName = null;
        if (payInterfaceDefine != null) {
            ifName = payInterfaceDefine.getIfName();
        } else if (transferInterfaceDefine != null) {
            ifName = transferInterfaceDefine.getTransIfName();
        }

        List<RateConfigSimple> result = new ArrayList<>();

        RateConfigSimple isvRateConfig = getIsvRateConfig(isvInfo, ifCode, ifName, range, mccCode, transferInterfaceDefine != null);
        result.add(isvRateConfig);

        return result;
    }

    /**
     * 返回代理的费率配置信息
     */
    public List<RateConfigSimple> getAgentRankFeeList(String isvNo, String agentNo, String ifCode, Integer range, String mccCode, String identityNo) {
        List<RateConfigSimple> result = new ArrayList<>();

        IsvInfoEntity isvInfo = isvInfoService.getById(isvNo);
        Assert.notNull(isvInfo, "未知的渠道商号【isvNo】");
        PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
        TransferInterfaceDefineEntity transferInterfaceDefine = transferInterfaceDefineService.getByCode(ifCode);

        String ifName = null;
        boolean transfer = transferInterfaceDefine != null;
        if (payInterfaceDefine != null) {
            ifName = payInterfaceDefine.getIfName();
        } else if (transfer) {
            ifName = transferInterfaceDefine.getTransIfName();
        }


        // identityNo == isvNo 为最高权限
        if (identityNo.equalsIgnoreCase(isvNo)) {
            RateConfigSimple isvRateConfig = getIsvRateConfig(isvInfo, ifCode, ifName, range, mccCode, transfer);
            result.add(isvRateConfig);
        }

        AgentInfo agentInfo = agentInfoService.getById(agentNo);

        List<String> agentNoList = new ArrayList<>();
        if (!ObjUtil.isEmpty(agentInfo.getPidArr())) {
            String[] split = agentInfo.getPidArr().split(",");
            agentNoList = CollUtil.list(false, split);
        }

        agentNoList.add(agentNo);

        boolean visibleFlag = identityNo.equalsIgnoreCase(isvNo);
        for (String itemAgentNo : agentNoList) {
            if (itemAgentNo.equalsIgnoreCase(identityNo)) {
                visibleFlag = true;
            }

            if (visibleFlag) {
                RateConfigSimple isvRateConfig = getAgentRateConfig(isvInfo, ifCode, ifName, itemAgentNo, range, mccCode, transfer);
                result.add(isvRateConfig);
            }
        }

        return result;
    }

    /**
     * 返回商户的费率配置信息
     */
    public List<RateConfigSimple> getMchRankFeeList(String isvNo, String mchNo, String ifCode, Integer range, String mccCode, String identityNo) {
        List<RateConfigSimple> result = new ArrayList<>();

        IsvInfoEntity isvInfo = isvInfoService.getById(isvNo);
        Assert.notNull(isvInfo, "未知的渠道商号【isvNo】");
        PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
        TransferInterfaceDefineEntity transferInterfaceDefine = transferInterfaceDefineService.getByCode(ifCode);

        boolean transfer = transferInterfaceDefine != null;
        String ifName = null;
        if (payInterfaceDefine != null) {
            ifName = payInterfaceDefine.getIfName();
        } else if (transferInterfaceDefine != null) {
            ifName = transferInterfaceDefine.getTransIfName();
        }

        // identityNo == isvNo 为最高权限
        if (identityNo.equalsIgnoreCase(isvNo)) {
            RateConfigSimple isvRateConfig = getIsvRateConfig(isvInfo, ifCode, ifName, range, mccCode, transfer);
            result.add(isvRateConfig);
        }

        MchInfo mchInfo = mchInfoService.getById(mchNo);
        AgentInfo agentInfo = agentInfoService.getById(mchInfo.getAgentNo());

        List<String> agentNoList = new ArrayList<>();
        if (!ObjUtil.isEmpty(agentInfo.getPidArr())) {
            String[] split = agentInfo.getPidArr().split(",");
            agentNoList = CollUtil.list(false, split);
        }

        agentNoList.add(mchInfo.getAgentNo());

        boolean visibleFlag = identityNo.equalsIgnoreCase(isvNo);
        for (String itemAgentNo : agentNoList) {
            if (itemAgentNo.equalsIgnoreCase(identityNo)) {
                visibleFlag = true;
            }

            if (visibleFlag) {
                RateConfigSimple isvRateConfig = getAgentRateConfig(isvInfo, ifCode, ifName, itemAgentNo, range, mccCode, transfer);
                result.add(isvRateConfig);
            }
        }

        // 收集到的费率数据不为空的情况下，获取商户费率，以及最后一个服务商的商户最大费率
        if (!result.isEmpty()) {
            RateConfigSimple isvRateConfig = getMchRateConfig(isvInfo, ifCode, ifName, mchInfo.getAgentNo(), mchInfo.getMchNo(), range, mccCode, transfer);
            result.add(isvRateConfig);
        }

        return result;
    }

    public void save(RateConfigSimple rateConfig) {
        String infoId = rateConfig.getInfoId();
        String infoType = rateConfig.getInfoType();

        Assert.notNull(infoType, "【infoType】不能为空");
        Assert.notNull(infoId, "【infoId】不能为空");
        Assert.notNull(rateConfig.getIsvNo(), "【isvNo】不能为空");
        Assert.notNull(rateConfig.getIfCode(), "【ifCode】不能为空");

        switch (infoType) {
            case CS.SYS_ROLE_TYPE.ISV:
                saveIsvRateConfig(rateConfig);
                break;
            case CS.SYS_ROLE_TYPE.AGENT:
                saveAgentRateConfig(rateConfig);
                break;
            case CS.SYS_ROLE_TYPE.MCH:
                saveMchRateConfig(rateConfig);
                break;
            default:
                throw new BizException("【infoType】不支持");
        }
    }

    public void saveIsvRateConfig(RateConfigSimple rateConfig) {
        Map<String, PaywayFee> self = rateConfig.getSelf();
        Map<String, PaywayFee> subAgentDef = Optional.ofNullable(rateConfig.getSubAgentDef()).orElse(new HashMap<>());
        Map<String, PaywayFee> subMchDef = Optional.ofNullable(rateConfig.getSubMchDef()).orElse(new HashMap<>());
        Map<String, PaywayFee> mchMax = Optional.ofNullable(rateConfig.getMchMax()).orElse(new HashMap<>());

        boolean transfer = transferInterfaceDefineService.getByCode(rateConfig.getIfCode()) != null;

        Assert.notEmpty(self, "【self】渠道商费率信息不能为空");

        // 一般来说，只有一个默认一级服务商
        String defaultAgentNo = sysConfigService.getDBDefaultConfig().getDefaultAgentNo();
        // 做数据校验
        Map<String, PaywayFee> agentRateConfig = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(defaultAgentNo), CS.SYS_ROLE_TYPE.AGENT, rateConfig.getIfCode(), rateConfig.getRange(), rateConfig.getMccCode(), rateConfig.getIsvNo(), transfer);

        for (Map.Entry<String, PaywayFee> rateItem : agentRateConfig.entrySet()) {
            PaywayFee paywayFee = self.get(rateItem.getKey());
            paywayFee.compareByFee(rateItem.getValue(), -10, "服务商【" + defaultAgentNo + "】");
        }

        // 比较默认下级服务商费率和默认下级商户费率
        for (Map.Entry<String, PaywayFee> rateItem : subMchDef.entrySet()) {
            PaywayFee paywayFee = subAgentDef.get(rateItem.getKey());
            paywayFee.compareByFee(rateItem.getValue(), -10, "下级服务商默认费率");
        }

        // 比较默认下级商户费率和最大下级商户费率
        for (Map.Entry<String, PaywayFee> rateItem : mchMax.entrySet()) {
            PaywayFee paywayFee = self.get(rateItem.getKey());
            paywayFee.compareByFee(rateItem.getValue(), -10, "最大商户费率");
        }

        List<RateConfig> saveDataList = new ArrayList<>();
        saveDataList.addAll(getRateConfigList(rateConfig, self, RateConfig.appendInfoByIsvCost(rateConfig.getIsvNo())));
        saveDataList.addAll(getRateConfigList(rateConfig, subAgentDef, RateConfig.appendInfoByAgentDef(rateConfig.getIsvNo())));
        saveDataList.addAll(getRateConfigList(rateConfig, subMchDef, RateConfig.appendInfoByMchDef(rateConfig.getIsvNo())));
        saveDataList.addAll(getRateConfigList(rateConfig, mchMax, RateConfig.appendInfoByMchMax(rateConfig.getIsvNo())));

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                LambdaQueryWrapper<RateConfig> wrapper = Wrappers.lambdaQuery(RateConfig.class)
                        .in(RateConfig::getInfoId
                                , RateConfig.appendInfoByIsvCost(rateConfig.getIsvNo())
                                , RateConfig.appendInfoByAgentDef(rateConfig.getIsvNo())
                                , RateConfig.appendInfoByMchDef(rateConfig.getIsvNo())
                                , RateConfig.appendInfoByMchMax(rateConfig.getIsvNo()))
                        .eq(RateConfig::getInfoType, rateConfig.getInfoType())
                        .eq(RateConfig::getIsvNo, rateConfig.getIsvNo())
                        .eq(RateConfig::getIfCode, rateConfig.getIfCode())
                        .eq(!ObjUtil.isEmpty(rateConfig.getRange()), RateConfig::getRange, rateConfig.getRange())
                        .eq(!ObjUtil.isEmpty(rateConfig.getMccCode()), RateConfig::getMccCode, rateConfig.getMccCode());

                remove(wrapper);

                saveBatch(saveDataList);
            }
        });
    }

    public void saveAgentRateConfig(RateConfigSimple rateConfig) {
        Map<String, PaywayFee> self = rateConfig.getSelf();
        Map<String, PaywayFee> subAgentDef = Optional.ofNullable(rateConfig.getSubAgentDef()).orElse(new HashMap<>());
        Map<String, PaywayFee> subMchDef = Optional.ofNullable(rateConfig.getSubMchDef()).orElse(new HashMap<>());
        Map<String, PaywayFee> mchMax = Optional.ofNullable(rateConfig.getMchMax()).orElse(new HashMap<>());

        Assert.notEmpty(self, "【self】服务商费率信息不能为空");

        boolean transfer = transferInterfaceDefineService.getByCode(rateConfig.getIfCode()) != null;

        AgentInfo agentSelfInfo = agentInfoService.getById(rateConfig.getInfoId());
        // 做数据校验
        Map<String, PaywayFee> agentRateConfig = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(agentSelfInfo.getPid()), CS.SYS_ROLE_TYPE.AGENT, rateConfig.getIfCode(), rateConfig.getRange(), rateConfig.getMccCode(), rateConfig.getIsvNo(), transfer);

        for (Map.Entry<String, PaywayFee> rateItem : agentRateConfig.entrySet()) {
            PaywayFee paywayFee = self.get(rateItem.getKey());
            paywayFee.compareByFee(rateItem.getValue(), -10, "服务商【" + agentSelfInfo.getPid() + "】");
        }

        // 比较默认下级服务商费率和默认下级商户费率
        for (Map.Entry<String, PaywayFee> rateItem : subMchDef.entrySet()) {
            PaywayFee paywayFee = subAgentDef.get(rateItem.getKey());
            paywayFee.compareByFee(rateItem.getValue(), -10, "下级服务商默认费率");
        }

        // 比较默认下级商户费率和最大下级商户费率
        for (Map.Entry<String, PaywayFee> rateItem : mchMax.entrySet()) {
            PaywayFee paywayFee = self.get(rateItem.getKey());
            paywayFee.compareByFee(rateItem.getValue(), -10, "最大商户费率");
        }

        List<RateConfig> saveDataList = new ArrayList<>();
        saveDataList.addAll(getRateConfigList(rateConfig, self, RateConfig.appendInfoByAgent(rateConfig.getInfoId())));
        saveDataList.addAll(getRateConfigList(rateConfig, subAgentDef, RateConfig.appendInfoByAgentDef(rateConfig.getInfoId())));
        saveDataList.addAll(getRateConfigList(rateConfig, subMchDef, RateConfig.appendInfoByMchDef(rateConfig.getInfoId())));
        saveDataList.addAll(getRateConfigList(rateConfig, mchMax, RateConfig.appendInfoByMchMax(rateConfig.getInfoId())));

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                LambdaQueryWrapper<RateConfig> wrapper = Wrappers.lambdaQuery(RateConfig.class)
                        .in(RateConfig::getInfoId
                                , RateConfig.appendInfoByAgent(rateConfig.getInfoId())
                                , RateConfig.appendInfoByAgentDef(rateConfig.getInfoId())
                                , RateConfig.appendInfoByMchDef(rateConfig.getInfoId())
                                , RateConfig.appendInfoByMchMax(rateConfig.getInfoId()))
                        .eq(RateConfig::getInfoType, rateConfig.getInfoType())
                        .eq(RateConfig::getIsvNo, rateConfig.getIsvNo())
                        .eq(RateConfig::getIfCode, rateConfig.getIfCode())
                        .eq(!ObjUtil.isEmpty(rateConfig.getRange()), RateConfig::getRange, rateConfig.getRange())
                        .eq(!ObjUtil.isEmpty(rateConfig.getMccCode()), RateConfig::getMccCode, rateConfig.getMccCode());

                remove(wrapper);

                saveBatch(saveDataList);
            }
        });
    }

    public void saveMchRateConfig(RateConfigSimple rateConfig) {
        Map<String, PaywayFee> self = rateConfig.getSelf();
        Assert.notEmpty(self, "【self】商户费率信息不能为空");

        boolean transfer = transferInterfaceDefineService.getByCode(rateConfig.getIfCode()) != null;

        MchInfo mchInfo = mchInfoService.getById(rateConfig.getInfoId());
        // 做数据校验
        Map<String, PaywayFee> agentRateConfig = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(mchInfo.getAgentNo()), CS.SYS_ROLE_TYPE.AGENT, rateConfig.getIfCode(), rateConfig.getRange(), rateConfig.getMccCode(), rateConfig.getIsvNo(), transfer);

        for (Map.Entry<String, PaywayFee> rateItem : agentRateConfig.entrySet()) {
            PaywayFee paywayFee = self.get(rateItem.getKey());
            paywayFee.compareByFee(rateItem.getValue(), 10, "服务商【" + mchInfo.getAgentNo() + "】");
        }

        List<RateConfig> saveDataList = new ArrayList<>();
        saveDataList.addAll(getRateConfigList(rateConfig, self, RateConfig.appendInfoByMchApp(rateConfig.getInfoId())));

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                LambdaQueryWrapper<RateConfig> wrapper = Wrappers.lambdaQuery(RateConfig.class)
                        .in(RateConfig::getInfoId, RateConfig.appendInfoByMchApp(rateConfig.getInfoId()))
                        .eq(RateConfig::getInfoType, rateConfig.getInfoType())
                        .eq(RateConfig::getIsvNo, rateConfig.getIsvNo())
                        .eq(RateConfig::getIfCode, rateConfig.getIfCode())
                        .eq(!ObjUtil.isEmpty(rateConfig.getRange()), RateConfig::getRange, rateConfig.getRange())
                        .eq(!ObjUtil.isEmpty(rateConfig.getMccCode()), RateConfig::getMccCode, rateConfig.getMccCode());

                remove(wrapper);

                saveBatch(saveDataList);
            }
        });
    }

    private List<RateConfig> getRateConfigList(RateConfigSimple rateConfig, Map<String, PaywayFee> paywayFeeMap, String infoId) {
        List<RateConfig> saveDataList = new ArrayList<>();
        Optional.ofNullable(paywayFeeMap).map(Map::values).orElse(Collections.emptyList()).forEach(paywayFeeItem -> {
            RateConfig item = infoConverter.toRateConfig(paywayFeeItem);
            item.setInfoId(infoId);
            item.setPaywayFeeDetail(((JSONObject) JSON.toJSON(paywayFeeItem)));
            infoConverter.cp(rateConfig, item);
            saveDataList.add(item);
        });

        return saveDataList;
    }
}
