package com.jeequan.jeepay.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.DesensitizedUtil;
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.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.converter.MchInfoConverter;
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.interfaces.paychannel.IIsvmchWxConfigService;
import com.jeequan.jeepay.core.interfaces.paychannel.IMchApiService;
import com.jeequan.jeepay.core.model.applyment.ApplymentBasicInfo;
import com.jeequan.jeepay.core.model.applyment.AutoConfigMchAppPayInfoResult;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.model.oauth2.Oauth2Params;
import com.jeequan.jeepay.core.model.oauth2.WxpayOauth2Params;
import com.jeequan.jeepay.core.model.rqrs.mch.ChannelMchRq;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.vo.MchThirdParamResult;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.mapper.MchAppMapper;
import com.jeequan.jeepay.service.mapper.MchApplymentMapper;
import com.jeequan.jeepay.service.mapper.MchModifyApplymentMapper;
import com.jeequan.jeepay.service.mapper.MchThirdConfigMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 特约商户进件信息表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2021-12-28
 */
@Slf4j
@Service
public class MchApplymentService extends ServiceImpl<MchApplymentMapper, MchApplyment> {

    @Autowired
    private PayInterfaceConfigService payInterfaceConfigService;
    @Autowired
    private RateConfigService rateConfigService;
    @Autowired
    private MchPayPassageService mchPayPassageService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private MchAppMapper mchAppMapper;
    @Autowired
    private MchStoreService mchStoreService;
    @Autowired
    private MchThirdConfigMapper mchThirdConfigMapper;

    @Autowired
    private MchConfigService mchConfigService;

    @Autowired
    private MchApplymentMapper mchApplymentMapper;

    @Autowired
    private MchModifyApplymentMapper mchModifyApplymentMapper;

    @Autowired
    private MchInfoConverter mchInfoConverter;

    @Autowired
    private MchSubInfoService mchSubInfoService;

    @Autowired
    private MchAppService mchAppService;

    @Autowired
    private MchQrcodeCardService mchQrcodeCardService;

    @Autowired
    private MchQrcShellService mchQrcShellService;

    @Autowired
    private PayInterfaceDefineService payInterfaceDefineService;

    public MchApplyment getByChannelMchNo(String channelMchNo) {
        LambdaQueryWrapper<MchApplyment> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(MchApplyment::getChannelMchNo, channelMchNo);

        return getOne(queryWrapper);
    }

    public MchApplyment getBySubApplyId(String subApplyId) {
        return lambdaQuery()
                .eq(MchApplyment::getSubApplyId, subApplyId)
                .one();
    }



    public MchApplyment getByMchNoAndAppId(String mchNo,String appId){
        return lambdaQuery().eq(MchApplyment::getMchNo,mchNo).eq(MchApplyment::getAutoConfigMchAppId,appId).eq(MchApplyment::getState,2).one();
    }

    @Override
    public MchApplyment getById(Serializable id) {
        Assert.notNull(id, "商户号不能为空");

        MchApplyment mchApplyment = super.getById(id);
        if (mchApplyment != null){
            MchAppEntity entity = mchAppService.getById(mchApplyment.getAutoConfigMchAppId());
            mchApplyment.setRange(entity.getRange());
            mchApplyment.setMccCode(entity.getMccCode());
        }
        return mchApplyment;
    }

    /**
     * @param orderId 入网的订单号，默认取ChannelApplyNo字段
     * @return
     */
    public MchApplyment getByOrderId(String orderId) {
        LambdaQueryWrapper<MchApplyment> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(MchApplyment::getChannelApplyNo, orderId);
        qWrapper.last("limit 1");

        return getOne(qWrapper);
    }

    /**
     * @author: xiaoyu
     * @date: 2022/5/19 17:08
     * @describe: 查询进件信息
     */
    public MchApplyment getInfoById(String recordId) {
        MchApplyment applyment = getById(recordId);

        if (applyment == null) {
            return null;
        }

        /** 对非空的联系人信息脱敏 **/

        // 联系人姓名
        applyment.setContactName(DesensitizedUtil.chineseName(applyment.getContactName()));
        // 联系人电话
        applyment.setContactPhone(DesensitizedUtil.mobilePhone(applyment.getContactPhone()));

        /** 解析进件JSON信息 对关键信息进行脱敏 **/
        JSONObject applymentJson = JSON.parseObject(applyment.getApplyDetailInfo());

        /*ApplymentBasicInfo applymentInfo = JSONObject.parseObject(applyment.getApplyDetailInfo(), ApplymentBasicInfo.class);
        DesenKit.desenObject(applymentInfo);*/


        /** 公共进件参数 **/
        // 联系人姓名
        applymentJson.put("contactName", DesensitizedUtil.chineseName(applymentJson.getString("contactName")));
        // 联系人电话
        applymentJson.put("contactPhone", DesensitizedUtil.mobilePhone(applymentJson.getString("contactPhone")));
        // 联系人邮箱
        applymentJson.put("contactEmail", DesensitizedUtil.email(applymentJson.getString("contactEmail")));

        // 身份证姓名
        applymentJson.put("idcardName", DesensitizedUtil.chineseName(applymentJson.getString("idcardName")));

        // 身份证号
        applymentJson.put("idcardNo", DesensitizedUtil.idCardNum(applymentJson.getString("idcardNo"), 3, 4));

        // 结算账号
        applymentJson.put("settAccountNo", DesensitizedUtil.bankCard(applymentJson.getString("settAccountNo")));
        // 结算账号用户名
        applymentJson.put("settAccountName", DesensitizedUtil.chineseName(applymentJson.getString("settAccountName")));

        // 结算非法人身份证号
        applymentJson.put("settAccountIdcardNo", DesensitizedUtil.idCardNum(applymentJson.getString("settAccountIdcardNo"), 3, 4));
        // 结算银行卡账号
        applymentJson.put("companyAccountNo", DesensitizedUtil.bankCard(applymentJson.getString("companyAccountNo")));

        /** 其他单独接口参数 **/

        /** 支付宝 **/
        String accountNo = applymentJson.getString("accountNo");
        // 支付宝账号
        if (!StringUtils.isEmpty(accountNo)) {
            applymentJson.put("accountNo", DesensitizedUtil.bankCard(accountNo));
        }

        /** 通联 **/
        String personTel = applymentJson.getString("persontel");
        // 手机号
        if (!StringUtils.isEmpty(personTel)) {
            applymentJson.put("persontel", DesensitizedUtil.mobilePhone(personTel));
        }
        String servicePhone = applymentJson.getString("servicephone");
        // 客服电话
        if (!StringUtils.isEmpty(servicePhone)) {
            applymentJson.put("servicephone", DesensitizedUtil.mobilePhone(servicePhone));
        }
        String holderName = applymentJson.getString("holdername");
        // 股东姓名
        if (!StringUtils.isEmpty(holderName)) {
            applymentJson.put("holdername", DesensitizedUtil.chineseName(holderName));
        }
        String holderIdNo = applymentJson.getString("holderidno");
        // 股东身份证号
        if (!StringUtils.isEmpty(holderIdNo)) {
            applymentJson.put("holderidno", DesensitizedUtil.idCardNum(holderIdNo, 3, 4));
        }

        applyment.setApplyDetailInfo(applymentJson.toJSONString());
        return applyment;
    }

    /**
     * 进件成功，自动配置应用支付信息
     * 参数：
     * applyId: 进件记录单号
     * appId: 配置应用ID，自动配置时为空(自动配置应用appId取自进件记录)
     * isOverWrite: 一键配置时，是否覆写支付方式已配置的支付通道
     * 规则：
     * 1、支付参数和支付费率将直接配置，若有原有配置也直接覆盖
     * 2、通道配置中，未开启通道的支付方式直接开启当前进件通道；已开启的，isOverWrite为true时，开启当前进件通道，否则忽略
     */
    public AutoConfigMchAppPayInfoResult autoConfigMchAppPayInfo(String applyId, String appId, boolean isOverWrite) {

        String logPrefix = "【进件成功applyId=" + applyId + "，配置应用支付信息】";
        log.info(logPrefix);

        boolean isAutoConfig = StringUtils.isBlank(appId); // true-进件成功自动配置
        String mchAppId = appId;

        // 配置结果
        AutoConfigMchAppPayInfoResult result = AutoConfigMchAppPayInfoResult.initAllStateFail();

        try {
            MchApplyment tbMchApplyment = getById(applyId);
            if (tbMchApplyment == null || tbMchApplyment.getState() != MchApplyment.STATE_SUCCESS) {
                throw new BizException("进件记录不存在或状态未成功");
            }

            // 一、进件成功 && 自动配置应用
            if (isAutoConfig && StringUtils.isBlank(tbMchApplyment.getAutoConfigMchAppId())) {
                throw new BizException("发起进件时未选择自动配置应用");
            }

            // 自动配置的应用AppId
            if (isAutoConfig) {
                mchAppId = tbMchApplyment.getAutoConfigMchAppId();
            }

            if (StringUtils.isBlank(mchAppId)) {
                throw new BizException("未选择应用");
            }

            MchAppEntity mchAppEntity = mchAppMapper.selectById(mchAppId);
            if (mchAppEntity == null || mchAppEntity.getState() != CS.YES) {
                throw new BizException("应用不存在或已停用");
            }

            result.setAppId(mchAppId);
            result.setMchNo(mchAppEntity.getMchNo());
            String ifCode = tbMchApplyment.getIfCode();

            // 二、配置应用支付参数
            updateMchAppPayConfig(logPrefix, tbMchApplyment, mchAppId, ifCode);

            // 应用支付参数配置成功
            result.setParamsState(CS.YES);


            // 获取费率信息
            ApplymentBasicInfo applymentBasicInfo = JSONObject.parseObject(tbMchApplyment.getApplyDetailInfo(), ApplymentBasicInfo.class);
            // 费率
            List<PaywayFee> paywayFeeList = applymentBasicInfo.getPaywayFeeList();
            if (CollUtil.isEmpty(paywayFeeList)) {
                throw new BizException("不存在费率配置，请手动配置");
            }

            // 三、配置费率
            updateMchAppRateConfig(logPrefix, paywayFeeList, mchAppId, ifCode);

            // 费率配置成功
            result.setRateState(CS.YES);

            // 四、通道配置，支付方式取自 费率配置
            updateMchAppPayPassage(logPrefix, paywayFeeList, tbMchApplyment.getMchNo(), mchAppId, ifCode, isOverWrite);

            // 通道配置成功
            result.setPassageState(CS.YES);

            log.info("{}配置成功", logPrefix);


            // 五、进件成功自动配置到应用时，调用渠道配置微信参数接口
            if (isAutoConfig) {
                interfaceWxConfig(tbMchApplyment, mchAppId);
            }

            result.setState(CS.YES);
            return result;

        } catch (Exception e) {
            log.error("进件单号applyId={}，商户应用appId={}，自动配置支付信息异常：{}", applyId, mchAppId, e.getMessage());

            result.setErrMsg(e.getMessage());
            return result;
        }
    }

    private void interfaceWxConfig(MchApplyment tbMchApplyment, String mchAppId) {

        try {
            IIsvmchWxConfigService iIsvmchWxConfigService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(tbMchApplyment.getIfCode()) + "IsvmchWxConfigService", IIsvmchWxConfigService.class);
            if (iIsvmchWxConfigService == null) {
                return;
            }

            String isvNo = tbMchApplyment.getIsvNo();
            String ifCode = tbMchApplyment.getIfCode();

            // 配置支付目录
            String paySiteUrl = JeepayKit.configPayUrlConvert(sysConfigService.getDBApplicationConfig().getPaySiteUrl());
            iIsvmchWxConfigService.configPayBaseUrl(paySiteUrl, isvNo, tbMchApplyment.getMchNo(), mchAppId, ifCode);


            // 查询微信oauth2配置
            String selectOauth2InfoId = payInterfaceConfigService.queryIsvSelectOauth2InfoId(isvNo, ifCode);

            PayInterfaceConfig dbRecord = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV_OAUTH2, StringUtils.defaultIfEmpty(selectOauth2InfoId, isvNo), CS.IF_CODE.WXPAY);
            if (dbRecord == null || StringUtils.isEmpty(dbRecord.getIfParams())) {
                return;
            }
            WxpayOauth2Params wxpayOauth2Params = Oauth2Params.factory(CS.IF_CODE.WXPAY, dbRecord.getIfParams(), WxpayOauth2Params.class);

            // 配置公众号appId
            if (wxpayOauth2Params != null) {
                String appId = wxpayOauth2Params.getAppId();
                iIsvmchWxConfigService.configBindAppId(appId, isvNo, tbMchApplyment.getMchNo(), mchAppId, ifCode);
            }

        } catch (Exception e) {
            log.error("自动配置微信配置项失败", e);
        }
    }

    // 更新应用支付参数
    private void updateMchAppPayConfig(String logPrefix, MchApplyment tbMchApplyment, String mchAppId, String ifCode) {

        if (StringUtils.isEmpty(tbMchApplyment.getSuccResParameter())) {
            throw new BizException("不存在进件支付参数，请手动配置");
        }
        PayInterfaceConfig updateRecord = new PayInterfaceConfig();
        updateRecord.setIfParams(tbMchApplyment.getSuccResParameter());

        PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.MCH_APP, mchAppId, ifCode);
        if (payInterfaceConfig != null) {
            updateRecord.setId(payInterfaceConfig.getId());
            payInterfaceConfigService.updateById(updateRecord);
            log.info("{}，配置应用appId={}支付参数：{}", logPrefix, mchAppId, updateRecord.getIfParams());
        } else {

            updateRecord.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP);
            updateRecord.setInfoId(mchAppId);
            updateRecord.setIfCode(ifCode);
            payInterfaceConfigService.save(updateRecord);
            log.info("{}，配置应用appId={}支付参数：{}", logPrefix, mchAppId, updateRecord.getIfParams());
        }

    }

    // 更新应用费率配置
    private void updateMchAppRateConfig(String logPrefix, List<PaywayFee> paywayFeeList, String mchAppId, String ifCode) {

        RateConfig mainRateConfig = new RateConfig();
        mainRateConfig.setInfoId(mchAppId);
        mainRateConfig.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP);
        mainRateConfig.setIfCode(ifCode);
        mainRateConfig.addExt("MCHRATE", JSON.toJSONString(paywayFeeList));
        mainRateConfig.addExt("configMode", "mgrMch");

        List<RateConfig> list = new ArrayList<>();
        paywayFeeList.forEach(paywayFee -> list.add(genMchAppRateConfig(mainRateConfig, RateConfig.MCHRATE, paywayFee)));

        LambdaQueryWrapper<RateConfig> delWrapper = RateConfig.gw();
        delWrapper.eq(RateConfig::getIfCode, mainRateConfig.getIfCode());
        delWrapper.eq(RateConfig::getInfoType, mainRateConfig.getInfoType());
        delWrapper.eq(mainRateConfig.getRange() != null, RateConfig::getRange, mainRateConfig.getRange());
        delWrapper.eq(!ObjUtil.isEmpty(mainRateConfig.getMccCode()), RateConfig::getMccCode, mainRateConfig.getMccCode());
        delWrapper.in(RateConfig::getInfoId, Collections.singletonList((mainRateConfig.getInfoId() + "_" + RateConfig.MCHRATE)));
        rateConfigService.resetRate(list, delWrapper, mainRateConfig, false, new ArrayList<>());
        log.info("{}，费率配置成功，应用appId={}", logPrefix, mchAppId);

    }

    // 更新商户应用通道配置
    @Transactional
    public void updateMchAppPayPassage(String logPrefix, List<PaywayFee> paywayFeeList, String mchNo, String mchAppId, String ifCode, boolean isOverWrite) {

        // 获取费率配置的支付方式列表
        List<String> wayCodeList = new ArrayList<>();
        paywayFeeList.forEach(paywayFee -> wayCodeList.add(paywayFee.getWayCode()));

        // 获取支付方式列表内  已存在通道配置的
        List<MchPayPassage> payPassages = mchPayPassageService.list(MchPayPassage.gw()
                .eq(MchPayPassage::getAppId, mchAppId)
                .in(MchPayPassage::getWayCode, wayCodeList));

        // 已存在通道配置的且开启的支付方式Set
        Set<String> existWayCodes = payPassages.stream().filter(i -> i.getState() == CS.YES).map(MchPayPassage::getWayCode).collect(Collectors.toSet());

        if (CollUtil.isNotEmpty(existWayCodes)) {
            // 覆盖原有通道配置，需先关闭原通道
            if (isOverWrite) {
                boolean result = mchPayPassageService.update(new LambdaUpdateWrapper<MchPayPassage>()
                        .set(MchPayPassage::getState, CS.NO)
                        .eq(MchPayPassage::getAppId, mchAppId)
                        .in(MchPayPassage::getWayCode, existWayCodes));
                if (!result) {
                    throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
                }
            } else {
                // 不覆盖原有通道配置，忽略已配置的支付方式
                wayCodeList.removeAll(existWayCodes);
            }
        }


        // 筛选相同支付接口的通道配置，转map<wayCode, MchPayPassage>，这些已存在配置执行更新操作
        Map<String, MchPayPassage> wayCodePassageMap = payPassages.stream()
                .filter(i -> i.getIfCode().equals(ifCode))
                .collect(Collectors.toMap(MchPayPassage::getWayCode, o -> o, (l, r) -> r));


        // 支付方式没有开启其他渠道，自动开启当前渠道
        if (CollUtil.isNotEmpty(wayCodeList)) {
            List<MchPayPassage> insertMchPassageList = new LinkedList<>();
            log.info("{}，通道配置{}，将自动开启以下支付方式{}", logPrefix, ifCode, CollUtil.join(wayCodeList, ","));
            for (String wayCode : wayCodeList) {
                MchPayPassage mchPayPassage = new MchPayPassage();

                if (wayCodePassageMap.get(wayCode) != null) {
                    mchPayPassage.setId(wayCodePassageMap.get(wayCode).getId());
                }

                mchPayPassage.setMchNo(mchNo);
                mchPayPassage.setAppId(mchAppId);
                mchPayPassage.setIfCode(ifCode);
                mchPayPassage.setWayCode(wayCode);
                mchPayPassage.setState(CS.YES);
                insertMchPassageList.add(mchPayPassage);
            }
            mchPayPassageService.saveOrUpdateBatch(insertMchPassageList);
        }

    }

    // 商户应用费率配置对象
    private RateConfig genMchAppRateConfig(RateConfig mainRateConfig, String suffix, PaywayFee paywayFee) {

        RateConfig result = new RateConfig();
        result.setInfoId(mainRateConfig.getInfoId() + "_" + suffix);
        result.setInfoType(mainRateConfig.getInfoType());
        result.setIfCode(mainRateConfig.getIfCode());
        result.setWayCode(paywayFee.getWayCode());
        result.setFeeType(paywayFee.getFeeType());
        result.setFeeRate(paywayFee.getFeeRate());
        result.setApplymentSupport(paywayFee.getApplymentSupport());
        result.setPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFee));

        return result;
    }

    public void deleteRelevance(String applyId) {
        LambdaQueryWrapper<MchStore> storeWrapper = Wrappers.lambdaQuery();
        storeWrapper.eq(MchStore::getMchApplyId, applyId);
        List<MchStore> storeList = mchStoreService.list(storeWrapper);
        storeList.forEach(sto -> sto.setMchApplyId(""));
        mchStoreService.updateBatchById(storeList);
    }

    /**
     * 进件完成后的通用操作
     *
     * @param applyId 商户号
     */
    public void onApplymentSuccess(String applyId) {
        MchApplyment tbMchApplyment = getById(applyId);
        if (tbMchApplyment == null) {
            log.info("未查询到商户数据{}，进件完成动作未执行", applyId);
            return;
        }
        // 自动关联商户池
//        mchAppApplymentService.autoInsertMchIntoPool(tbMchApplyment);

        // 自动创建门店
        //防止二次创建
        List<MchStore> storeList = mchStoreService.list(MchStore.gw().eq(MchStore::getMchApplyId, tbMchApplyment.getApplyId())
                .eq(MchStore::getRemark, "[入网后自动创建]")
                .eq(MchStore::getMchNo, tbMchApplyment.getMchNo()));

        if (storeList.isEmpty()){
            MchStore mchStore = new MchStore();
            mchInfoConverter.cp(tbMchApplyment, mchStore);
            mchStore.setMchApplyId(tbMchApplyment.getApplyId());

            ApplymentBasicInfo applymentBasicInfo = JSON.parseObject(tbMchApplyment.getApplyDetailInfo(), ApplymentBasicInfo.class);
            mchStore.setStoreLogo(applymentBasicInfo.getStoreOuterImg());
            mchStore.setStoreInnerImg(applymentBasicInfo.getStoreInnerImg());
            mchStore.setStoreOuterImg(applymentBasicInfo.getStoreOuterImg());
            mchStore.setAreaCode(applymentBasicInfo.getAreaCode());
            mchStore.setContactPhone(applymentBasicInfo.getContactPhone());
            mchStore.setIsvNo(tbMchApplyment.getIsvNo());
            mchStore.setRemark("[入网后自动创建]");
            mchStore.setDefaultFlag((byte) 1);
            mchStore.setCreatedAt(new Date());
            mchStore.setUpdatedAt(new Date());
            mchStore.setStoreId(SeqKit.genStoreNo());
            mchStore.setStoreName(applymentBasicInfo.getMchShortName());
            //门店绑定应用id
            mchStore.setBindAppId(tbMchApplyment.getAutoConfigMchAppId());

            mchStoreService.save(mchStore);
            //自动为门店创建一个电子码
            try{
                MchQrcodeCard mchQrcodeCard = new MchQrcodeCard();
                mchQrcodeCard.setQrcAlias("自动创建码牌");
                mchQrcodeCard.setAgentNo(tbMchApplyment.getAgentNo());
                mchQrcodeCard.setMchNo(tbMchApplyment.getMchNo());
                mchQrcodeCard.setAppId(tbMchApplyment.getAutoConfigMchAppId());
                mchQrcodeCard.setStoreId(mchStore.getStoreId());
                mchQrcodeCard.setQrcType(MchQrcodeCard.QRC_TYPE_DZ);
                mchQrcodeCard.setBindState((byte) 1);
                mchQrcodeCard.setQrcBelongType((byte) 2);
                mchQrcodeCard.setMchApplyName(tbMchApplyment.getMchShortName());
                mchQrcodeCard.setMchApplyId(tbMchApplyment.getApplyId());
                mchQrcodeCard.setRemark("[入网后自动创建的码牌]");
                mchQrcodeCard.setCreatedAt(new Date());
                mchQrcodeCard.setUpdatedAt(new Date());
                mchQrcodeCard.setQrcId(SeqKit.genQrcodeCardId());
                MchQrcShell defaultTemplate = mchQrcShellService.getDefaultTemplate(CS.SYS_ROLE_TYPE.PLATFORM);
                if(defaultTemplate != null){
                    mchQrcodeCard.setQrcShellId(defaultTemplate.getSid());
                }
                mchQrcodeCardService.save(mchQrcodeCard);
            }catch (Exception e){
                log.info("入网后自动创建码牌失败！");
            }
        } else {
            log.info("查询到有相同门店,入网后自动创建失败！");
        }


    }

    /**
     * 获取参数配置
     *
     * @param applyId   进件号
     * @param sysRoleType  平台类型，参考 CS.SYS_ROLE_TYPE
     * @return
     */
    public MchThirdParamResult getThirdConfig(String applyId, String sysRoleType) {

        MchApplyment applyment = getBaseMapper().selectById(applyId);
        if (applyment == null) {
            throw new BizException("数据异常");
        }
        String channelMchNo = applyment.getChannelMchNo();
        if (StringUtils.isEmpty(channelMchNo)) {
            throw new BizException("商户还未入网通过无法配置");
        }
        JSONObject subMchInfo = mchSubInfoService.getMainSubMchInfo(applyment.getApplyId());
        List<MchThirdConfig> configList = mchThirdConfigMapper.selectList(MchThirdConfig.gw().eq(MchThirdConfig::getChannelMerchantId, channelMchNo));
        List<JSONObject> wxAppidList = Lists.newArrayList();
        List<String> wxPathList = Lists.newArrayList();

        if (configList != null) {
            configList.forEach(item -> {
                if (MchThirdConfig.ThirdType.WX.name().equals(item.getThirdType())) {
                    if (MchThirdConfig.Type.APPID.getCode().equals(item.getType())) {
                        MchThirdConfig.AppidType val = MchThirdConfig.AppidType.getVal(item.getAppidType());
                        JSONObject idData = new JSONObject(2);
                        idData.put("appid", item.getSubAppid());
                        idData.put("desc", val.getDesc());
                        wxAppidList.add(idData);
                    } else {
                        wxPathList.add(item.getJsapiPath());
                    }
                }
            });
        }

        com.jeequan.jeepay.core.entity.MchApplyment model = mchInfoConverter.toModel(applyment);
        MchThirdParamResult result = new MchThirdParamResult(subMchInfo.getString("WX"), subMchInfo.getString("ZFB"), wxAppidList, wxPathList);
        result.setScanPayPermFlag(applyment.getScanPayPerm());

        if (CS.SYS_ROLE_TYPE.PLATFORM.equals(sysRoleType)) {
            String regionLock = mchConfigService.getRegionLock(model);
            result.setRegionLock(regionLock);
        }

        return result;
    }

    /**
     * 新增配置
     *
     * @param thirdConfig
     */
    public void addConfig(MchThirdConfig thirdConfig) {
        thirdConfig.preCheck();
        MchApplyment mchApplyment = baseMapper.selectById(thirdConfig.getMchNo());
        if (mchApplyment == null) {
            throw new BizException("数据异常");
        }
        IMchApiService api = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(mchApplyment.getIfCode()) + "MchApiService", IMchApiService.class);
        if (api == null) {
            throw new BizException("获取接口异常");
        }
        String type = thirdConfig.getAppidType();
        if (MchThirdConfig.Type.PATH.getCode().equals(thirdConfig.getType())) {
            type = ChannelMchRq.Type.PATH.getType();
        }
        JSONObject subMchInfo = mchSubInfoService.getMainSubMchInfo(mchApplyment.getApplyId());
        ChannelMchRq mchRq = new ChannelMchRq(thirdConfig.getSubAppid(), thirdConfig.getJsapiPath(), type, thirdConfig.getSubMchNo());
        mchRq.setSubMchNo(subMchInfo.getString("WX"));
        ChannelRetMsg retMsg = api.appidAndPath(mchInfoConverter.toModel(mchApplyment), mchRq);
        if (ChannelRetMsg.ChannelState.CONFIRM_SUCCESS != retMsg.getChannelState()) {
            throw new BizException(retMsg.getChannelErrMsg());
        }
        thirdConfig.setChannelMerchantId(mchApplyment.getChannelMchNo());
        mchThirdConfigMapper.insert(thirdConfig);
    }

    public Page<MchApplyment> selectMchApplyment(Page<MchApplyment> page, MchApplyment mchApplyment) {
        // 时间搜索
        Date[] searchDateRange = mchApplyment.buildQueryDateRange();
        if(searchDateRange[0] != null){
            mchApplyment.setFirstDate(searchDateRange[0]);
        }
        if(searchDateRange[1] != null){
            mchApplyment.setLastDate(searchDateRange[1]);
        }
        Page<MchApplyment> result = mchApplymentMapper.selectMchApplyment(page, mchApplyment);
        List<String> ifCodeList = new ArrayList<>();
        result.getRecords().forEach(item -> {
            // 列表中所有接口代码
            ifCodeList.add(item.getIfCode());
            //手机号脱敏
            if (StringUtils.isNotEmpty(item.getMchServicePhone())){
                item.setMchServicePhone(DesensitizedUtil.mobilePhone(item.getMchServicePhone()));
            }
            if (StringUtils.isNotEmpty(item.getContactPhone())){
                item.setContactPhone(DesensitizedUtil.mobilePhone(item.getContactPhone()));
            }
            if (StringUtils.isNotEmpty(item.getMchUserPhone())){
                item.setMchUserPhone(DesensitizedUtil.mobilePhone(item.getMchUserPhone()));
            }
        });
        // 接口代码配置
        if (CollectionUtils.isNotEmpty(ifCodeList)) {
            HashMap<String, PayInterfaceDefine> defineMap = new HashMap<>();
            payInterfaceDefineService.list(PayInterfaceDefine.gw()
                    .select(PayInterfaceDefine::getIfCode, PayInterfaceDefine::getBgColor, PayInterfaceDefine::getIcon, PayInterfaceDefine::getIfName)
                    .in(PayInterfaceDefine::getIfCode, ifCodeList)
            ).forEach(item -> defineMap.put(item.getIfCode(), item));
            result.getRecords().forEach(item -> {
                PayInterfaceDefine define = defineMap.get(item.getIfCode());
                if (define == null) {
                    return;
                }
                item.addExt("bgColor", define.getBgColor());
                item.addExt("icon", define.getIcon());
                item.addExt("ifName", define.getIfName());
            });
        }
        return result;
    }

    public Page<MchModifyApplymentEntity> getModifyApplyments(Page<MchModifyApplymentEntity> page, MchModifyApplymentEntity mchModifyApplymentEntity) {
        page.addOrder(OrderItem.desc("modify.created_at"));
        return mchModifyApplymentMapper.getModifyApplyments(page, mchModifyApplymentEntity);
    }

    /**
     *
     * @param mchApplyment
     * @return
     */
    public List<MchApplyment> getSucceedIsvName(MchApplyment mchApplyment){
        List<MchApplyment> succeedIsvName = mchApplymentMapper.getSucceedIsvName(mchApplyment);
        List<MchApplyment> result = new ArrayList<>();
        if(mchApplyment.getIsDivision() != null && CS.YES == mchApplyment.getIsDivision()){
            for (MchApplyment apply:succeedIsvName) {
                PayInterfaceConfig config = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, apply.getIsvNo(), apply.getIfCode());
                if(CS.YES == config.getIsDivision()){
                    result.add(apply);
                }
            }
            return result;
        }
        return succeedIsvName;
    }
}
