package com.qmth.sop.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.sop.business.bean.dto.DataPermissionDto;
import com.qmth.sop.business.bean.dto.RoleDto;
import com.qmth.sop.business.bean.dto.SopCrmInfo;
import com.qmth.sop.business.bean.dto.UserArchivesDto;
import com.qmth.sop.business.bean.params.ServiceScopeParam;
import com.qmth.sop.business.bean.result.*;
import com.qmth.sop.business.entity.*;
import com.qmth.sop.business.mapper.TBCrmMapper;
import com.qmth.sop.business.service.*;
import com.qmth.sop.business.sync.FxxkApiUtils;
import com.qmth.sop.business.sync.been.fxxk.FxxkCrm;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.*;
import com.qmth.sop.common.util.ResultUtil;
import com.qmth.sop.common.util.ServletUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 派单信息表 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2023-08-01
 */
@Service
public class TBCrmServiceImpl extends ServiceImpl<TBCrmMapper, TBCrm> implements TBCrmService {

    @Resource
    private TBServiceService tbServiceService;

    @Resource
    private TBUserArchivesAllocationService tbUserArchivesAllocationService;

    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private TBUserArchivesService tbUserArchivesService;

    @Resource
    private TBServiceRegionDetailService tbServiceRegionDetailService;

    @Resource
    private SysUserService sysUserService;

    @Resource
    private FxxkApiUtils fxxkApiUtils;

    @Resource
    private SysCustomService sysCustomService;

    @Resource
    private TBProductService tbProductService;

    @Override
    public IPage<CrmServiceResult> findServiceScopePage(Long serviceUnitId, String city, ProductTypeEnum productType,
            String customName, Boolean bindStatus, Integer pageNumber, Integer pageSize) {
        if (city != null && city.length() > 0) {
            city = SystemConstant.translateSpecificSign(city);
        }
        if (customName != null && customName.length() > 0) {
            customName = SystemConstant.translateSpecificSign(customName);
        }
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
        return this.baseMapper.findServiceScopePage(new Page<>(pageNumber, pageSize), serviceUnitId, city, productType,
                customName, bindStatus, dpr);
    }

    @Override
    public IPage<CrmServiceResult> findUnbindOrderPage(Long crmUserId, ProductTypeEnum productType, String customName,
            String crmNo, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
        if (customName != null && customName.length() > 0) {
            customName = SystemConstant.translateSpecificSign(customName);
        }
        if (crmNo != null && crmNo.length() > 0) {
            crmNo = SystemConstant.translateSpecificSign(crmNo);
        }
        return this.baseMapper.findUnbindOrderPage(new Page<>(pageNumber, pageSize), crmUserId, productType, customName,
                crmNo, startTime, endTime);
    }

    @Override
    public List<CrmServiceResult> findCrmOrderByServiceIdList(List<Long> serviceIdList) {
        return this.baseMapper.findOrderListByServiceIds(serviceIdList);
    }

    @Transactional
    @Override
    public void bindCrmWithServiceBatch(ServiceScopeParam serviceScopeParam) {
        List<Long> crmIdList = serviceScopeParam.getCrmIdList();
        Long serviceUnitId = serviceScopeParam.getServiceUnitId();
        if (CollectionUtils.isEmpty(crmIdList)) {
            throw ExceptionResultEnum.ERROR.exception("未选择要划定的派单");
        }

        TBService tbService = tbServiceService.getById(serviceUnitId);
        if (Objects.isNull(tbService) || !tbService.getEnable()) {
            throw ExceptionResultEnum.ERROR.exception("服务单元不存在");
        } else {
            ServiceStatusEnum status = tbService.getStatus();
            if (ServiceStatusEnum.FINISH.equals(status) || ServiceStatusEnum.CANCEL.equals(status)) {
                throw ExceptionResultEnum.ERROR.exception("不能划定进已完结或已作废的服务单元");
            }
        }
        List<TBCrm> tbCrmList = this.listByIds(crmIdList);
        // 派单调配资源变换
        for (TBCrm dbCrm : tbCrmList) {
            this.crmReBindServiceUnit(dbCrm.getCrmNo(), dbCrm.getServiceId(), serviceUnitId);
        }
    }

    @Transactional
    @Override
    public void unbindCrmWithService(Long crmId) {
        TBCrm tbCrm = this.getById(crmId);
        if (Objects.isNull(tbCrm)) {
            throw ExceptionResultEnum.ERROR.exception("未找到派单信息");
        }
        Long serviceUnitId = tbCrm.getServiceId();
        TBService tbService = tbServiceService.getById(serviceUnitId);
        if (Objects.nonNull(tbService)) {
            ServiceStatusEnum status = tbService.getStatus();
            if (ServiceStatusEnum.FINISH.equals(status)) {
                throw ExceptionResultEnum.ERROR.exception("服务单元的当前状态更新为" + ServiceStatusEnum.FINISH.name() + "不允许移除");
            }
        }
        this.crmReBindServiceUnit(tbCrm.getCrmNo(), serviceUnitId, null);
    }

    @Override
    public CrmSubTotalResult findCrmSubTotalData(Long serviceUnitId, String city, ProductTypeEnum productType, String customName, Boolean bindStatus) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
        List<CrmServiceResult> crmServiceResultList = this.baseMapper.findServiceScopeList(serviceUnitId, city,
                productType, customName, bindStatus, dpr);
        int totalCrmCount = crmServiceResultList.size();
        int bindCrmCount = 0;
        int unbindCrmCount = 0;
        if (totalCrmCount > 0) {
            bindCrmCount = (int) crmServiceResultList.stream().filter(e -> e.getServiceUnitId() != null).count();
            unbindCrmCount = (int) crmServiceResultList.stream().filter(e -> e.getServiceUnitId() == null).count();
        }
        CrmSubTotalResult crmSubTotalResult = new CrmSubTotalResult();
        crmSubTotalResult.setTotalCrmCount(totalCrmCount);
        crmSubTotalResult.setBindCrmCount(bindCrmCount);
        crmSubTotalResult.setUnbindCrmCount(unbindCrmCount);
        return crmSubTotalResult;
    }

    @Override
    public TBCrm findByCrmNo(String crmNo) {
        List<TBCrm> tbCrmList = this.list(
                new QueryWrapper<TBCrm>().lambda().eq(TBCrm::getCrmNo, crmNo).eq(TBCrm::getEnable, true));
        if (CollectionUtils.isEmpty(tbCrmList)) {
            throw ExceptionResultEnum.ERROR.exception("派单不存在[" + crmNo + "]");
        }
        if (tbCrmList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception("有重复派单号[" + crmNo + "]");
        }
        return tbCrmList.get(0);
    }

    @Override
    public IPage<TBCrmResult> query(IPage<Map> iPage, Long serviceId, Boolean isBind, Long leadId, Long crmUserId,
            ProductTypeEnum type, String custom, String crmNo, Long startTime, Long endTime) {
        if (custom != null && custom.length() > 0) {
            custom = SystemConstant.translateSpecificSign(custom);
        }
        if (crmNo != null && crmNo.length() > 0) {
            crmNo = SystemConstant.translateSpecificSign(crmNo);
        }
        return this.baseMapper.query(iPage, serviceId, isBind, leadId, crmUserId,
                Objects.nonNull(type) ? type.name() : null, custom, crmNo, startTime, endTime);
    }

    @Override
    public int count(Long serviceId, Boolean isBind, Long leadId, Long crmUserId, ProductTypeEnum type, String custom,
            String crmNo, Long startTime, Long endTime) {
        if (custom != null && custom.length() > 0) {
            custom = SystemConstant.translateSpecificSign(custom);
        }
        if (crmNo != null && crmNo.length() > 0) {
            crmNo = SystemConstant.translateSpecificSign(crmNo);
        }
        return this.baseMapper.count(serviceId, isBind, leadId, crmUserId, Objects.nonNull(type) ? type.name() : null,
                custom, crmNo, startTime, endTime);
    }

    /**
     * 新增修改派单信息表
     *
     * @param tBCrm tBCrm
     */
    @Override
    @Transactional
    public Boolean saveTBCrm(TBCrm tBCrm) {
        try {
            Long oldServiceUnitId = null;
            tBCrm.setSync(false);
            tBCrm.setEnable(true);
            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
            if (Objects.isNull(tBCrm.getId())) {// 新增
                tBCrm.setStatus(CrmStatusEnum.UN_PUBLISH);
                tBCrm.insertInfo(sysUser.getId());
            } else { // 修改
                TBCrm dbTBCrm = this.getById(tBCrm.getId());
                if (Objects.isNull(dbTBCrm)) {
                    throw ExceptionResultEnum.ERROR.exception("未找到派单信息");
                }
                oldServiceUnitId = dbTBCrm.getServiceId();
                tBCrm.updateInfo(sysUser.getId());
            }
            boolean result = saveOrUpdate(tBCrm);
            Long serviceId = tBCrm.getServiceId();
            if (result) {
                this.crmReBindServiceUnit(tBCrm.getCrmNo(), oldServiceUnitId, serviceId);
            }

            return result;
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                String errorColumn = e.getCause().toString();
                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3).replaceAll("'", "");
                throw ExceptionResultEnum.SQL_ERROR.exception("[" + FieldUniqueEnum.convertToTitle(columnStr) + "]数据不允许重复插入");
            } else if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return null;
    }

    /**
     * 删除派单信息表
     *
     * @param id id
     */
    @Override
    @Transactional
    public Boolean delete(Long id) {
        return this.removeById(id);
    }

    @Override
    @Transactional
    public boolean batchDisable(long[] crmIds) {
        //批量修改
        List<Long> crmIdList = Arrays.stream(crmIds).boxed().collect(Collectors.toList());
        List<TBCrm> tbCrmList = this.listByIds(crmIdList);
        for (TBCrm tbCrm : tbCrmList) {
            Long serviceId = tbCrm.getServiceId();
            if (serviceId != null && serviceId > 0) {
                throw ExceptionResultEnum.ERROR.exception(String.format("已经划分的派单[%s]不能作废", tbCrm.getCrmNo()));
            }
            tbCrm.setEnable(false);
        }

        return this.updateBatchById(tbCrmList);
    }

    @Override
    public CrmProjectResult findCrmProjectBySopNoOrCrmNo(String sopNo, String crmNo) {
        CrmProjectResult result = new CrmProjectResult();
        List<CrmProjectResult> crmProjectResults;
        if (sopNo != null && sopNo.length() > 0) {
            crmProjectResults = this.baseMapper.findCrmProjectBySopNo(sopNo);
        } else if (crmNo != null && crmNo.length() > 0) {
            crmProjectResults = this.baseMapper.findCrmProjectByCrmNo(crmNo);
        } else {
            throw ExceptionResultEnum.ERROR.exception("缺少sop单号和crm单号");
        }
        if (CollectionUtils.isNotEmpty(crmProjectResults)) {
            if (crmProjectResults.size() > 1) {
                throw ExceptionResultEnum.ERROR.exception("根据sop号找到多个与之对应的派单异常");
            }
            CrmProjectResult crmProjectResult = crmProjectResults.get(0);
            String tbCrmNo = crmProjectResult.getCrmNo();

            List<TBUserArchivesAllocation> archivesAllocationList = tbUserArchivesAllocationService.list(
                    new QueryWrapper<TBUserArchivesAllocation>().lambda().eq(TBUserArchivesAllocation::getCrmNo, tbCrmNo));

            RoleResult effectRole = sysRoleService.findRoleInfoByArchivesType(RoleTypeEnum.EFFECT_ENGINEER);
            Long effectRoleId = effectRole.getRoleId();

            List<UserArchivesDto> effectEngineerList = archivesAllocationList.stream()
                    .filter(e -> effectRoleId.equals(e.getRoleId())).flatMap(e -> {
                        UserArchivesDto dto = new UserArchivesDto();
                        Long userArchivesId = e.getArchivesId();
                        dto.setUserArchivesId(userArchivesId);
                        dto.setUserId(e.getUserId());
                        dto.setName(tbUserArchivesService.getById(userArchivesId).getName());
                        return Stream.of(dto);
                    }).collect(Collectors.toList());

            RoleResult assistant = sysRoleService.findRoleInfoByArchivesType(RoleTypeEnum.ASSISTANT_ENGINEER);
            Long assistantRoleId = assistant.getRoleId();
            List<UserArchivesDto> assistantEngineerList = archivesAllocationList.stream()
                    .filter(e -> assistantRoleId.equals(e.getRoleId())).flatMap(e -> {
                        UserArchivesDto dto = new UserArchivesDto();
                        Long userArchivesId = e.getArchivesId();
                        dto.setUserArchivesId(userArchivesId);
                        dto.setUserId(e.getUserId());
                        dto.setName(tbUserArchivesService.getById(userArchivesId).getName());
                        return Stream.of(dto);
                    }).collect(Collectors.toList());
            crmProjectResult.setEffectEngineerList(effectEngineerList);
            crmProjectResult.setAssistantEngineerList(assistantEngineerList);
            result = crmProjectResult;
        }
        return result;
    }

    @Override
    public SopCrmInfo findSopCrmInfoBySop(String sopNo) {
        List<SopCrmInfo> sopCrmInfoList = this.baseMapper.findSopCrmInfoBySopNo(sopNo);
        if (CollectionUtils.isEmpty(sopCrmInfoList)) {
            //            throw ExceptionResultEnum.ERROR.exception(String.format("未找到sop单号为[%s]的派单信息", sopNo));
            return null;
        } else if (sopCrmInfoList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception(String.format("sop单号为[%s]的派单信息异常", sopNo));
        }
        return sopCrmInfoList.get(0);
    }

    @Override
    public List<TBCrm> findOccupiedCrm(Long userId, Long userArchivesId) {
        return this.baseMapper.findOccupiedCrm(userId, userArchivesId);
    }

    @Override
    public List<TBCrm> findAllCrm(Long userId, Long userArchivesId) {
        return this.baseMapper.findAllCrm(userId, userArchivesId);
    }

    @Transactional
    @Override
    public void updateCrmStatus(String crmNo, CrmStatusEnum status) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        TBCrm tbCrm = this.findByCrmNo(crmNo);
        switch (status) {
        case UN_PUBLISH: // 撤回
            tbCrm.setStatus(CrmStatusEnum.UN_PUBLISH);
            break;
        case PUBLISH: // 发布
            tbCrm.setStatus(CrmStatusEnum.PUBLISH);
            tbCrm.setPublishUserId(requestUser.getId());
            tbCrm.setPublishTime(System.currentTimeMillis());
            break;
        case FINISH: // 完结
            tbCrm.setStatus(CrmStatusEnum.FINISH);
            // crm完结 释放工程师资源
            List<CrmArchivesAllocationResult> crmArchivesAllocationResultList = tbUserArchivesAllocationService.findAllocationByCrmNo(
                    crmNo);
            List<Long> engineerArchivesIdList = crmArchivesAllocationResultList.stream().filter(e -> !RoleTypeEnum.REGION_COORDINATOR.equals(e.getType()))
                    .map(CrmArchivesAllocationResult::getArchivesId).distinct().collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(engineerArchivesIdList)) {
                UpdateWrapper<TBUserArchives> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().set(TBUserArchives::getStatus, UserArchivesStatusEnum.FREE).in(TBUserArchives::getId, engineerArchivesIdList);
                tbUserArchivesService.update(updateWrapper);
            }
            break;
        }
        this.updateById(tbCrm);
    }

    @Override
    public List<TBCrm> findByTBCrmListByServiceUnitIdAndAddress(Long serviceUnitId, String province, String city) {
        return this.baseMapper.findByTBCrmListByServiceUnitIdAndAddress(serviceUnitId, province, city);
    }

    @Transactional
    @Override
    public void crmReBindServiceUnit(String crmNo, Long oldServiceUnitId, Long newServiceUnitId) {
        TBCrm tbCrm = this.findByCrmNo(crmNo);
        if (CrmStatusEnum.PUBLISH.equals(tbCrm.getStatus())) {
            throw ExceptionResultEnum.ERROR.exception(String.format("已发布的派单[%s]不能重新划分，请先撤销发布", tbCrm.getCrmNo()));
        }

        if (oldServiceUnitId != null && oldServiceUnitId > 0) {
            // 之前派单有划定在服务单元 -> 解绑派单所有资源信息
            List<TBUserArchivesAllocation> dbAllocationList = tbUserArchivesAllocationService.list(
                    new QueryWrapper<TBUserArchivesAllocation>().lambda().eq(TBUserArchivesAllocation::getCrmNo, crmNo).eq(TBUserArchivesAllocation::getServiceId, oldServiceUnitId));

            if (CollectionUtils.isNotEmpty(dbAllocationList)) {
                // 释放工程师资源
                List<Long> archivesIdList = dbAllocationList.stream().map(TBUserArchivesAllocation::getArchivesId).distinct().collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(archivesIdList)) {
                    UpdateWrapper<TBUserArchives> archivesUpdateWrapper = new UpdateWrapper<>();
                    archivesUpdateWrapper.lambda().in(TBUserArchives::getId, archivesIdList)
                            .set(TBUserArchives::getStatus, UserArchivesStatusEnum.FREE);
                    tbUserArchivesService.update(archivesUpdateWrapper);
                }
                // 删除之前的派单分配详情
                tbUserArchivesAllocationService.removeByIds(
                        dbAllocationList.stream().map(TBUserArchivesAllocation::getId).distinct().collect(Collectors.toList()));
            }
            UpdateWrapper<TBCrm> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(TBCrm::getId, tbCrm.getId()).set(TBCrm::getServiceId, null)
                    .set(TBCrm::getLeadId, null).set(TBCrm::getRegionId, null).set(TBCrm::getRegionDetailId, null)
                    .set(TBCrm::getRegionCoordinatorId, null);
            this.update(updateWrapper);
        }
        if (newServiceUnitId != null && newServiceUnitId > 0) {
            // 为派单划定的新服务单元绑定大区信息
            UpdateWrapper<TBCrm> bindServiceWrapper = new UpdateWrapper<>();
            bindServiceWrapper.lambda().eq(TBCrm::getId, tbCrm.getId()).set(TBCrm::getServiceId, newServiceUnitId);
            this.update(bindServiceWrapper);

            ServiceRegionDetailResult regionDetail = tbServiceRegionDetailService.findRegionDetail(newServiceUnitId,
                    crmNo);
            if (Objects.nonNull(regionDetail)) {
                UpdateWrapper<TBCrm> matchWrapper = new UpdateWrapper<>();
                matchWrapper.lambda().eq(TBCrm::getId, tbCrm.getId()).set(TBCrm::getLeadId, regionDetail.getLeadId())
                        .set(TBCrm::getRegionId, regionDetail.getServiceRegionId())
                        .set(TBCrm::getRegionDetailId, regionDetail.getServiceRegionDetailId());
                this.update(matchWrapper);
            }
        }
    }

    @Transactional
    @Override
    public Map<String, Object> syncCrmFromFxxk(Map<String, Object> map) {
        SysUser requestUser = (SysUser) map.get(SystemConstant.USER);
        // 已有派单信息
        List<TBCrm> tbCrmList = this.list();
        List<String> crmNoList = tbCrmList.stream().map(TBCrm::getCrmNo).collect(Collectors.toList());

        List<String> errorMsgList = new ArrayList<>();
        List<FxxkCrm> fxxkCrmList = fxxkApiUtils.findCustomList();
        int totalCount = fxxkCrmList.size();
        // 成功同步的派单数
        int successCount = 0;
        // 已有的派单数（派单号相同不重新同步）
        int alreadyCount = 0;
        try {
            for (FxxkCrm fxxkCrm : fxxkCrmList) {
                String basicInfoMissingError = "";
                String crmNo = fxxkCrm.getCrmNo();
                if (crmNoList.contains(crmNo)) {
                    alreadyCount++;
                    continue;
                }
                String crmName = fxxkCrm.getCrmName();
                Long beginTime = fxxkCrm.getBeginTime();
                String managerName = fxxkCrm.getManagerName();
                String managerMobileNumber = fxxkCrm.getManagerMobileNumber();
                ProductTypeEnum customType = fxxkCrm.getCustomType();
                String customName = fxxkCrm.getCustomName();
                Long examStartTime = fxxkCrm.getExamStartTime();
                Long examEndTime = fxxkCrm.getExamEndTime();

                if (crmName == null || crmName.length() == 0) {
                    basicInfoMissingError = basicInfoMissingError + "缺少派单名称";
                }
                if (beginTime == null || beginTime == 0) {
                    basicInfoMissingError = basicInfoMissingError + "缺少派单开始时间";
                }
                if (managerName == null || managerName.length() == 0) {
                    basicInfoMissingError = basicInfoMissingError + "缺少客户经理";
                }
                if (managerMobileNumber == null || managerMobileNumber.length() == 0) {
                    basicInfoMissingError = basicInfoMissingError + "缺少客户经理电话";
                }
                if (customType == null) {
                    basicInfoMissingError = basicInfoMissingError + "缺少客户类型或客户类型不为['高校教务处'或'研究生招办']";
                }
                if (customName == null || customName.length() == 0) {
                    basicInfoMissingError = basicInfoMissingError + "缺少客户名称";
                }
                if (examStartTime == null || examStartTime == 0) {
                    basicInfoMissingError = basicInfoMissingError + "缺少考试开始时间";
                }
                if (examEndTime == null || examEndTime == 0) {
                    basicInfoMissingError = basicInfoMissingError + "缺少考试结束时间";
                }
                if (basicInfoMissingError.length() > 0) {
                    // fxxk 项目派单基础信息缺失异常 -> 补充fxxk系统的派单基础信息
                    basicInfoMissingError = String.format("纷享销客派单[%s]基础信息异常请补充: %s \n", crmNo, basicInfoMissingError);
                    errorMsgList.add(basicInfoMissingError);
                } else {
                    // 基础信息正常再继续解析需要和质控平台对接的信息
                    String matchInfoError = "";

                    // 客户经理校验
                    Long crmUserId = null;
                    SysUser sysUser = sysUserService.getOne(
                            new QueryWrapper<SysUser>().lambda().eq(SysUser::getMobileNumber, managerMobileNumber).eq(SysUser::getRealName, managerName));
                    if (Objects.isNull(sysUser) || !sysUser.getEnable()) {
                        matchInfoError = matchInfoError + String.format("纷享销客中的客户经理[%s(%s)]在质控平台不存在或已禁用(姓名 + 手机号)\n",
                                managerName, managerMobileNumber);
                    } else {
                        List<RoleDto> roleDtoList = sysRoleService.listRolesByUserId(sysUser.getId());
                        if (roleDtoList.stream().noneMatch(e -> RoleTypeEnum.ACCOUNT_MANAGER.equals(e.getType()))) {
                            matchInfoError =
                                    matchInfoError + String.format("纷享销客中的客户经理[%s(%s)]在质控平台缺少[%s]角色)\n", managerName,
                                            managerMobileNumber, RoleTypeEnum.ACCOUNT_MANAGER);
                        } else {
                            crmUserId = sysUser.getId();
                        }
                    }

                    // 客户名称校验
                    Long customId = null;
                    List<SysCustom> sysCustomList = sysCustomService.list(
                            new QueryWrapper<SysCustom>().lambda().eq(SysCustom::getName, customName).eq(SysCustom::getType, customType).eq(SysCustom::getEnable, true));

                    if (CollectionUtils.isEmpty(sysCustomList)) {
                        matchInfoError = matchInfoError + String.format("纷享销客中的客户[%s(%s)]在质控平台不存在或已禁用(客户名称 + 客户类型)\n",
                                customName, customType.getTitle());
                    } else if (sysCustomList.size() > 1) {
                        throw ExceptionResultEnum.ERROR.exception("客户数据异常 ：客户名称-客户类型 不唯一\n");
                    } else {
                        SysCustom sysCustom = sysCustomList.get(0);
                        customId = sysCustom.getId();
                    }

                    // 实施产品校验
                    Long productId = null;
                    List<TBProduct> tbProductList = tbProductService.list(
                            new QueryWrapper<TBProduct>().lambda().eq(TBProduct::getEnable, true));
                    if (CollectionUtils.isEmpty(tbProductList)) {
                        matchInfoError = matchInfoError + "质控平台缺少可用产品\n";
                    } else {
                        productId = tbProductList.get(0).getId();
                    }
                    if (matchInfoError.length() > 0) {
                        // 质控平台基础信息缺失异常 -> 补充质控平台系统的派单相关信息
                        matchInfoError = String.format("纷享销客派单[%s]中的相关信息在质控平台中缺失,请先补充质控平台系统的派单相关信息: %s \n", crmNo,
                                matchInfoError);
                        errorMsgList.add(matchInfoError);
                    } else {
                        // 新增
                        TBCrm tbCrm = new TBCrm();
                        tbCrm.setCrmNo(crmNo);
                        tbCrm.setName(crmName);
                        tbCrm.setBeginTime(beginTime);
                        tbCrm.setCrmUserId(crmUserId);
                        tbCrm.setCustomId(customId);
                        tbCrm.setExamStartTime(examStartTime);
                        tbCrm.setExamEndTime(examEndTime);
                        tbCrm.setProductId(productId);
                        tbCrm.setSync(true);
                        tbCrm.setEnable(true);
                        tbCrm.setStatus(CrmStatusEnum.UN_PUBLISH);
                        tbCrm.insertInfo(requestUser.getId());
                        tbCrm.updateInfo(requestUser.getId());
                        this.save(tbCrm);
                        successCount++;
                    }
                }
            }
            String errorMsg = "";
            if (errorMsgList.size() > 0) {
                errorMsg = String.join(";\n", errorMsgList);
            }
            map.put(SystemConstant.SUCCESS, successCount);
            map.put(SystemConstant.RESULT_ERROR, totalCount - successCount - alreadyCount);
            map.put(SystemConstant.ALREADY_COUNT, alreadyCount);
            map.put(SystemConstant.ERROR_MSG, errorMsg);
            return map;
        } catch (Exception e) {
            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
        }
    }
}
