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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
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.params.NormalMchParams;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mch.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/***
 * 支付配置
 *
 * @author terrfly
 *
 * @date 2022/3/21 0:13
 */
@RestController
@RequestMapping("/api/payConfig")
public class PayConfigController extends CommonCtrl {

    @Autowired
    private MchInfoService mchInfoService;
    @Autowired
    private MchAppService mchAppService;
    @Autowired
    private PayInterfaceDefineService payInterfaceDefineService;
    @Autowired
    private PayInterfaceConfigService payInterfaceConfigService;
    @Autowired
    private RateConfigService rateConfigService;
    @Autowired
    private IMQSender mqSender;
    @Autowired
    private IsvUserConnService isvUserConnService;


    /**
     * 查询可用的支付接口
     * <p>
     * 使用功能项目：  参数及费率的填写
     * 服务商查询全部支付接口
     * 服务商查询服务商开启的支付接口
     **/
    @PreAuthorize("hasAnyAuthority( 'ENT_MCH_APP_PAY_CONFIG', 'ENT_MCH_APPLYMENT' )")
    @GetMapping("/ifCodes")
    public ApiRes ifCodes() {

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

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

        Integer range = getValInteger("range");
        String mccCode = getValString("mccCode");

        // 支付接口列表
        LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(PayInterfaceDefine::getState, CS.YES); // 查询可用的支付接口列表
        lambdaQueryWrapper.like(StringUtils.isNotEmpty(ifName), PayInterfaceDefine::getIfName, ifName);



        String infoType = CS.SYS_ROLE_TYPE.MCH_APP;

        MchInfo mchInfo = mchInfoService.getById(getCurrentMchNo());
        if (mchInfo.getType() == CS.MCH_TYPE_ISVSUB) {

            // 商户进件模式
            if (RateConfig.CONFIG_MODE_MCHAPPLYMENT.equals(configMode)) {

                // 查询 服务商 or  服务商开通的支付接口

                lambdaQueryWrapper.eq(PayInterfaceDefine::getIsSupportApplyment, CS.YES); // 查询可用的支付接口列表
                lambdaQueryWrapper.eq(PayInterfaceDefine::getIsOpenApplyment, CS.YES); // 查询 开启的

                Set<String> ifCodes = new HashSet<>();

                // 获取关联的渠道信息
                // 获取关联的渠道信息
                List<String> isvList = isvUserConnService.lambdaQuery()
                        .eq(IsvUserConnEntity::getInfoType, CS.SYS_ROLE_TYPE.MCH)
                        .eq(IsvUserConnEntity::getStatus, CS.YES)
                        .eq(IsvUserConnEntity::getInfoId, mchInfo.getMchNo())
                        .list()
                        .stream().map(IsvUserConnEntity::getIsvNo).collect(Collectors.toList());

                if (isvList.isEmpty()) {
                    return ApiRes.ok(new ArrayList<>());
                }

                // 根据渠道号获取ifCode
                QueryWrapper<PayInterfaceConfig> query = Wrappers.query();
                // 去重
                query.select("DISTINCT")
                        .lambda()
                        .select(PayInterfaceConfig::getIfCode)
                        .eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
                        .in(PayInterfaceConfig::getInfoId, isvList)
                        .eq(PayInterfaceConfig::getState, CS.YES)
                        .eq(PayInterfaceConfig::getIsOpenApplyment, CS.YES);

                payInterfaceConfigService.list(query).forEach(r -> ifCodes.add(r.getIfCode()));

                if (ifCodes.isEmpty()) {
                    return ApiRes.ok(new ArrayList<>());
                }

                lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodes); // 查询可用的支付接口列表

            } else {  // 特约商户无需配置

                return ApiRes.ok(new ArrayList<>());
            }
        } else {

            // 普通商户
            lambdaQueryWrapper.eq(PayInterfaceDefine::getIsMchMode, CS.YES); //支持普通商户模式
        }

        lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
        List<PayInterfaceDefine> list = payInterfaceDefineService.list(lambdaQueryWrapper);

        if (list.isEmpty()) {
            return ApiRes.ok(list);
        }


        Map<String, Byte> stateMap = new HashMap<>();
        payInterfaceConfigService.lambdaQuery().select(PayInterfaceConfig::getIfCode, PayInterfaceConfig::getState)
                .eq(PayInterfaceConfig::getInfoId, infoId)
                .eq(PayInterfaceConfig::getInfoType, infoType)
                .list().forEach(r -> stateMap.put(r.getIfCode(), r.getState()));

        list.forEach(r -> {
            // 是否已配置
            if (RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)) { // 服务商查询的就是已经配置的接口，无需填入
                r.addExt("configState", stateMap.get(r.getIfCode()));
            } else {
                r.addExt("configState", ObjectUtil.defaultIfNull(stateMap.get(r.getIfCode()), 1));
            }
            //返回json数据
            if (StringUtils.isNotEmpty(r.getChannelTypes())){
                try {
                    JSONArray jsonObject = JSON.parseArray("[" + r.getChannelTypes() + "]");
                    r.setJsonChannelTypes(jsonObject);
                }catch (Exception e){
                    r.setJsonChannelTypes(new JSONArray());
                }
            }
        });

        return ApiRes.ok(list);
    }


    /**
     * 查询已经配置的参数信息
     **/
    @GetMapping(value = "/interfaceSavedConfigs")
    public ApiRes interfaceSavedConfigs() {

        MchInfo mchInfoSelf = mchInfoService.getById(getCurrentMchNo());
        if (mchInfoSelf.getType() == CS.MCH_TYPE_ISVSUB) {
            throw new BizException("特约商户，无需配置");
        }

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

        PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);

        String infoType = null;
        JSONArray ifDefineArray = null;

        Byte mchType = CS.MCH_TYPE_NORMAL; // 商户类型

        // 配置商户应用信息
        if (RateConfig.CONFIG_MODE_MCHSELFAPP1.equals(configMode)) {
            infoType = CS.SYS_ROLE_TYPE.MCH_APP;
            ifDefineArray = JSONArray.parseArray(payInterfaceDefine.getNormalMchParams());
        }

        // 查询已经配置的信息
        PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(infoType, infoId, ifCode);

        if (payInterfaceConfig == null) {
            payInterfaceConfig = new PayInterfaceConfig();
        }

        // 处理脱敏数据
        if (StringUtils.isNotEmpty(payInterfaceConfig.getIfParams())) {

            NormalMchParams isvParams = NormalMchParams.factory(ifCode, payInterfaceConfig.getIfParams());
            if (isvParams != null) {
                payInterfaceConfig.setIfParams(isvParams.deSenData());
            }
        }

        payInterfaceConfig.addExt("ifDefineArray", ifDefineArray);
        payInterfaceConfig.addExt("mchType", mchType);
        payInterfaceConfig.addExt("configPageType", payInterfaceDefine.getConfigPageType());
        return ApiRes.ok(payInterfaceConfig);
    }


    /**
     * 更新支付参数
     **/
    @PostMapping("/interfaceParams")
    @MethodLog(remark = "更新支付参数")
    public ApiRes saveOrUpdate() {

        MchInfo mchInfoSelf = mchInfoService.getById(getCurrentMchNo());
        if (mchInfoSelf.getType() == CS.MCH_TYPE_ISVSUB) {
            throw new BizException("特约商户，无需配置");
        }

        PayInterfaceConfig payInterfaceConfig = getObject(PayInterfaceConfig.class);

        String configMode = payInterfaceConfig.extv().getString("configMode");  // 设置类型

        String infoType = CS.SYS_ROLE_TYPE.MCH_APP;


        payInterfaceConfig.setInfoType(infoType);

        //添加更新者信息
        Long userId = getCurrentUser().getSysUser().getSysUserId();
        String realName = getCurrentUser().getSysUser().getRealname();
        payInterfaceConfig.setUpdatedUid(userId);
        payInterfaceConfig.setUpdatedBy(realName);

        //根据 服务商号、接口类型 获取商户参数配置
        PayInterfaceConfig dbRecoed = payInterfaceConfigService.getByInfoIdAndIfCode(payInterfaceConfig.getInfoType(), payInterfaceConfig.getInfoId(), payInterfaceConfig.getIfCode());
        //若配置存在，为saveOrUpdate添加ID，第一次配置添加创建者
        if (dbRecoed != null) {
            payInterfaceConfig.setId(dbRecoed.getId());

            // 合并支付参数
            payInterfaceConfig.setIfParams(StringKit.marge(dbRecoed.getIfParams(), payInterfaceConfig.getIfParams(), dbRecoed.getIfCode()));
        } else {
            payInterfaceConfig.setCreatedUid(userId);
            payInterfaceConfig.setCreatedBy(realName);
        }

        boolean result = payInterfaceConfigService.saveOrUpdate(payInterfaceConfig);
        if (!result) {
            return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "配置失败");
        }

        return ApiRes.ok();
    }


    @GetMapping("/existPayParams/{appId}/{ifCode}")
    public ApiRes existPayParams(@PathVariable("appId") String appId, @PathVariable("ifCode") String ifCode) {

//        RateConfig param = getObject(RateConfig.class);
//
//        // 应用参数配置
//        PayInterfaceConfig interfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.MCH_APP, appId, ifCode);
//        if (interfaceConfig == null) {
//            return ApiRes.ok();
//        }
//
//        if (StringUtils.isNotBlank(interfaceConfig.getIfParams()) && !interfaceConfig.getIfParams().equals("{}")) {
//            return ApiRes.ok(JsonKit.newJson("existMchParams", CS.YES));
//        }
//
//        // 费率配置
//        Map<String, PaywayFee> paywayFeeMap = rateConfigService.queryPaywayFeeMap(appId + "_" + RateConfig.MCHRATE, CS.SYS_ROLE_TYPE.MCH_APP, param.getIfCode(), param.getRange(), param.getMccCode(), param.getIsvNo());
//        if (paywayFeeMap != null && StringUtils.isNotBlank(interfaceConfig.getIfParams()) && !interfaceConfig.getIfParams().equals("{}")) {
//            return ApiRes.ok(JsonKit.newJson("existMchParams", CS.YES));
//        }

        return ApiRes.ok();
    }
}
