package com.jeequan.jeepay.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.PayInterfaceDefine;
import com.jeequan.jeepay.db.entity.PayWay;
import com.jeequan.jeepay.db.entity.RateConfig;
import com.jeequan.jeepay.db.entity.TransferInterfaceDefineEntity;
import com.jeequan.jeepay.service.mapper.PayWayMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;

/**
 * <p>
 * 支付方式表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2021-04-27
 */
@Service
public class PayWayService extends ServiceImpl<PayWayMapper, PayWay> {

    static class NotFoundPayIfCodeException extends RuntimeException {}

    @Autowired
    private PayInterfaceDefineService payInterfaceDefineService;
    @Autowired
    private RateConfigService rateConfigService;
    @Autowired
    private AgentInfoService agentInfoService;

    @Autowired
    private TransferInterfaceDefineService transferInterfaceDefineService;

    /**
     * 用于费率配置显示时的支付方式查询
     **/
    public IPage<PayWay> queryWayListByRate(String ifCode, String belongIsvNo, String belongAgentNo, boolean isOnlyApplymentSupport, Integer range, String mccCode, String isvNo) {
        try {
            return queryPayWayListByRate(ifCode, belongIsvNo, belongAgentNo, isOnlyApplymentSupport, range, mccCode, isvNo);
        } catch (NotFoundPayIfCodeException e) {
            return queryTransferWayListByRate(ifCode, belongIsvNo, belongAgentNo, isvNo);
        }
    }

    public IPage<PayWay> queryPayWayListByRate(String ifCode, String belongIsvNo, String belongAgentNo, boolean isOnlyApplymentSupport, Integer range, String mccCode, String isvNo) {

        // 需要查询的所有的支付方式
        Set<String> allWayCodes = new HashSet<>();

        // 查询支付接口 支持的支付方式
        PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
        if (payInterfaceDefine == null) {
            throw new NotFoundPayIfCodeException();
        }

        if (CollUtil.isEmpty(payInterfaceDefine.getWayCodes())) {
            return new Page<>(); //无任何产品
        }

        // 支付接口支持的所有的支付方式
        for (Object wayCodeObject : payInterfaceDefine.getWayCodes()) {
            allWayCodes.add(((JSONObject) wayCodeObject).getString("wayCode"));
        }

        // 服务商的配置信息
        Map<String, PaywayFee> isvPaywayFeeMap = new HashMap<>();

        // 查询服务商所有的配置
        if (StringUtils.isNotEmpty(belongIsvNo)) {

            Map<String, PaywayFee> map = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByIsvCost(belongIsvNo), CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);
            Assert.notEmpty(map, "当前渠道下的支付通道[" + ifCode + "]费率暂未配置, 请联系运营完成费率配置");
            for (PaywayFee paywayFeeItem : map.values()) {

                // 如果只显示进件支持的 && 当前不支持进件
                if (isOnlyApplymentSupport && paywayFeeItem.getApplymentSupport() != CS.YES) {
                    continue;
                }

                // 清空信息
                PaywayFee paywayFee = new PaywayFee();
                paywayFee.setApplymentSupport(paywayFeeItem.getApplymentSupport());
                paywayFee.setFeeType(paywayFeeItem.getFeeType());
                if (PaywayFee.FEE_TYPE_LEVEL.equals(paywayFeeItem.getFeeType()) && paywayFeeItem.getLevelList() != null) { // 阶梯费率
                    for (PaywayFee fee : paywayFeeItem.getLevelList()) {
                        fee.setFeeRate(null);
                    }
                    paywayFee.setLevelList(paywayFeeItem.getLevelList());
                }

                if (paywayFeeItem.getCreditCardPaywayFee() != null && paywayFeeItem.getLevelList() != null) {
                    for (PaywayFee fee : paywayFeeItem.getCreditCardPaywayFee().getLevelList()) {
                        fee.setFeeRate(null);
                    }
                    paywayFee.setCreditCardPaywayFee(paywayFeeItem.getCreditCardPaywayFee());
                }

                isvPaywayFeeMap.put(paywayFeeItem.getWayCode(), paywayFee);
            }

            // 取两个的交集
            allWayCodes = CollUtil.intersectionDistinct(allWayCodes, isvPaywayFeeMap.keySet());
        } else {
            // 服务商是空： 只有两种清空：  1. 配置服务商的费率， 2.自营商户。
        }

        if (allWayCodes.isEmpty()) {
            return new Page<>(); //无任何产品
        }

        if (StringUtils.isNotEmpty(belongAgentNo)) {

            List<String> agentInfoIds = new ArrayList<>();
            agentInfoService.queryAllParentAgentNo(belongAgentNo).forEach(a -> agentInfoIds.add(RateConfig.appendInfoByAgent(a)));

            // 查询全部的服务商费率 ( 不可通过 agentInfoIds 需要查询每一个， 然后取到 交集 )
            for (String agentInfoId : agentInfoIds) {
                Set<String> agentWayCodes = rateConfigService.getAllWayCodesByInfoId(ifCode, agentInfoId, CS.SYS_ROLE_TYPE.AGENT, isvNo);
                allWayCodes = CollUtil.intersectionDistinct(allWayCodes, agentWayCodes);
            }
        }

        if (allWayCodes.isEmpty()) {
            return new Page<>(); //无任何产品
        }


        LambdaQueryWrapper<PayWay> condition = PayWay.gw();
        condition.orderByAsc(PayWay::getWayCode);
        condition.in(PayWay::getWayCode, allWayCodes);

        List<PayWay> result = list(condition);
        for (PayWay payWay : result) {

            // 添加服务商的配置参数（包含是否支持进件， 费率模式等） [ 固定格式： 不支持更改 ]
            payWay.addExt("fixConfig", isvPaywayFeeMap.get(payWay.getWayCode()));
        }

        // 构造分页
        return new Page<PayWay>().setRecords(result).setTotal(result.size());
    }

    public IPage<PayWay> queryTransferWayListByRate(String ifCode, String belongIsvNo, String belongAgentNo, String isvNo) {

        // 需要查询的所有的支付方式
        Set<String> allWayCodes = new HashSet<>();

        // 查询支付接口 支持的支付方式
        TransferInterfaceDefineEntity transferInterfaceDefine = transferInterfaceDefineService.getByCode(ifCode);
        if (transferInterfaceDefine == null) {
            throw new BizException("未定义的【ifCode】");
        }

        if (CollUtil.isEmpty(transferInterfaceDefine.getWayCodes())) {
            return new Page<>(); //无任何产品
        }

        // 支付接口支持的所有的支付方式
        for (Object wayCodeObject : transferInterfaceDefine.getWayCodes()) {
            allWayCodes.add(((JSONObject) wayCodeObject).getString("wayCode"));
        }

        // 服务商的配置信息
        Map<String, PaywayFee> isvPaywayFeeMap = new HashMap<>();

        // 查询服务商所有的配置
        if (StringUtils.isNotEmpty(belongIsvNo)) {

            Map<String, PaywayFee> map = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByIsvCost(belongIsvNo), CS.SYS_ROLE_TYPE.ISV, ifCode, null, null, isvNo);
            Assert.notEmpty(map, "当前渠道下的代付通道[" + ifCode + "]费率暂未配置, 请联系运营完成费率配置");
            for (PaywayFee paywayFeeItem : map.values()) {
                // 清空信息
                PaywayFee paywayFee = new PaywayFee();
                paywayFee.setApplymentSupport(paywayFeeItem.getApplymentSupport());
                paywayFee.setFeeType(paywayFeeItem.getFeeType());
                if (PaywayFee.FEE_TYPE_LEVEL.equals(paywayFeeItem.getFeeType()) && paywayFeeItem.getLevelList() != null) { // 阶梯费率
                    for (PaywayFee fee : paywayFeeItem.getLevelList()) {
                        fee.setFeeRate(null);
                    }
                    paywayFee.setLevelList(paywayFeeItem.getLevelList());
                }

                if (paywayFeeItem.getCreditCardPaywayFee() != null && paywayFeeItem.getLevelList() != null) {
                    for (PaywayFee fee : paywayFeeItem.getCreditCardPaywayFee().getLevelList()) {
                        fee.setFeeRate(null);
                    }
                    paywayFee.setCreditCardPaywayFee(paywayFeeItem.getCreditCardPaywayFee());
                }

                isvPaywayFeeMap.put(paywayFeeItem.getWayCode(), paywayFee);
            }

            // 取两个的交集
            allWayCodes = CollUtil.intersectionDistinct(allWayCodes, isvPaywayFeeMap.keySet());
        } else {
            // 服务商是空： 只有两种清空：  1. 配置服务商的费率， 2.自营商户。
        }

        if (allWayCodes.isEmpty()) {
            return new Page<>(); //无任何产品
        }

        if (StringUtils.isNotEmpty(belongAgentNo)) {

            List<String> agentInfoIds = new ArrayList<>();
            agentInfoService.queryAllParentAgentNo(belongAgentNo).forEach(a -> agentInfoIds.add(RateConfig.appendInfoByAgent(a)));

            // 查询全部的服务商费率 ( 不可通过 agentInfoIds 需要查询每一个， 然后取到 交集 )
            for (String agentInfoId : agentInfoIds) {
                Set<String> agentWayCodes = rateConfigService.getAllWayCodesByInfoId(ifCode, agentInfoId, CS.SYS_ROLE_TYPE.AGENT, isvNo);
                allWayCodes = CollUtil.intersectionDistinct(allWayCodes, agentWayCodes);
            }
        }

        if (allWayCodes.isEmpty()) {
            return new Page<>(); //无任何产品
        }

        LambdaQueryWrapper<PayWay> condition = PayWay.gw();
        condition.orderByAsc(PayWay::getWayCode);
        condition.in(PayWay::getWayCode, allWayCodes);

        List<PayWay> result = list(condition);
        for (PayWay payWay : result) {

            // 添加服务商的配置参数（包含是否支持进件， 费率模式等） [ 固定格式： 不支持更改 ]
            payWay.addExt("fixConfig", isvPaywayFeeMap.get(payWay.getWayCode()));
        }

        // 构造分页
        return new Page<PayWay>().setRecords(result).setTotal(result.size());
    }
}
