package com.jeequan.jeepay.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.IsvUserConnEntity;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.service.mapper.AgentInfoMapper;
import com.jeequan.jeepay.service.mapper.IsvUserConnMapper;
import com.jeequan.jeepay.service.mapper.MchInfoMapper;
import lombok.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class IsvUserConnService extends ServiceImpl<IsvUserConnMapper, IsvUserConnEntity> {

    @Resource
    private AgentInfoMapper agentInfoMapper;

    @Resource
    private MchInfoMapper mchInfoMapper;

    public IsvUserConnEntity get(String infoType, String infoId, String isvNo) {
        return lambdaQuery().eq(IsvUserConnEntity::getIsvNo, isvNo)
                .eq(IsvUserConnEntity::getInfoId, infoId)
                .eq(IsvUserConnEntity::getInfoType, infoType)
                .one();
    }

    /**
     * 获取关联的渠道商信息
     *
     * @param infoType 用户类型 {@link com.jeequan.jeepay.core.constants.CS.SYS_ROLE_TYPE}
     * @param infoId   服务商号 / 商户号
     */
    public List<IsvUserConnEntity> getConnInfo(String infoType, String... infoId) {
        return lambdaQuery().eq(IsvUserConnEntity::getInfoType, infoType)
                .in(IsvUserConnEntity::getInfoId, Arrays.stream(infoId))
                .eq(IsvUserConnEntity::getStatus, CS.YES)
                .list();
    }

    /**
     * 获取上级服务商(原代理)关联的渠道商(原服务商)关联信息, 并构建指定用户或者服务商(原代理)关联的渠道商(原服务商)关联信息
     * @since 2024-01-06
     * <p>改为由上级关联信息来管理</p>
     */
    public List<IsvUserConnEntity> getSuperiorConnInfo(String infoType, String infoId) {
        String agentNo;
        switch (infoType) {
            case CS.SYS_ROLE_TYPE.AGENT:
                agentNo = agentInfoMapper.selectById(infoId).getPid();
                break;
            case CS.SYS_ROLE_TYPE.MCH:
                agentNo = mchInfoMapper.selectById(infoId).getAgentNo();
                break;
            default:
                throw new BizException("不支持的用户类型");
        }

        return lambdaQuery()
                .eq(IsvUserConnEntity::getInfoId, agentNo)
                .eq(IsvUserConnEntity::getInfoType, CS.SYS_ROLE_TYPE.AGENT)
                .eq(IsvUserConnEntity::getConfigStatus, IsvUserConnEntity.STATUS_ENABLED)
                .list()
                .stream()
                .map(r -> r.toBuilder().infoId(infoId).infoType(infoType).id(null).build())
                .collect(Collectors.toList());
    }

    public List<IsvUserConnEntity> getConnInfoByAgentNo(String agentNo, String isvNo) {
        AgentInfo agentInfo = ChainWrappers.lambdaQueryChain(agentInfoMapper)
                .eq(AgentInfo::getAgentNo, agentNo)
                .select(AgentInfo::getPidArr, AgentInfo::getAgentNo)
                .one();
        Assert.notNull(agentInfo, "未知的服务商号");

        // 查询上级代理信息
        final Set<String> superAgentNoList = new HashSet<>();
        Optional.ofNullable(agentInfo.getPidArr()).ifPresent(r -> {
            superAgentNoList.addAll(Arrays.asList(agentInfo.getPidArr().split(",")));
        });

        // 查询下级代理信息
        Set<String> subAgentNoList = ChainWrappers.lambdaQueryChain(agentInfoMapper)
                .apply("FIND_IN_SET({0}, `pid_arr`)", agentNo)
                .select(AgentInfo::getAgentNo)
                .list().stream()
                .map(AgentInfo::getAgentNo)
                .collect(Collectors.toSet());

        // 添加自己
        subAgentNoList.add(agentNo);
        Set<String> subMchNoList = ChainWrappers.lambdaQueryChain(mchInfoMapper)
                .apply("FIND_IN_SET({0}, `agent_no_arr`)", agentNo)
                .select(MchInfo::getMchNo)
                .list().stream().map(MchInfo::getMchNo)
                .collect(Collectors.toSet());

        return getUserConnList(superAgentNoList, subAgentNoList, subMchNoList, isvNo, null);
    }

    public List<IsvUserConnEntity> getConnInfoByMchNo(String mchNo, String isvNo) {
        MchInfo mchInfo = ChainWrappers.lambdaQueryChain(mchInfoMapper)
                .eq(MchInfo::getMchNo, mchNo)
                .select(MchInfo::getAgentNoArr)
                .one();
        Assert.notNull(mchInfo, "未知的商户号");

        String[] agentNoArr = mchInfo.getAgentNoArr().split(",");
        // 查询上级代理信息
        Set<String> agentNoList = new HashSet<>(Arrays.asList(agentNoArr));
        return getUserConnList(agentNoList, Collections.emptySet(), Collections.singleton(mchNo), isvNo, agentNoArr[0]);
    }

    private List<IsvUserConnEntity> getUserConnList(@NonNull Set<String> superAgentNoList, @NonNull Set<String> subAgentNoList,
                                                    @NonNull Set<String> mchNoList, @NonNull String isvNo, String pAgentNo) {
        List<IsvUserConnEntity> result = new ArrayList<>();

        for (String itemAgentNo : superAgentNoList) {
            IsvUserConnEntity entity = IsvUserConnEntity.create(CS.SYS_ROLE_TYPE.AGENT, itemAgentNo, isvNo, IsvUserConnEntity.STATUS_DISABLED, IsvUserConnEntity.STATUS_ENABLED);
            result.add(entity);
        }

        for (String itemAgentNo : subAgentNoList) {
            IsvUserConnEntity entity = IsvUserConnEntity.create(CS.SYS_ROLE_TYPE.AGENT, itemAgentNo, isvNo, IsvUserConnEntity.STATUS_ENABLED, IsvUserConnEntity.STATUS_ENABLED);
            result.add(entity);
        }

        for (String itemMchNo : mchNoList) {
            IsvUserConnEntity entity = IsvUserConnEntity.create(CS.SYS_ROLE_TYPE.MCH, itemMchNo, isvNo, IsvUserConnEntity.STATUS_ENABLED, IsvUserConnEntity.STATUS_ENABLED);
            result.add(entity);
        }

        return result;
    }
}
