
package com.jeequan.jeepay.agent.ctrl.payconfig;

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.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.converter.BaseConverter;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
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.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/***
 * 费率配置信息
 *
 * @author terrfly
 *
 * @date 2022/3/21 0:13
 */
@RestController
@RequestMapping("/api/rateConfig")
public class RateConfigController extends CommonCtrl {

    @Autowired private MchAppService mchAppService;
    @Autowired private RateConfigService rateConfigService;
    @Autowired private PayWayService payWayService;
    @Autowired private PayInterfaceConfigService payInterfaceConfigService;
    @Autowired
    private BaseConverter baseConverter;
    @Autowired
    private RateConfigV2Service rateConfigV2Service;


    /** 查询可用的支付接口 **/
    @GetMapping("/ifCodes")
    public ApiRes ifCodes() {

        // 搜索条件
        String ifName = getValString("ifName");

        String infoId = getValStringRequired("infoId"); // infoId
        String configMode = getValStringRequired("configMode"); // 设置类型

        // 支付接口列表
        LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
        lambdaQueryWrapper.eq(PayInterfaceDefine::getState, CS.YES); // 查询可用的支付接口列表

        lambdaQueryWrapper.like(StringUtils.isNotEmpty(ifName), PayInterfaceDefine::getIfName, ifName);


        AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());

        // 服务商 配置 商户费率 | 下级服务商费率 | 自己配置信息 【显示  当前服务商所有接口】
        if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode) ||
                RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)||
                RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)
        ){

            List<String> ifCodeList = new ArrayList<>();
            payInterfaceConfigService.list(PayInterfaceConfig.gw().select(PayInterfaceConfig::getIfCode)
                    .eq(PayInterfaceConfig::getInfoId, agentInfo.getIsvNo())
                    .eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
                    .eq(PayInterfaceConfig::getState, CS.YES)
            ).forEach(r -> ifCodeList.add(r.getIfCode()));

            if(ifCodeList.isEmpty()){ // 没有可用的接口
                return ApiRes.ok(ifCodeList);
            }
            lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodeList);

        }else if( RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode) ){ // 服务商进件


            // 查询服务商开通的
            List<String> ifCodeList = new ArrayList<>();
            List<PayInterfaceConfig> result = payInterfaceConfigService.list(PayInterfaceConfig.gw().select(PayInterfaceConfig::getIfCode)
                    .eq(PayInterfaceConfig::getInfoId, agentInfo.getIsvNo())
                    .eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
                    .eq(PayInterfaceConfig::getState, CS.YES));

            for (PayInterfaceConfig payInterfaceConfig : result) {
                ifCodeList.add(payInterfaceConfig.getIfCode());
            }

            if(ifCodeList.isEmpty()){ // 没有可用的接口
                return ApiRes.ok(ifCodeList);
            }

            // 查询服务商配置费率的支付接口
            Set<String> agentIfCodes = new HashSet<>();
            rateConfigService.lambdaQuery()
                    .select(RateConfig::getIfCode)
                    .eq(RateConfig::getInfoId, RateConfig.appendInfoByAgent(getCurrentAgentNo()))
                    .eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.AGENT)
                    .in(RateConfig::getIfCode, ifCodeList)
                    .list().forEach(r -> agentIfCodes.add(r.getIfCode()));

            //
            Collection<String> ifCodeList1 = CollUtil.intersection(ifCodeList, agentIfCodes);
            ifCodeList = new ArrayList<>(ifCodeList1);

            if(ifCodeList.isEmpty()){ // 没有可用的接口
                return ApiRes.ok(ifCodeList);
            }

            lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodeList);

        }


        lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
        List<PayInterfaceDefine> list = payInterfaceDefineService.list(lambdaQueryWrapper);
        return ApiRes.ok(list);
    }


    /** 查询所有可配置的支付方式  payways **/
    @GetMapping("/payways")
    public ApiRes payways() {

        String ifCode = getValStringRequired("ifCode"); // ifCode
//        String infoId = getValStringRequired("infoId"); // infoId
//        String isvNo = getValStringRequired("isvNo"); // infoId
        String isvNo = getValStringDefault("isvNo", "V1703659196"); // infoId
        String configMode = getValStringRequired("configMode"); // 设置类型
        Integer range = getValInteger("range");
        String mccCode = getValString("mccCode");

        String mchAppId = getValString("appId");
        if (!ObjUtil.isEmpty(mchAppId)) {
            MchAppEntity mchApp = mchAppService.getById(mchAppId);
            range = mchApp.getRange();
            mccCode = mchApp.getMccCode();
        }

        // 商户服务商或者服务商的父ID (用于过滤掉关闭的支付方式)
        String belongAgentNo = null;

        // 是否仅显示 支持进件的支付方式（用作进件使用）
        boolean isOnlyApplymentSupport = false;

        AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());

        belongAgentNo = agentInfo.getAgentNo();

        // 进件模式
        if(RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){
            isOnlyApplymentSupport = true;
        }

        IPage<PayWay> pages = payWayService.queryWayListByRate(ifCode, isvNo, belongAgentNo, isOnlyApplymentSupport, range, mccCode, isvNo);
        return ApiRes.page(pages);
    }



    /** 查询当前已经配置的列表 **/
    @GetMapping(value="/savedMapData")
    public ApiRes savedMapData() {

        String ifCode = getValStringRequired("ifCode"); // ifCode
        String infoId = getValStringRequired("infoId"); // infoId
        String configMode = getValStringRequired("configMode"); // 设置类型
//        String isvNo = getValStringRequired("isvNo"); // 设置类型
        String isvNo = getValStringDefault("isvNo", "V1703659196"); // 设置类型
        Integer range = getValInteger("range");
        String mccCode = getValString("mccCode");

        String mchAppId = getValString("appId");
        if (!ObjUtil.isEmpty(mchAppId)) {
            MchAppEntity mchApp = mchAppService.getById(mchAppId);
            range = mchApp.getRange();
            mccCode = mchApp.getMccCode();
        }

        // 配置商户费率 || 服务商进件模式
        if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode) || RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){
            Map<String,  Map<String, PaywayFee>> result = new HashMap<>();

            String mchNo = "";
            String applyId = "";

            // 进件模式 :  infoId =  applyId_mchNo 的拼接方式。
            if(RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){
                applyId = infoId.split("_")[0];
                mchNo = infoId.split("_")[1];
            } else {
//                MchAppEntity mchAppEntity = mchAppService.getById(infoId);
//                mchNo = mchAppEntity.getMchNo();
                mchNo = infoId;
            }

            Map<String, PaywayFee> mchRateMap = null;
            // 查询已经配置的信息
            if(RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){  // 运营平台进件模式
//                mchRateMap = rateConfigService.queryPaywayFeeMapByApplyment(applyId);
                // 此处费率不从商户信息里面取了
                mchRateMap = rateConfigService.queryPaywayFeeMap(mchNo, CS.SYS_ROLE_TYPE.MCH_APPLYMENT, ifCode, range, mccCode, isvNo);
            }else{
                mchRateMap = rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.MCHRATE, commonGetInfoType(configMode), ifCode, range, mccCode, isvNo);
            }

            MchInfo mchInfo = mchInfoService.getById(mchNo);

            Map<String, PaywayFee> parentDefRate = null;
            // 特约商户
            if(mchInfo.getType() == CS.MCH_TYPE_ISVSUB){

                // 我的费率（商户上级服务商的费率）
                result.put(RateConfig.READONLYPARENTAGENT, rateConfigService.queryPaywayFeeMap(mchInfo.getAgentNo() + "_" + RateConfig.AGENTRATE, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

                // 默认费率
                parentDefRate = rateConfigService.queryPaywayFeeMap(mchInfo.getAgentNo() + "_" + RateConfig.MCHAPPLYDEF, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
                result.put(RateConfig.READONLYPARENTDEFRATE, parentDefRate);
            }

            // 商户费率为空时，将默认费率设置为商户费率
            if (ObjUtil.isEmpty(mchRateMap)) {
                mchRateMap = parentDefRate;
            }

            PaywayFee.resetData(mchRateMap, parentDefRate);

            result.put(RateConfig.MCHRATE, mchRateMap);
            // 默认商户最大费率
            result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(getCurrentAgentNo() + "_" + RateConfig.MCHAPPLYMAX, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

            return ApiRes.ok(result);
        }

        // 配置子服务商的费率
        else if(RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode) ){
            Map<String, Object> result = new HashMap<>();

            Map<String, PaywayFee> agentRate = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(infoId), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
            // 查询已经配置的信息
            result.put(RateConfig.AGENTRATE, agentRate);

            AgentInfo agentInfo = agentInfoService.getById(infoId);
            Map<String, PaywayFee> parentDefRate = null;
            if (agentInfo.getPid() == null) {
                parentDefRate = rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.AGENTDEF, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
            }

            if (parentDefRate == null) {
                parentDefRate = rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.AGENTDEF, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);
            }

            Map<String, PaywayFee> mchFeeMax = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(infoId), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
            Map<String, PaywayFee> isvMchFeeMax = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(isvNo), CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);

            for (Map.Entry<String, PaywayFee> isvMchFeeMaxItem : isvMchFeeMax.entrySet()) {
                String wayCode = isvMchFeeMaxItem.getKey();
                PaywayFee item = isvMchFeeMaxItem.getValue();
                if (mchFeeMax.get(wayCode) == null) {
                    // 为空传递空值
                    mchFeeMax.put(wayCode, PaywayFee.toEmptyData(item));
                }
            }

            result.put(RateConfig.MCHAPPLYMAX, mchFeeMax);

            // 我的费率（商户上级服务商的费率）
            result.put(RateConfig.READONLYPARENTAGENT, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

            // 默认费率
            result.put(RateConfig.READONLYPARENTDEFRATE, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

            // 商户最大费率
            result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

            PaywayFee.resetData(agentRate, baseConverter.newPaywayFeeMap(parentDefRate));

            return ApiRes.ok(result);

        }// 配置服务商自己的配置
        else if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode) ){
            Map<String, Object> result = new HashMap<>();

            // 当前服务商的费率配置信息
            result.put(RateConfig.AGENTRATE, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
            // 用于显示代理的费率信息（兼容前端）
            result.put(RateConfig.READONLYPARENTAGENT, result.get(RateConfig.AGENTRATE));

            // 商户默认费率
            result.put(RateConfig.MCHAPPLYDEF, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchDef(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

            // 服务商默认费率
            result.put(RateConfig.AGENTDEF, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

            // 商户最大费率
            result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));

            return ApiRes.ok(result);
        }

        return ApiRes.ok();
    }

    /** 保存费率信息 **/
    @MethodLog(remark = "配置费率")
    @PostMapping(value="")
    public ApiRes reset() {

        // 需要删除的集合， 比如：  配置渠道商底价， 关闭了某些渠道， 那么需要将下属的配置删除掉。
        List<RateConfig> delList = new ArrayList<>();

        String configMode = getValStringRequired("configMode");

        // 主对象
        RateConfig mainRateConfig = getObject(RateConfig.class);

        mainRateConfig.setInfoType(commonGetInfoType(configMode)); // 必须设置infoType, 检查费率会使用

        // 当前服务商的配置信息
        if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)){
            mainRateConfig.setInfoId(getCurrentAgentNo());
        }

        List<RateConfig> list = new ArrayList<>();

        // 服务商默认费率 infoId = ISVNO_AGENTDEF  infoType = 1(服务商)
        if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.AGENTDEF))){
            JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTDEF), PaywayFee.class)
                    .forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTDEF, configMode)));
        }

        // 商户默认费率 infoId = ISVNO_MCHAPPLYDEF   infoType = 1(服务商)
        if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.MCHAPPLYDEF))){
            JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHAPPLYDEF), PaywayFee.class)
                    .forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHAPPLYDEF, configMode)));
        }

        // 商户费率
        if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.MCHRATE))){
            JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHRATE), PaywayFee.class)
                    .forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHRATE, configMode)));
        }

        // 服务商费率
        if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.AGENTRATE))){
            JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTRATE), PaywayFee.class)
                    .forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTRATE, configMode)));

            // 配置 服务商 需要删除 下属配置。
            delList = this.genDelRateConfigList(null, mainRateConfig.getInfoId(), mainRateConfig.getIfCode());
        }

        // 服务商最大费率 infoId = ISVNO_AGENTMAX  infoType = 1(服务商)
        if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.AGENTMAX))) {
            JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTMAX), PaywayFee.class)
                    .forEach(r -> list.add( getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTMAX, configMode)));
        }

        // 商户最大费率 infoId = ISVNO_MCHAPPLYMAX  infoType = 1(服务商)
        if (configMode.equalsIgnoreCase(RateConfig.CONFIG_MODE_AGENTSELF)
            || configMode.equalsIgnoreCase(RateConfig.CONFIG_MODE_AGENTEMCH)) {
            // 配置代理费率和商户费率时，删除最大费率值
            mainRateConfig.getExt().remove(RateConfig.MCHAPPLYMAX);
        }

        if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.MCHAPPLYMAX))) {
            JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHAPPLYMAX), PaywayFee.class)
                    .forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHAPPLYMAX, configMode)));
        }

        LambdaQueryWrapper<RateConfig> delWrapper = RateConfig.gw();
        delWrapper.eq(RateConfig::getIfCode, mainRateConfig.getIfCode());
        delWrapper.eq(RateConfig::getInfoType, commonGetInfoType(configMode));
        delWrapper.eq(mainRateConfig.getRange()!= null, RateConfig::getRange, mainRateConfig.getRange());
        delWrapper.eq(!ObjUtil.isEmpty(mainRateConfig.getMccCode()), RateConfig::getMccCode, mainRateConfig.getMccCode());
        delWrapper.in(RateConfig::getInfoId, commonGetInfoId(configMode, mainRateConfig.getInfoId()));

        rateConfigService.resetRate(list, delWrapper, mainRateConfig, false, delList);
        return ApiRes.ok();
    }


    private RateConfig getFillInfoIdAndType(RateConfig mainRateConfig, PaywayFee paywayFee, String infoSuffix, String configMode){

        RateConfig result = new RateConfig();
        result.setInfoId(mainRateConfig.getInfoId() + "_" + infoSuffix);
        result.setIfCode(mainRateConfig.getIfCode());
        result.setMccCode(mainRateConfig.getMccCode());
        result.setRange(mainRateConfig.getRange());
        result.setIsvNo(mainRateConfig.getIsvNo());
        result.setWayCode(paywayFee.getWayCode());
        result.setFeeType(paywayFee.getFeeType());
        result.setFeeRate(paywayFee.getFeeRate());
        result.setApplymentSupport(paywayFee.getApplymentSupport());
        result.setPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFee));
        result.setInfoType(commonGetInfoType(configMode));


        return result;
    }



    private String commonGetInfoType(String configMode){

        //设置服务商信息
        if(RateConfig.CONFIG_MODE_MGRISV.equals(configMode)){

            return CS.SYS_ROLE_TYPE.ISV;

        }else if(RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)){

            return CS.SYS_ROLE_TYPE.AGENT;

        }else if(RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)){

            return CS.SYS_ROLE_TYPE.MCH_APP;

        }else if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)){

            return CS.SYS_ROLE_TYPE.AGENT;

        }else if(RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)){

            return CS.SYS_ROLE_TYPE.AGENT;

        }else if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)){

            return CS.SYS_ROLE_TYPE.MCH_APP;

        }

        return "";
    }

    private List<String> commonGetInfoId(String configMode, String infoId){

        //设置服务商信息
        if(RateConfig.CONFIG_MODE_MGRISV.equals(configMode)){

            return Arrays.asList(
                    (infoId + "_" + RateConfig.ISVCOST),
                    (infoId + "_" + RateConfig.AGENTDEF),
                    (infoId + "_" + RateConfig.AGENTMAX),
                    (infoId + "_" + RateConfig.MCHAPPLYDEF),
                    (infoId + "_" + RateConfig.MCHAPPLYMAX)
            );

        }else if(RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)){

            return Arrays.asList(
                    (infoId + "_" + RateConfig.AGENTRATE),
                    (infoId + "_" + RateConfig.AGENTDEF),
                    (infoId + "_" + RateConfig.AGENTMAX),
                    (infoId + "_" + RateConfig.MCHAPPLYDEF),
                    (infoId + "_" + RateConfig.MCHAPPLYMAX)
            );

        }else if(RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)){

            return Collections.singletonList(
                    (infoId + "_" + RateConfig.MCHRATE)
            );

        }else if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)){

            return Arrays.asList(
                    (infoId + "_" + RateConfig.AGENTDEF),
                    (infoId + "_" + RateConfig.MCHAPPLYDEF),
                    (infoId + "_" + RateConfig.MCHAPPLYMAX)
            );

        }else if(RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)){

            return Arrays.asList(
                    (infoId + "_" + RateConfig.AGENTRATE),
                    (infoId + "_" + RateConfig.MCHAPPLYMAX)
            );

        }else if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)){

            return Collections.singletonList(
                    (infoId + "_" + RateConfig.MCHRATE)
            );

        }

        return new ArrayList<>();
    }


    /**
     获取待删除的列表集合  info_id/ info_type  if_code  way_code

     以下三个场景需要判断：
     渠道商底价
     运营平台 --》 设置服务商费率
     服务商 配置 下级服务商费率 (服务商)
     **/
    private List<RateConfig> genDelRateConfigList(String isvNo, String agentNo, String ifCode){

        String delPaywayCodeListStr = getValString("delPaywayCodeListStr");
        if(StringUtils.isEmpty(delPaywayCodeListStr)){
            return null;
        }

        List<String> delWayCodeList = JSON.parseArray(delPaywayCodeListStr, String.class);

        // 没有待删除的列表
        if(delWayCodeList.isEmpty()){
            return null;
        }

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


        Set<String> allAgentNoList = new HashSet<>();
        Set<String> allMchNoList = new HashSet<>();
        Set<String> allAppIdList = new HashSet<>();


        // 服务商不为空
        if(StringUtils.isNotEmpty(isvNo)){


            // 判断是否支持服务商
            if(SysConfigService.IS_HAS_AGENT_ENT){

                // 查询所有的服务商列表 ( 一级服务商 )
                agentInfoService.list(AgentInfo.gw().select(AgentInfo::getAgentNo).eq(AgentInfo::getIsvNo, isvNo)).forEach(r -> allAgentNoList.add(r.getAgentNo()));

            }

            // 查询所有的商户列表  [ 无需查询服务商的所属了， 已经是全部服务商下的商户了。  ]
            mchInfoService.lambdaQuery().select(MchInfo::getMchNo).list().forEach(r -> allMchNoList.add(r.getMchNo()));

            // 查询下级服务商的 子服务商【递归】
            for (String agentNoItem : allAgentNoList) {
                allAgentNoList.addAll(agentInfoService.queryAllSubAgentNo(agentNoItem));
            }

            // 查询下级服务商【递归】的商户

        }

        // 服务商不为空
        if(StringUtils.isNotEmpty(agentNo)){

            // 查询所有的服务商列表 （ 当前服务商的 直属 服务商  ）
            agentInfoService.lambdaQuery().select(AgentInfo::getAgentNo).eq(AgentInfo::getPid, agentNo).list().forEach(r -> allAgentNoList.add(r.getAgentNo()));

            // 查询所有的商户列表  （ 当前服务商的 直属 商户  ） 【 当前服务商的所属商户 】
            mchInfoService.lambdaQuery().select(MchInfo::getMchNo).eq(MchInfo::getAgentNo, agentNo).list().forEach(r -> allMchNoList.add(r.getMchNo()));

            // 查询下级服务商的 子服务商【递归】
            for (String agentNoItem : allAgentNoList) {
                allAgentNoList.addAll(agentInfoService.queryAllSubAgentNo(agentNoItem));
            }

            // 查询下级服务商 所属的商户集合
            for (String agentNoItem : allAgentNoList) {
                mchInfoService.lambdaQuery().select(MchInfo::getMchNo).eq(MchInfo::getAgentNo, agentNoItem)
                        .list().forEach(r -> allMchNoList.add(r.getMchNo()));
            }

        }

        if(!allMchNoList.isEmpty()){

            // 查询所有的商户列表
            mchAppService.lambdaQuery().select(MchAppEntity::getMchNo).in(MchAppEntity::getMchNo, allMchNoList)
                    .list().forEach(r -> allAppIdList.add(r.getAppId()));
        }


        // 服务商：  包括 服务商配置， 下级服务商默认、  服务商商户默认
        for (String agentNoItem : allAgentNoList) {
            for (String wayCode : delWayCodeList) {

                RateConfig r = new RateConfig();
                r.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.AGENTRATE)); r.setInfoType(CS.SYS_ROLE_TYPE.AGENT); r.setIfCode(ifCode); r.setWayCode(wayCode);
                result.add(r);

                RateConfig r1 = new RateConfig();
                r1.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.AGENTDEF)); r1.setInfoType(CS.SYS_ROLE_TYPE.AGENT); r1.setIfCode(ifCode); r1.setWayCode(wayCode);
                result.add(r1);

                RateConfig r2 = new RateConfig();
                r2.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.MCHAPPLYDEF)); r2.setInfoType(CS.SYS_ROLE_TYPE.AGENT); r2.setIfCode(ifCode); r2.setWayCode(wayCode);
                result.add(r2);
            }
        }


        // 商户：  包括 商户应用费率
        for (String appIdItem : allAppIdList) {
            for (String wayCode : delWayCodeList) {

                RateConfig r = new RateConfig();
                r.setInfoId(RateConfig.buildInfoId(appIdItem, RateConfig.MCHRATE)); r.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP); r.setIfCode(ifCode); r.setWayCode(wayCode);
                result.add(r);
            }
        }

        return result;
    }

    @GetMapping("/rateInfoDetail")
    public ApiRes rateInfoDetail() {
        String isvNo = getValStringRequired("isvNo");
        String ifCode = getValStringRequired("ifCode");
        Integer range = getValInteger("range");
        String mccCode = getValString("mccCode");
        String infoType = getValStringRequired("infoType");
        String infoId = getValStringRequired("infoId");

        String currentAgentNo = getCurrentAgentNo();

        List<RateConfigSimple> result = rateConfigV2Service.getRankFeeList(isvNo, infoType, infoId, ifCode, range, mccCode, currentAgentNo);

        return ApiRes.ok(result);
    }

    @PostMapping("/resetV2")
    public ApiRes resetV2() {
        String currentAgentNo = getCurrentAgentNo();

        RateConfigSimple rateConfigSimple = getObject(RateConfigSimple.class);

        if (rateConfigSimple.getInfoType().equalsIgnoreCase(CS.SYS_ROLE_TYPE.AGENT)) {
            AgentInfo agentInfo = agentInfoService.getById(rateConfigSimple.getInfoId());
            Assert.equals(agentInfo.getPid(), currentAgentNo, "所操作的服务商与登录账号非上下级关系");
        } else if (rateConfigSimple.getInfoType().equalsIgnoreCase(CS.SYS_ROLE_TYPE.MCH)) {
            MchInfo mchInfo = mchInfoService.getById(rateConfigSimple.getInfoId());
            Assert.equals(mchInfo.getAgentNo(), currentAgentNo, "所操作的用户与登录账号非上下级关系");
        } else {
            throw new BizException("未知的操作类型");
        }

        rateConfigV2Service.save(rateConfigSimple);

        return ApiRes.ok();
    }
}
