package com.jeequan.jeepay.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.utils.StringKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.mapper.MchAppMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商户应用表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2021-06-15
 */
@Service
public class MchAppService extends ServiceImpl<MchAppMapper, MchAppEntity> {

    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private MchPayPassageService mchPayPassageService;
    @Autowired
    private PayInterfaceConfigService payInterfaceConfigService;
    @Autowired
    private MchInfoService mchInfoService;
    @Autowired
    private TransferOrderService transferOrderService;
    @Autowired
    private MchAppApplymentService mchAppApplymentService;
    @Autowired
    private MchApplymentService mchApplymentService;
    @Autowired
    private MchAppMapper mchAppMapper;

    @Transactional(rollbackFor = Exception.class)
    public boolean correlation(String appId) {
        Assert.notNull(appId, "应用号[appId]不能为空");
        //根据appid查询mchApp
        MchAppEntity mchAppEntity = baseMapper.selectById(appId);
        if (mchAppEntity == null) {
            return false;
        }

        List<MchAppApplyment> mchAppApplyments = new ArrayList<>();
        //根据MchNo查询achApplyment
        List<MchApplyment> tbMchApplyments = mchApplymentService.lambdaQuery()
                .eq(MchApplyment::getMchNo, mchAppEntity.getMchNo())
                .eq(MchApplyment::getAutoConfigMchAppId, mchAppEntity.getAppId())
                .eq(MchApplyment::getState, MchApplyment.STATE_SUCCESS).list();
        if (ObjectUtils.isEmpty(tbMchApplyments)) {
            return false;
        }

        //判断根据appid删除是否成功
        mchAppApplymentService.remove(mchAppApplymentService.lambdaQuery().eq(MchAppApplyment::getMchAppId, appId));
        for (MchApplyment tbMchApplyment : tbMchApplyments) {
            MchAppApplyment appApplyment = new MchAppApplyment();
            appApplyment.setMchAppId(mchAppEntity.getAppId())
                    .setMchNo(mchAppEntity.getMchNo())
                    .setMchApplyId(tbMchApplyment.getApplyId())
                    .setStatus(1);
            mchAppApplyments.add(appApplyment);
        }
        //返回批量新增结果
        return mchAppApplymentService.saveBatch(mchAppApplyments);
    }


    @Transactional(rollbackFor = Exception.class)
    public void removeByAppId(String appId) {

        // 1.查看当前应用是否存在交易数据
        long payCount = payOrderService.count(PayOrder.gw().eq(PayOrder::getAppId, appId));
        if (payCount > 0) {
            throw new BizException("该应用已存在交易数据，不可删除");
        }

        // 1.1是否存在转账交易
        long transferCount = transferOrderService.count(TransferOrderEntity.gw().eq(TransferOrderEntity::getAppId, appId));
        if (transferCount > 0) {
            throw new BizException("该应用已存在转账数据，不可删除");
        }

        // 2.删除应用关联的支付通道
        mchPayPassageService.remove(MchPayPassage.gw().eq(MchPayPassage::getAppId, appId));

        // 3.删除应用配置的支付参数
        payInterfaceConfigService.remove(PayInterfaceConfig.gw()
                .eq(PayInterfaceConfig::getInfoId, appId)
                .eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.MCH_APP)
        );

        // 4.删除当前应用
        if (!removeById(appId)) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
        }
    }

    public MchAppEntity selectById(String appId) {
        MchAppEntity mchAppEntity = this.getById(appId);
        if (mchAppEntity == null) {
            return null;
        }
        mchAppEntity.setAppSecret(StringKit.autoDesensitization(mchAppEntity.getAppSecret()));

        return mchAppEntity;
    }

    public IPage<MchAppEntity> selectPage(IPage<MchAppEntity> iPage, MchAppEntity mchAppEntity) {

        if (mchAppEntity.getExt() != null) {
            String unionSearchId = mchAppEntity.getExt().getString("unionSearchId");
            if (StringUtils.isNotBlank(unionSearchId)) {
                List<String> mchNoList = new ArrayList<>();
                List<MchInfo> list = mchInfoService.list(MchInfo.gw().like(MchInfo::getMchName, unionSearchId));
                if (CollUtil.isNotEmpty(list)) {
                    mchNoList = list.stream().map(MchInfo::getMchNo).collect(Collectors.toList());
                }
                List<String> finalMchNoList = mchNoList;
                mchAppEntity.setUnionSearchId(unionSearchId);
                if (CollUtil.isNotEmpty(finalMchNoList)) {
                    mchAppEntity.setFinalMchNoList(finalMchNoList);
                }
            }
        }

        return mchAppMapper.getAppList(iPage, mchAppEntity);
    }

    public MchAppEntity getOneByMch(String mchNo, String appId) {
        return lambdaQuery().eq(MchAppEntity::getMchNo, mchNo).eq(MchAppEntity::getAppId, appId).one();
    }

    public MchAppEntity getDefaultApp(String mchNo) {
        List<MchAppEntity> list = lambdaQuery().eq(MchAppEntity::getDefaultFlag, CS.YES).eq(MchAppEntity::getMchNo, mchNo).list();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    public MchAppEntity getOfflineApp(String mchNo) {
        return lambdaQuery()
                .eq(MchAppEntity::getMchNo, mchNo)
                .eq(MchAppEntity::getRange, 0)
                .eq(MchAppEntity::getState, CS.YES)
                .last("limit 1").one();
    }

    public List<MchAppEntity> selectAllIsvsubMchApp() {
        return this.selectAllMchApp((byte) 2);
    }

    public List<MchAppEntity> selectAllNormalMchApp() {
        return this.selectAllMchApp((byte) 1);
    }

    public List<MchAppEntity> selectAllMchApp(Byte type) {
        Map<String, Object> params = new HashMap<>();
        params.put("type", type);

        return baseMapper.selectMchAppList(params);
    }

    /**
     * 审核操作
     * @param mchApp
     */
    public void audit(MchAppEntity mchApp) {
        String appId = mchApp.getAppId();
        if(StringUtils.isEmpty(appId)){
            throw new BizException("缺失应用id参数");
        }
        MchAppEntity extApp = baseMapper.selectById(appId);
        if(!MchAppEntity.AUDIT.equals(extApp.getState())){
            throw new BizException("只能审核应用状态为”审核中“的数据");
        }
        if(mchApp.getState() == null){
            throw new BizException("审核状态不能为空");
        }
        if(MchAppEntity.REJECT.equals(mchApp.getState()) && StringUtils.isEmpty(mchApp.getStateDesc())){
            throw new BizException("审核驳回需要填写驳回原因");
        }
        updateById(mchApp);
    }

    public int getMchAppCheckNumber(String mchNo){
        return mchAppMapper.getMchAppCheckNumber(mchNo);
    }
}
