package com.jeequan.jeepay.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.model.DBDefaultConfig;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.core.utils.InviteCodeUtil;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.mapper.AgentInfoMapper;
import com.jeequan.jeepay.service.mapper.RateConfigMapper;
import org.apache.commons.collections4.CollectionUtils;
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.ObjectUtils;

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

/**
 * <p>
 * 服务商信息表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2022-03-12
 */
@Service
public class AgentInfoService extends ServiceImpl<AgentInfoMapper, AgentInfo> {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserAuthService sysUserAuthService;
    @Autowired
    private IsvInfoService isvInfoService;
    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private MchApplymentService mchApplymentService;
    @Autowired
    private MchAppService mchAppService;
    @Autowired
    private InfoAccountService infoAccountService;
    @Autowired
    private RateConfigMapper rateConfigMapper;
    @Autowired
    private MchInfoService mchInfoService;
    @Autowired
    private MchStoreDeviceService mchStoreDeviceService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private AgentConfigService agentConfigService;
    @Autowired
    private IsvUserConnService isvUserConnService;

    /**
     * 新的代理信息保存逻辑
     * @param agentInfo     代理信息
     * @param loginPassword 登录密码
     * @param isAudit       是否自动审核
     */
    @Transactional(rollbackFor = Exception.class)
    public void addAgentV2(AgentInfo agentInfo, String loginPassword, boolean isAudit) {

        // 服务商等级
        agentInfo.setLevel(1); //一级服务商

        // 包含上级服务商
        if (StringUtils.isNotEmpty(agentInfo.getPid())) {
            AgentInfo parentAgent = getById(agentInfo.getPid());
            agentInfo.setLevel(parentAgent.getLevel() + 1);
            agentInfo.setPname(parentAgent.getAgentShortName());
            if (!ObjectUtils.isEmpty(parentAgent.getPidArr())) {
                agentInfo.setPidArr(parentAgent.getAgentNo() + "," + parentAgent.getPidArr());
            } else {
                agentInfo.setPidArr(parentAgent.getAgentNo());
            }

            if (agentInfo.getState() != CS.YES) {
                throw new BizException("所选上级服务商状态禁止该操作");
            }
        } else {
            DBDefaultConfig dbDefaultConfig = sysConfigService.getDBDefaultConfig();
            agentInfo.setPid(dbDefaultConfig.getDefaultAgentNo());
            agentInfo.setPid(dbDefaultConfig.getDefaultAgentNo());
        }

        byte userState = CS.YES;
        if (isAudit) {
            // 查询配置是否需要审核
            SysConfig sysConfig = sysConfigService.getById("agentNewSubIsAudit");
            if (sysConfig != null && "1".equals(sysConfig.getConfigVal())) {
                // 待平台审核
//                userState = agentInfo.getState();
                agentInfo.setState(AgentInfo.AUDIT_STATE_UN_AUTH);
            } else {
                userState = agentInfo.getState();
            }
        } else {
            userState = agentInfo.getState();
        }

        // 插入服务商基本信息
        boolean saveResult = save(agentInfo);
        if (!saveResult) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }

        // 插入用户信息
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setLoginUsername(agentInfo.getLoginUsername());
        sysUserEntity.setRealname(agentInfo.getContactName());
        sysUserEntity.setTelphone(agentInfo.getContactTel());
        sysUserEntity.setUserNo(agentInfo.getAgentNo());
        sysUserEntity.setBelongInfoId(agentInfo.getAgentNo());
        sysUserEntity.setSex(CS.SEX_MALE);
        sysUserEntity.setUserType(com.jeequan.jeepay.core.entity.SysUser.UEST_TYPE_ADMIN);
        sysUserEntity.setState(userState);
        sysUserService.addSysUser(sysUserEntity, CS.SYS_ROLE_TYPE.AGENT, loginPassword);

        // 存入服务商的默认用户ID
        AgentInfo updateRecord = AgentInfo.builder()
                .agentNo(agentInfo.getAgentNo())
                .initUserId(sysUserEntity.getSysUserId())
                .build();
        saveResult = updateById(updateRecord);
        if (!saveResult) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }

        // 初始化账户数据
        infoAccountService.initAgentAccount(agentInfo.getAgentNo());

        // 服务商的默认费率
        List<RateConfig> rateConfigList;

        String applyGroupKey = AgentConfig.GROUP_KEY_APPLYMENT_CONFIG;
        List<AgentConfig> agentConfigList = new ArrayList<>();

        // 包含服务商
        if (StringUtils.isNotEmpty(agentInfo.getPid())) {

            // 查询上级服务商的
            rateConfigList = rateConfigMapper.selectList(RateConfig.gw()
                    .eq(RateConfig::getInfoId, RateConfig.appendInfoByAgentDef(agentInfo.getPid()))
                    .eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.AGENT)
            );
            // 查询上级服务商的进件配置
            LambdaQueryWrapper<AgentConfig> queryWrapper = AgentConfig.gw().eq(AgentConfig::getAgentNo, agentInfo.getPid());
            queryWrapper.eq(AgentConfig::getGroupKey, applyGroupKey);
            agentConfigService.list(queryWrapper).forEach(item -> {
                item.setAgentNo(agentInfo.getAgentNo());
                agentConfigList.add(item);
            });
        } else {
            // 查询服务商的默认费率
            rateConfigList = rateConfigMapper.selectList(RateConfig.gw()
                    .eq(RateConfig::getInfoId, RateConfig.appendInfoByAgentDef(agentInfo.getIsvNo()))
                    .eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
            );
            // 查询平台的服务商默认进件配置
            JSONObject applyGroupJson = sysConfigService.selectByGroupKey("defaultConfig");
            // 服务商进件配置管理方式-默认
            agentConfigList.add(new AgentConfig(agentInfo.getAgentNo(), AgentConfig.KEY_APPLYMENT_AUDIT_MODE, AgentConfig.KEY_APPLYMENT_AUDIT_MODE_DEF, applyGroupKey));
            // 服务商进件是否需要运营平台预审核
            agentConfigList.add(new AgentConfig(agentInfo.getAgentNo(), AgentConfig.KEY_AGENT_APPLYMENT_PRE_AUDIT_CONFIG, applyGroupJson.getString("agentApplymentPreAudit"), applyGroupKey));
            // 服务商发起进件时间限制
            agentConfigList.add(new AgentConfig(agentInfo.getAgentNo(), AgentConfig.KEY_AGENT_APPLY_TIME_LIMIT_CONFIG, applyGroupJson.getString("agentApplyTimeLimit"), applyGroupKey));
        }
        if (!agentConfigList.isEmpty()) {
            // 如果有配置条数再进行插入操作，否则给新用户展示页面初始化的内容（即使用默认配置）
            agentConfigService.saveBatch(agentConfigList);
        }

        for (RateConfig rateConfig : rateConfigList) {
            rateConfig.setInfoId(RateConfig.appendInfoByAgent(agentInfo.getAgentNo()));
            rateConfig.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
            rateConfig.setUpdatedAt(null);
            rateConfig.setUpdatedAt(null);
            rateConfigMapper.insert(rateConfig);
        }

        List<IsvUserConnEntity> userConnEntityList = isvUserConnService.getSuperiorConnInfo(CS.SYS_ROLE_TYPE.AGENT, agentInfo.getAgentNo());

        isvUserConnService.saveBatch(userConnEntityList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addAgent(AgentInfo agentInfo, String loginPassword, boolean isAudit) {

        // 当前服务商状态是否正确
        IsvInfoEntity isvInfoEntity = isvInfoService.getById(agentInfo.getIsvNo());
        if (isvInfoEntity == null || isvInfoEntity.getState() == CS.NO) {
            throw new BizException("当前服务商不可用");
        }

        // 服务商等级
        agentInfo.setLevel(1); //一级服务商
        // 包含上级服务商
        if (StringUtils.isNotEmpty(agentInfo.getPid())) {
            AgentInfo parentAgent = getById(agentInfo.getPid());
            agentInfo.setLevel(parentAgent.getLevel() + 1);
        }

        byte userState = CS.YES;
        if (isAudit) {
            // 查询配置是否需要审核
            SysConfig sysConfig = sysConfigService.getById("agentNewSubIsAudit");
            if (sysConfig != null && "1".equals(sysConfig.getConfigVal())) {
                // 待平台审核
//                userState = agentInfo.getState();
                agentInfo.setState(AgentInfo.AUDIT_STATE_UN_AUTH);
            } else {
                userState = agentInfo.getState();
            }
        } else {
            userState = agentInfo.getState();
        }

        // 插入服务商基本信息
        boolean saveResult = save(agentInfo);
        if (!saveResult) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }

        // 插入用户信息
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setLoginUsername(agentInfo.getLoginUsername());
        sysUserEntity.setRealname(agentInfo.getContactName());
        sysUserEntity.setTelphone(agentInfo.getContactTel());
        sysUserEntity.setUserNo(agentInfo.getAgentNo());
        sysUserEntity.setBelongInfoId(agentInfo.getAgentNo());
        sysUserEntity.setSex(CS.SEX_MALE);
        sysUserEntity.setUserType(com.jeequan.jeepay.core.entity.SysUser.UEST_TYPE_ADMIN);
        sysUserEntity.setState(userState);
        sysUserService.addSysUser(sysUserEntity, CS.SYS_ROLE_TYPE.AGENT, loginPassword);

        // 存入服务商的默认用户ID
        AgentInfo updateRecord = new AgentInfo();
        updateRecord.setAgentNo(agentInfo.getAgentNo());
        updateRecord.setInitUserId(sysUserEntity.getSysUserId());
        saveResult = updateById(updateRecord);
        if (!saveResult) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }

        // 初始化账户数据
        infoAccountService.initAgentAccount(agentInfo.getAgentNo());

        // 服务商的默认费率
        List<RateConfig> rateConfigList = new ArrayList<>();

        String applyGroupKey = AgentConfig.GROUP_KEY_APPLYMENT_CONFIG;
        List<AgentConfig> agentConfigList = new ArrayList<>();

        // 包含服务商
        if (StringUtils.isNotEmpty(agentInfo.getPid())) {

            // 查询上级服务商的
            rateConfigList = rateConfigMapper.selectList(RateConfig.gw()
                    .eq(RateConfig::getInfoId, RateConfig.appendInfoByAgentDef(agentInfo.getPid()))
                    .eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.AGENT)
            );
            // 查询上级服务商的进件配置
            LambdaQueryWrapper<AgentConfig> queryWrapper = AgentConfig.gw().eq(AgentConfig::getAgentNo, agentInfo.getPid());
            queryWrapper.eq(AgentConfig::getGroupKey, applyGroupKey);
            agentConfigService.list(queryWrapper).stream().forEach(item -> {
                item.setAgentNo(agentInfo.getAgentNo());
                agentConfigList.add(item);
            });
        } else {
            // 查询服务商的默认费率
            rateConfigList = rateConfigMapper.selectList(RateConfig.gw()
                    .eq(RateConfig::getInfoId, RateConfig.appendInfoByAgentDef(agentInfo.getIsvNo()))
                    .eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
            );
            // 查询平台的服务商默认进件配置
            JSONObject applyGroupJson = sysConfigService.selectByGroupKey("defaultConfig");
            // 服务商进件配置管理方式-默认
            agentConfigList.add(new AgentConfig(agentInfo.getAgentNo(), AgentConfig.KEY_APPLYMENT_AUDIT_MODE, AgentConfig.KEY_APPLYMENT_AUDIT_MODE_DEF, applyGroupKey));
            // 服务商进件是否需要运营平台预审核
            agentConfigList.add(new AgentConfig(agentInfo.getAgentNo(), AgentConfig.KEY_AGENT_APPLYMENT_PRE_AUDIT_CONFIG, applyGroupJson.getString("agentApplymentPreAudit"), applyGroupKey));
            // 服务商发起进件时间限制
            agentConfigList.add(new AgentConfig(agentInfo.getAgentNo(), AgentConfig.KEY_AGENT_APPLY_TIME_LIMIT_CONFIG, applyGroupJson.getString("agentApplyTimeLimit"), applyGroupKey));
        }
        if (!agentConfigList.isEmpty()) {
            // 如果有配置条数再进行插入操作，否则给新用户展示页面初始化的内容（即使用默认配置）
            agentConfigService.saveBatch(agentConfigList);
        }
        for (RateConfig rateConfig : rateConfigList) {
            rateConfig.setInfoId(RateConfig.appendInfoByAgent(agentInfo.getAgentNo()));
            rateConfig.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
            rateConfig.setUpdatedAt(null);
            rateConfig.setUpdatedAt(null);
            rateConfigMapper.insert(rateConfig);
        }

    }


    /**
     * 查询顶级服务商
     **/
    public String queryTopAgentNo(String currentAgentNo) {

        List<String> allAgentNo = queryAllParentAgentNo(currentAgentNo);
        return allAgentNo.isEmpty() ? null : allAgentNo.get(0);
    }

    /**
     * 所有的服务商号码 : 顺序  顶级服务商 --》 二级 --》 ... --》 商户直接服务商
     */
    public List<String> queryAllParentAgentNo(String currentAgentNo) {

        List<String> result = new ArrayList<>();
        recursionQueryPid(currentAgentNo, result);

        // 反转
        Collections.reverse(result);

        return result;
    }

    /**
     * 所有的下级服务商号码 （当前 和 所有的下级服务商 ）
     */
    public List<String> queryAllSubAgentNo(String currentAgentNo) {

        List<String> result = new ArrayList<>();
        recursionQuerySubAgentId(currentAgentNo, result);
        return result;
    }

    /**
     * 所有的直接下级服务商号码 （当前 和 所有的直接下级服务商 ）
     */
    public List<String> querySubAgentNo(String currentAgentNo) {

        List<String> result = new ArrayList<>();
        result.add(currentAgentNo);

        // 查询下级服务商
        List<AgentInfo> agentInfoList = this.list(AgentInfo.gw().select(AgentInfo::getAgentNo).eq(AgentInfo::getPid, currentAgentNo));
        if (CollUtil.isEmpty(agentInfoList)) {
            return result;
        }

        result.addAll(agentInfoList.stream().map(AgentInfo::getAgentNo).collect(Collectors.toList()));
        return result;
    }


    /**
     * 递归查询上级服务商
     */
    private void recursionQueryPid(String agentNo, List<String> result) {

        // 号码为空
        if (StringUtils.isEmpty(agentNo)) {
            return;
        }

        // 加入当前服务商号码
        result.add(agentNo);

        // 查询上级服务商
        AgentInfo agentInfo = this.getOne(AgentInfo.gw().select(AgentInfo::getPid).eq(AgentInfo::getAgentNo, agentNo));

        // 获取不到上级服务商
        if (agentInfo == null || StringUtils.isEmpty(agentInfo.getPid())) {
            return;
        }

        // 继续查询
        recursionQueryPid(agentInfo.getPid(), result);
    }


    /**
     * 递归查询下级服务商
     */
    private void recursionQuerySubAgentId(String agentNo, List<String> result) {

        // 号码为空
        if (StringUtils.isEmpty(agentNo)) {
            return;
        }

        // 加入当前服务商号码
        result.add(agentNo);

        // 查询上级服务商
        List<AgentInfo> agentInfoList = this.list(AgentInfo.gw().select(AgentInfo::getAgentNo).eq(AgentInfo::getPid, agentNo));

        for (AgentInfo agentInfo : agentInfoList) {
            recursionQuerySubAgentId(agentInfo.getAgentNo(), result);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public List<Long> removeByAgentNo(String agentNo) {
        // 0.当前服务商是否存在
        AgentInfo agentInfo = getById(agentNo);
        if (agentInfo == null) {
            throw new BizException("该服务商不存在");
        }

        // 是否存在商户
        long mchCount = mchInfoService.count(MchInfo.gw().eq(MchInfo::getAgentNo, agentNo));
        if (mchCount > 0) {
            throw new BizException("该服务商已存在下级商户，不可删除");
        }

        // 是否存在下级代理
        long subAgentCount = count(AgentInfo.gw().eq(AgentInfo::getPid, agentNo));
        if (subAgentCount > 0) {
            throw new BizException("该服务商已存在下级代理，不可删除");
        }

        // 是否存在设备
        long deviceCount = mchStoreDeviceService.count(MchStoreDevice.gw().eq(MchStoreDevice::getAgentNo, agentNo));
        if (deviceCount > 0) {
            throw new BizException("该服务商已存在门店设备，不可删除");
        }

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

        // 1.1.2查看当前服务商是否存在交易数据
        long subCount = count(AgentInfo.gw().eq(AgentInfo::getPid, agentNo));
        if (subCount > 0) {
            throw new BizException("该服务商已存在子代理，不可删除");
        }

        // 1.1当前服务商是否存在进件记录
        long applyMentCount = mchApplymentService.count(MchApplyment.gw().eq(MchApplyment::getAgentNo, agentNo));
        if (applyMentCount > 0) {
            throw new BizException("该服务商已存在进件信息，不可删除");
        }

        // 3.删除当前服务商支付接口配置参数
        List<String> appIdList = new LinkedList<>();
        mchAppService.lambdaQuery().eq(MchAppEntity::getAgentNo, agentNo)
                .list().forEach(item -> appIdList.add(item.getAppId()));

        List<SysUserEntity> userList = sysUserService.list(SysUserEntity.gw()
                .eq(SysUserEntity::getBelongInfoId, agentNo)
                .eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.AGENT)
        );

        // 4.删除当前服务商应用信息
        if (CollectionUtils.isNotEmpty(appIdList)) {
            mchAppService.removeByIds(appIdList);
        }

        // 返回的用户id
        List<Long> userIdList = new ArrayList<>();
        for (SysUserEntity user : userList) {
            userIdList.add(user.getSysUserId());
        }

        if (CollectionUtils.isNotEmpty(userList)) {
            // 5.删除当前服务商用户子用户信息
            sysUserAuthService.remove(SysUserAuth.gw().in(SysUserAuth::getUserId, userIdList));
        }

        // 6.删除当前服务商的登录用户
        sysUserService.remove(SysUserEntity.gw()
                .eq(SysUserEntity::getBelongInfoId, agentNo)
                .eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.AGENT)
        );

        // 7.删除当前服务商
        boolean removeMchInfo = removeById(agentNo);
        if (!removeMchInfo) {
            throw new BizException("删除当前服务商失败");
        }
        return userIdList;

    }

    public JSONObject agentCount(String agentNo, List<String> agentSubList, JSONObject paramJSON) {
        String dateRange = paramJSON.getString("queryDateRange");
        String isQueryAll = (String) paramJSON.getOrDefault("isQueryAll", "");
        String createdStart = null;
        String createdEnd = null;

        if (StringUtils.isEmpty(isQueryAll)) {
            // 获取查询时间请求参数  [开始时间,  结束时间]
            Date[] queryDateRangeArray = DateKit.getQueryDateRange(dateRange);
            if (StringUtils.isEmpty(dateRange)) {   // 如果未传入参数默认为当天
                // 今日时间范围
                queryDateRangeArray = DateKit.getQueryDateRange("today");
            }

            createdStart = DateUtil.formatDateTime(queryDateRangeArray[0]);
            createdEnd = DateUtil.formatDateTime(queryDateRangeArray[1]);
        }
        JSONObject result = new JSONObject();

        // 服务商总数
        long agentAllCount = count(AgentInfo.gw()
                .eq(StringUtils.isNotBlank(agentNo), AgentInfo::getPid, agentNo)
                .in(CollUtil.isNotEmpty(agentSubList), AgentInfo::getPid, agentSubList)
        );
        result.put("agentAllCount", agentAllCount);

        // 新增服务商数
        long agentNewCount = count(AgentInfo.gw()
                .eq(StringUtils.isNotBlank(agentNo), AgentInfo::getPid, agentNo)
                .in(CollUtil.isNotEmpty(agentSubList), AgentInfo::getPid, agentSubList)
                .ge(StringUtils.isNotEmpty(createdStart), AgentInfo::getCreatedAt, createdStart)
                .le(StringUtils.isNotEmpty(createdEnd), AgentInfo::getCreatedAt, createdEnd)
        );

        result.put("agentNewCount", agentNewCount);
        // 活动服务商数
        long agentOnCount = count(AgentInfo.gw()
                .eq(StringUtils.isNotBlank(agentNo), AgentInfo::getPid, agentNo)
                .in(CollUtil.isNotEmpty(agentSubList), AgentInfo::getPid, agentSubList)
                .eq(AgentInfo::getState, CS.YES)
                .ge(StringUtils.isNotEmpty(createdStart), AgentInfo::getCreatedAt, createdStart)
                .le(StringUtils.isNotEmpty(createdEnd), AgentInfo::getCreatedAt, createdEnd)
        );
        result.put("agentOnCount", agentOnCount);
        return result;
    }


    /**
     * 更新服务商信息， 返回需要清除登录信息的userIdSet
     **/
    @Transactional
    public Set<Long> updateAgent(AgentInfo updateInfo, JSONObject updateJson, boolean resetPass, String confirmPwd) {

        // 待删除用户登录信息的ID list
        Set<Long> removeCacheUserIdList = new HashSet<>();

        // 如果商户状态为禁用状态，清除该商户用户登录信息
        if (updateInfo.getState() == CS.NO) {
            sysUserService.list(SysUserEntity.gw().select(SysUserEntity::getSysUserId).eq(SysUserEntity::getBelongInfoId, updateInfo.getAgentNo()).eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.AGENT)).forEach(u -> removeCacheUserIdList.add(u.getSysUserId()));
        }

        // 获取商户超管
        Long agentAdminUserId = sysUserService.findAgentAdminUserId(updateInfo.getAgentNo());


        //判断是否重置密码
        if (resetPass) {

            //删除超管登录信息
            removeCacheUserIdList.add(agentAdminUserId);

        }

        // 转换钱包冻结金额
        if (updateJson != null && StringUtils.isNotBlank(updateJson.getString("freezeAmount"))) {
            updateInfo.setFreezeAmount(AmountUtil.convertDollar2CentLong(updateJson.getString("freezeAmount")));
            // 没有冻结金额时，清除冻结原因
            updateInfo.setFreezeDesc(updateInfo.getFreezeAmount() > 0 ? updateInfo.getFreezeDesc() : "");
        }

        //重置超管 手机号 & 密码
        sysUserService.resetUserAndAuthInfo(agentAdminUserId, null, updateInfo.getContactTel(), resetPass, confirmPwd, CS.SYS_ROLE_TYPE.AGENT);

        //更新商户信息
        if (!updateById(updateInfo)) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
        }

        return removeCacheUserIdList;
    }

    /**
     * 服务商审核
     **/
    @Transactional
    public void auditInfo(String agentNo, Byte auditState, String auditRemark) {

        AgentInfo agentInfo = getById(agentNo);
        if (agentInfo == null) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }

        AgentInfo updateInfo = new AgentInfo();
        updateInfo.setAgentNo(agentNo);

        // 审核通过
        if (CS.YES == auditState) {
            updateInfo.setState(CS.YES);
            updateInfo.setAuditRemark("");
        } else {
            updateInfo.setAuditRemark(auditRemark);
            updateInfo.setState(AgentInfo.AUDIT_STATE_FALSE);
        }
        boolean update = updateById(updateInfo);

        if (!update) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
        }
    }

    /**
     * 服务商注册
     **/
    @Transactional(rollbackFor = Exception.class)
    public void mchRegister(String phone, String loginPassword, String agentName, String inviteCode) {

        // 判断是否邀请码必填
        SysConfig agentRegisterInviteCodeRequired = sysConfigService.getById("agentRegisterInviteCodeRequired");
        if (agentRegisterInviteCodeRequired != null && "1".equals(agentRegisterInviteCodeRequired.getConfigVal()) && StringUtils.isBlank(inviteCode)) {
            throw new BizException("请填写邀请码");
        }

        String pid = null; // 注册时邀请码对应的上级服务商号
        String pName = null; // 注册时邀请码对应的上级服务商名称
        Long inviteSysUserId = null; // 商户邀请者ID
        String inviteRealName = null; // 商户邀请者姓名

        // 邀请者信息
        if (StringUtils.isNotBlank(inviteCode)) {
            SysUserEntity sysUserEntity = sysUserService.getById(InviteCodeUtil.codeToId(inviteCode));
            if (sysUserEntity == null) {
                throw new BizException("邀请码错误");
            }
            inviteSysUserId = sysUserEntity.getSysUserId();
            inviteRealName = sysUserEntity.getRealname();

            // 邀请码对应的服务商信息
            if (sysUserEntity.getSysType().equals(CS.SYS_ROLE_TYPE.AGENT)) {
                AgentInfo agentInfo = getById(sysUserEntity.getBelongInfoId());
                if (agentInfo == null) {
                    throw new BizException("邀请码错误");
                }
                pid = agentInfo.getAgentNo();
                // pid对应的服务商是否允许发展下级代理
                if (agentInfo.getAddAgentFlag() != CS.YES) {
                    throw new BizException("无效服务商[所填邀请码不可用]");
                }
                pName = agentInfo.getAgentShortName();
            }
            // 邀请码对应的平台用户
            else if (sysUserEntity.getSysType().equals(CS.SYS_ROLE_TYPE.PLATFORM)) {
                JSONObject defaultIsvJson = sysConfigService.selectByGroupKey("defaultConfig");
                if (defaultIsvJson == null) {
                    throw new BizException("平台未配置服务商");
                }
                pid = defaultIsvJson.getString("defaultIsvNo");
                if (StringUtils.isEmpty(pid)) {
                    throw new BizException("平台未配置默认服务商");
                }
            } else {
                throw new BizException("邀请码错误");
            }

        } else {
            // 平台默认服务商配置
            DBDefaultConfig defaultConfig = sysConfigService.getDBDefaultConfig();
            if (defaultConfig == null) {
                throw new BizException("平台未配置服务商");
            }

            pid = defaultConfig.getDefaultAgentNo();
            if (ObjectUtils.isEmpty(pid)) {
                throw new BizException("平台未配置默认服务商");
            }
        }


        /* 参数校验 **/
        if (StringUtils.isEmpty(phone)) {
            throw new BizException("手机号不能为空");
        }
        if (StringUtils.isEmpty(loginPassword)) {
            throw new BizException("密码不能为空");
        }

        AgentInfo agentInfo = new AgentInfo();
        agentInfo.setAgentNo(SeqKit.genAgentNo());
        agentInfo.setAgentName(agentName);
        agentInfo.setAgentShortName(agentName);
        agentInfo.setLevel(2);
        agentInfo.setAddAgentFlag(CS.YES);
        agentInfo.setAddMchFlag(CS.YES);
        agentInfo.setLoginUsername("a" + phone);
        agentInfo.setContactTel(phone);
        agentInfo.setContactName(agentName);
        // 邀请者对应的服务商信息
        agentInfo.setPid(pid);
        agentInfo.setPidArr(pid);
        agentInfo.setPname(pName);

        // 服务商等级
        agentInfo.setLevel(1); //一级服务商
        // 包含上级服务商
        if (StringUtils.isNotEmpty(agentInfo.getPid())) {
            AgentInfo parentAgent = getById(agentInfo.getPid());
            agentInfo.setLevel(parentAgent.getLevel() + 1);
        }

        // 创建者/邀请者信息
        agentInfo.setCreatedUid(inviteSysUserId);
        agentInfo.setCreatedBy(inviteRealName);
        // 查询配置是否需要审核
        SysConfig sysConfig = sysConfigService.getById("agentRegisterIsAudit");

        if (sysConfig != null && "1".equals(sysConfig.getConfigVal())) {
            // 待平台审核
            agentInfo.setState(AgentInfo.AUDIT_STATE_UN_AUTH);
        }

        // 插入商户基本信息
        boolean saveResult = save(agentInfo);
        if (!saveResult) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }

        // 插入用户信息
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setLoginUsername(agentInfo.getLoginUsername());
        sysUserEntity.setRealname(agentInfo.getContactName());
        sysUserEntity.setTelphone(agentInfo.getContactTel());
        sysUserEntity.setUserNo(agentInfo.getAgentNo());
        sysUserEntity.setBelongInfoId(agentInfo.getAgentNo());
        sysUserEntity.setSex(CS.SEX_MALE);
        sysUserEntity.setUserType(com.jeequan.jeepay.core.entity.SysUser.UEST_TYPE_ADMIN);
        sysUserEntity.setState(CS.YES);
        sysUserService.addSysUser(sysUserEntity, CS.SYS_ROLE_TYPE.AGENT, loginPassword);

        // 存入服务商的默认用户ID
        AgentInfo updateRecord = new AgentInfo();
        updateRecord.setAgentNo(agentInfo.getAgentNo());
        updateRecord.setInitUserId(sysUserEntity.getSysUserId());
        saveResult = updateById(updateRecord);
        if (!saveResult) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }

        // 初始化账户数据
        infoAccountService.initAgentAccount(agentInfo.getAgentNo());

        // 服务商的默认费率
        List<RateConfig> rateConfigList;

        // 包含服务商
        if (StringUtils.isNotEmpty(agentInfo.getPid())) {

            // 查询上级服务商的
            rateConfigList = rateConfigMapper.selectList(RateConfig.gw()
                    .eq(RateConfig::getInfoId, RateConfig.appendInfoByAgentDef(agentInfo.getPid()))
                    .eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.AGENT)
            );
        } else {
            // 查询服务商的默认费率
            rateConfigList = rateConfigMapper.selectList(RateConfig.gw()
                    .eq(RateConfig::getInfoId, RateConfig.appendInfoByAgentDef(agentInfo.getIsvNo()))
                    .eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
            );
        }

        for (RateConfig rateConfig : rateConfigList) {
            rateConfig.setInfoId(RateConfig.appendInfoByAgent(agentInfo.getAgentNo()));
            rateConfig.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
            rateConfig.setUpdatedAt(null);
            rateConfig.setUpdatedAt(null);
            rateConfigMapper.insert(rateConfig);
        }

        List<IsvUserConnEntity> userConnEntityList = isvUserConnService.getSuperiorConnInfo(CS.SYS_ROLE_TYPE.AGENT, agentInfo.getAgentNo());
        isvUserConnService.saveBatch(userConnEntityList);
    }

    /**
     * 服务商列表统计
     **/
    public Map<String, Object> countByAccount(LambdaQueryWrapper<AgentInfo> wrapper) {
        return baseMapper.countByAccount(wrapper);
    }
}
