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.sop.business.activiti.service.ActivitiService;
import com.qmth.sop.business.bean.dto.DataPermissionDto;
import com.qmth.sop.business.bean.params.AllocationParam;
import com.qmth.sop.business.bean.params.AutoAllocationParam;
import com.qmth.sop.business.bean.params.SopPublishParam;
import com.qmth.sop.business.bean.params.UserArchivesAllocationParam;
import com.qmth.sop.business.bean.result.*;
import com.qmth.sop.business.entity.*;
import com.qmth.sop.business.mapper.TBUserArchivesAllocationMapper;
import com.qmth.sop.business.service.*;
import com.qmth.sop.common.base.BaseEntity;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.*;
import com.qmth.sop.common.util.ServletUtil;
import org.apache.commons.collections4.CollectionUtils;
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 TBUserArchivesAllocationServiceImpl extends ServiceImpl<TBUserArchivesAllocationMapper, TBUserArchivesAllocation> implements TBUserArchivesAllocationService {
    @Resource
    private TBServiceService tbServiceService;
    @Resource
    private TBCrmService tbCrmService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private TBUserArchivesService tbUserArchivesService;
    @Resource
    private TBSopInfoService tbSopInfoService;
    @Resource
    private TFCustomFlowService tfCustomFlowService;
    @Resource
    private ActivitiService activitiService;
    @Resource
    private SysUserService sysUserService;

    @Override
    public IPage<UserArchivesAllocationResult> findCrmAllocationPage(Long serviceUnitId, String province, String city, String area, String customName, Integer gap, Long regionId, Integer pageNumber, Integer pageSize) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        Long userId = requestUser.getId();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(userId);

        province = SystemConstant.translateSpecificSign(province);
        city = SystemConstant.translateSpecificSign(city);
        area = SystemConstant.translateSpecificSign(area);
        customName = SystemConstant.translateSpecificSign(customName);
        return this.baseMapper.findCrmAllocationPage(new Page<>(pageNumber, pageSize), serviceUnitId, province, city, area, customName, gap, regionId, dpr);
    }

    @Override
    public UserArchivesAllocationSubTotalResult findCrmAllocationSubTotal(Long serviceUnitId, String province, String city, String area, String customName, Integer gap, Long regionId) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        Long userId = requestUser.getId();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(userId);

        province = SystemConstant.translateSpecificSign(province);
        city = SystemConstant.translateSpecificSign(city);
        area = SystemConstant.translateSpecificSign(area);
        customName = SystemConstant.translateSpecificSign(customName);
        List<UserArchivesAllocationResult> list = this.baseMapper.findCrmAllocationSubTotal(serviceUnitId, province, city, area, customName, gap, null, null,regionId, dpr);
        Integer publishedCrmCount = Math.toIntExact(list.stream().filter(e -> CrmStatusEnum.PUBLISH.equals(e.getCrmStatus())).count());
        Integer totalCrmCount = list.size();

        Integer coordinatorQuota = list.stream().mapToInt(UserArchivesAllocationResult::getCoordinatorQuota).sum();
        Integer coordinatorDistributed = list.stream().mapToInt(UserArchivesAllocationResult::getCoordinatorDistributed).sum();

        Integer effectQuota = list.stream().mapToInt(UserArchivesAllocationResult::getEffectQuota).sum();
        Integer effectDistributed = list.stream().mapToInt(UserArchivesAllocationResult::getEffectDistributed).sum();

        Integer assistantQuota = list.stream().mapToInt(UserArchivesAllocationResult::getAssistantQuota).sum();
        Integer assistantDistributed = list.stream().mapToInt(UserArchivesAllocationResult::getAssistantDistributed).sum();

        UserArchivesAllocationSubTotalResult result = new UserArchivesAllocationSubTotalResult();
        result.setPublishedCrmCount(publishedCrmCount);
        result.setTotalCrmCount(totalCrmCount);
        result.setCoordinatorDistributed(coordinatorDistributed);
        result.setCoordinatorQuota(coordinatorQuota);
        result.setEffectDistributed(effectDistributed);
        result.setEffectQuota(effectQuota);
        result.setAssistantDistributed(assistantDistributed);
        result.setAssistantQuota(assistantQuota);
        return result;
    }

    @Transactional
    @Override
    public void editCrmAllocation(UserArchivesAllocationParam userArchivesAllocationParam) {
        Long serviceUnitId = userArchivesAllocationParam.getServiceUnitId();
        TBService tbService = tbServiceService.getById(serviceUnitId);
        if (Objects.isNull(tbService)) {
            throw ExceptionResultEnum.ERROR.exception("服务单元不存在");
        }

        String crmNo = userArchivesAllocationParam.getCrmNo();
        Long regionUserId = userArchivesAllocationParam.getRegionUserId();

        List<TBCrm> tbCrmList = tbCrmService.list(new QueryWrapper<TBCrm>().lambda().eq(TBCrm::getCrmNo, crmNo));
        if (CollectionUtils.isEmpty(tbCrmList)) {
            throw ExceptionResultEnum.ERROR.exception("派单不存在");
        }
        if (tbCrmList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception("存在多个相同派单号的派单[" + crmNo + "]");
        }
        TBCrm tbCrm = tbCrmList.get(0);

        List<TBUserArchivesAllocation> dbList = this.list(new QueryWrapper<TBUserArchivesAllocation>()
                .lambda()
                .eq(TBUserArchivesAllocation::getCrmNo, crmNo));

        if (dbList.stream().anyMatch(e -> Objects.nonNull(e.getSopNo()))) {
            throw ExceptionResultEnum.ERROR.exception("已发布的派单不能调配");
        }

        // 新增关系
        List<AllocationParam> allocationParamList = userArchivesAllocationParam.getAllocationParams();


        List<TBUserArchivesAllocation> tbUserArchivesAllocationList = new ArrayList<>();
        // 处理实施工程师或助理工程师
        if (CollectionUtils.isNotEmpty(allocationParamList)) {
            for (AllocationParam allocationParam : allocationParamList) {
                Long roleId = allocationParam.getRoleId();
                List<Long> userIdList = allocationParam.getUserIdList();
                SysRole role = sysRoleService.getById(roleId);
                if (Objects.isNull(role)) {
                    throw ExceptionResultEnum.ERROR.exception("认证角色不存在");
                } else {
                    if (!RoleTypeEnum.EFFECT_ENGINEER.equals(role.getType()) && !RoleTypeEnum.ASSISTANT_ENGINEER.equals(role.getType())) {
                        throw ExceptionResultEnum.ERROR.exception(String.format("认证角色类型为[%s]不属于[%s]或[%s]",
                                role.getType().getDesc(),
                                RoleTypeEnum.EFFECT_ENGINEER.getDesc(),
                                RoleTypeEnum.ASSISTANT_ENGINEER.getDesc()));
                    }
                }

                for (Long userId : userIdList) {
                    List<Long> sysRoleIdList = sysUserRoleService.listRoleByUserId(userId).stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
                    if (!sysRoleIdList.contains(roleId)) {
                        throw ExceptionResultEnum.ERROR.exception("所选用户不包含认证角色[" + role.getType().getDesc() + "]");
                    }
                    TBUserArchives tbUserArchives = tbUserArchivesService.findByUserId(userId);
                    if (!UserArchivesStatusEnum.FREE.equals(tbUserArchives.getStatus())) {
                        List<TBCrm> occupiedCrm = tbCrmService.findOccupiedCrm(userId, null);
                        if (CollectionUtils.isEmpty(occupiedCrm)) {
                            throw ExceptionResultEnum.ERROR.exception("人员占用状态异常");
                        }
                        if (!occupiedCrm.stream().map(TBCrm::getCrmNo).collect(Collectors.toList()).contains(crmNo)) {
                            throw ExceptionResultEnum.ERROR.exception(String.format("工程师[%s]已经被派单号为[%s]的派单占用,请先将工程师从派单中移出",
                                    tbUserArchives.getName(), occupiedCrm.stream().map(TBCrm::getCrmNo).collect(Collectors.joining())));
                        }
                    }
                    TBUserArchivesAllocation tbUserArchivesAllocation = new TBUserArchivesAllocation();
                    tbUserArchivesAllocation.setCrmNo(crmNo);
                    tbUserArchivesAllocation.setArchivesId(tbUserArchives.getId());
                    tbUserArchivesAllocation.setServiceId(serviceUnitId);
                    tbUserArchivesAllocation.setUserId(userId);
                    tbUserArchivesAllocation.setRoleId(roleId);
                    tbUserArchivesAllocation.setRegionUserId(regionUserId);
                    tbUserArchivesAllocationList.add(tbUserArchivesAllocation);
                }
            }
        }

        // 更新区域负责人
        UpdateWrapper<TBCrm> coordinatorUpdateWrapper = new UpdateWrapper<>();
        coordinatorUpdateWrapper.lambda()
                .set(TBCrm::getRegionCoordinatorId, regionUserId)
                .eq(TBCrm::getId, tbCrm.getId());
        tbCrmService.update(coordinatorUpdateWrapper);

        // 新增前删除派单关系
        if (CollectionUtils.isNotEmpty(dbList)) {
            // 删除关系前先将工程师状态更改为空闲
            List<Long> engineerDbIdList = dbList.stream().map(TBUserArchivesAllocation::getArchivesId).distinct().collect(Collectors.toList());
            UpdateWrapper<TBUserArchives> archivesUpdateWrapper = new UpdateWrapper<>();
            archivesUpdateWrapper.lambda()
                    .set(TBUserArchives::getStatus, UserArchivesStatusEnum.FREE)
                    .in(TBUserArchives::getId, engineerDbIdList);
            tbUserArchivesService.update(archivesUpdateWrapper);

            // 删除派单关系
            this.removeByIds(dbList.stream().map(TBUserArchivesAllocation::getId).collect(Collectors.toList()));
        }


        if (CollectionUtils.isNotEmpty(tbUserArchivesAllocationList)) {
            // 新增前先将工程师的状态设置为非空闲
            List<Long> engineerAddIdLIst = tbUserArchivesAllocationList.stream().map(TBUserArchivesAllocation::getArchivesId).distinct().collect(Collectors.toList());
            UpdateWrapper<TBUserArchives> archivesUpdateWrapper = new UpdateWrapper<>();
            archivesUpdateWrapper.lambda()
                    .set(TBUserArchives::getStatus, UserArchivesStatusEnum.OCCUPIED)
                    .in(TBUserArchives::getId, engineerAddIdLIst);
            tbUserArchivesService.update(archivesUpdateWrapper);

            // 新增分配关系
            this.saveBatch(tbUserArchivesAllocationList);
        }
    }

    @Override
    public List<CrmArchivesAllocationResult> findAllocationByCrmNo(String crmNo) {
        List<CrmArchivesAllocationResult> list = this.baseMapper.findAllocationByCrmNo(crmNo);
        TBCrm tbCrm = tbCrmService.findByCrmNo(crmNo);
        Long regionCoordinatorId = tbCrm.getRegionCoordinatorId();

        if (regionCoordinatorId != null && regionCoordinatorId > 0) {

            UserArchivesResult userArchivesResult = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(null, regionCoordinatorId);
            if (Objects.nonNull(userArchivesResult)) {
                // 为空是大区经理兼任的情况 不处理
                CrmArchivesAllocationResult region = new CrmArchivesAllocationResult();
                region.setType(RoleTypeEnum.REGION_COORDINATOR);
                region.setArchivesId(userArchivesResult.getUserArchivesId());
                region.setArchiverName(userArchivesResult.getName());
                region.setSupplierId(userArchivesResult.getSupplierId());
                region.setSupplierName(userArchivesResult.getSupplierName());
                region.setArchivesProvince(userArchivesResult.getProvince());
                region.setArchivesCity(userArchivesResult.getCity());
                region.setUserId(userArchivesResult.getUserId());
                list.add(region);
            }
        }
        return list.stream().peek(e -> e.setRoleResult(sysRoleService.findRoleInfoByArchivesType(e.getType()))).collect(Collectors.toList());
    }

    @Transactional
    @Override
    public void autoEditCrmAllocationBatch(AutoAllocationParam autoAllocationParam) {
        Long serviceUnitId = autoAllocationParam.getServiceUnitId();
        List<Long> crmIdList = autoAllocationParam.getCrmIdList();
        List<UserArchivesAllocationResult> crmSourceList = this.baseMapper.findCrmAllocationSubTotal(serviceUnitId, null, null, null, null, null, crmIdList, CrmStatusEnum.UN_PUBLISH, null,null);
        // crm按照差额倒序
        crmSourceList = crmSourceList.stream().filter(e -> e.getUnDistributed() > 0)
                .sorted(Comparator.comparing(UserArchivesAllocationResult::getUnDistributed).reversed())
                .collect(Collectors.toList());

        for (UserArchivesAllocationResult crmSource : crmSourceList) {
            String crmNo = crmSource.getCrmNo();
            String city = crmSource.getCity();
            String province = crmSource.getProvince();

            // 区域协调人差额
            Integer coordinatorUnDistributed = crmSource.getCoordinatorUnDistributed();

            // 实施工程师差额
            Integer effectUnDistributed = crmSource.getEffectUnDistributed();

            // 助理工程师差额
            Integer assistantUnDistributed = crmSource.getAssistantUnDistributed();

            // 该派单已经分配的人员名单
            List<CrmArchivesAllocationResult> crmArchivesAllocationResultList = this.findAllocationByCrmNo(crmNo);
            // 区域协调人
            List<CrmArchivesAllocationResult> coordinatorList = crmArchivesAllocationResultList
                    .stream()
                    .filter(e -> RoleTypeEnum.REGION_COORDINATOR.equals(e.getType()))
                    .collect(Collectors.toList());
            // 实施工程师
            List<CrmArchivesAllocationResult> effectList = crmArchivesAllocationResultList
                    .stream()
                    .filter(e -> RoleTypeEnum.EFFECT_ENGINEER.equals(e.getType()))
                    .collect(Collectors.toList());
            // 助理工程师
            List<CrmArchivesAllocationResult> assistantList = crmArchivesAllocationResultList
                    .stream()
                    .filter(e -> RoleTypeEnum.ASSISTANT_ENGINEER.equals(e.getType()))
                    .collect(Collectors.toList());

            // 可分配的人力资源
            List<ArchivesSourceResult> effectFree = tbUserArchivesService.findFreeEngineerSourceByType(RoleTypeEnum.EFFECT_ENGINEER, null)
                    .stream()
                    .filter(e -> province.equals(e.getProvince()) && city.equals(e.getCity()))
                    .collect(Collectors.toList());

            List<ArchivesSourceResult> assistantFree = tbUserArchivesService.findFreeEngineerSourceByType(RoleTypeEnum.ASSISTANT_ENGINEER, null)
                    .stream()
                    .filter(e -> province.equals(e.getProvince()) && city.equals(e.getCity()))
                    .collect(Collectors.toList());

            List<ArchivesSourceResult> coordinatorFree = tbUserArchivesService.findFreeCoordinatorByServiceId(serviceUnitId, null, true)
                    .stream()
                    .filter(e -> province.equals(e.getProvince()) && city.equals(e.getCity()))
                    .collect(Collectors.toList());

            List<AllocationParam> allocationParamList = new ArrayList<>();

            // 先分实施工程师
            if (effectUnDistributed > 0) {
                SysRole effectRole = sysRoleService.list(new QueryWrapper<SysRole>().lambda().eq(SysRole::getType, RoleTypeEnum.EFFECT_ENGINEER)).get(0);
                Long effectRoleId = effectRole.getId();
                List<Long> userIdList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(coordinatorList)) {
                    // 实施工程师和区域协调人同供应商，实施工程师和crm客户同城市
                    CrmArchivesAllocationResult coordinator = coordinatorList.get(0);
                    Long supplierId = coordinator.getSupplierId();
                    effectFree = effectFree.stream()
                            .filter(e -> supplierId.equals(e.getSupplierId()))
                            .limit(effectUnDistributed)
                            .collect(Collectors.toList());
                    userIdList.addAll(effectFree.stream().map(ArchivesSourceResult::getUserId).distinct().collect(Collectors.toList()));
                    this.addDistributeTemp(effectList, effectFree);
                } else {
                    // 不存在区域协调人，实施工程师和crm客户同城市，且实施工程师尽可能集中在同一个供应商中

                    // 供应商和实施工程师数量键值对
                    Map<Long, Integer> supplierMap = effectFree.stream().collect(Collectors.toMap(ArchivesSourceResult::getSupplierId, e -> 1, Integer::sum));
                    supplierMap = SystemConstant.sortMapByValues(supplierMap);
                    for (Long supplierId : supplierMap.keySet()) {
                        Integer count = supplierMap.get(supplierId);
                        int effectDivide = effectUnDistributed - count;
                        List<ArchivesSourceResult> cell;
                        if (effectDivide > 0) {
                            // 该供应商的不够分配配额
                            cell = effectFree.stream().filter(e -> supplierId.equals(e.getSupplierId())).limit(count).collect(Collectors.toList());
                            userIdList.addAll(cell.stream().map(ArchivesSourceResult::getUserId).distinct().collect(Collectors.toList()));
                            this.addDistributeTemp(effectList, cell);
                            // 进入下一个供应商循环
                            effectUnDistributed = effectUnDistributed - count;
                        } else {
                            // 该供应商的足够分配配额
                            cell = effectFree.stream().filter(e -> supplierId.equals(e.getSupplierId())).limit(effectUnDistributed).collect(Collectors.toList());
                            userIdList.addAll(cell.stream().map(ArchivesSourceResult::getUserId).distinct().collect(Collectors.toList()));
                            this.addDistributeTemp(effectList, cell);
                            break;
                        }
                    }
                }
                AllocationParam allocationParam = new AllocationParam();
                allocationParam.setRoleId(effectRoleId);
                allocationParam.setUserIdList(userIdList);
                allocationParamList.add(allocationParam);
            }
            // 再分助理工程师
            if (assistantUnDistributed > 0) {
                SysRole assistantRole = sysRoleService.list(new QueryWrapper<SysRole>().lambda().eq(SysRole::getType, RoleTypeEnum.ASSISTANT_ENGINEER)).get(0);
                Long assistantRoleId = assistantRole.getId();
                List<Long> userIdList = new ArrayList<>();
                Map<Long, Integer> supplierMap = assistantFree.stream().collect(Collectors.toMap(ArchivesSourceResult::getSupplierId, e -> 1, Integer::sum));
                supplierMap = SystemConstant.sortMapByValues(supplierMap);
                for (Long supplierId : supplierMap.keySet()) {
                    Integer count = supplierMap.get(supplierId);
                    int assistantDivide = assistantUnDistributed - count;
                    List<ArchivesSourceResult> cell;
                    if (assistantDivide > 0) {
                        // 该供应商的不够分配配额
                        cell = assistantFree.stream().filter(e -> supplierId.equals(e.getSupplierId())).limit(count).collect(Collectors.toList());
                        userIdList.addAll(cell.stream().map(ArchivesSourceResult::getUserId).distinct().collect(Collectors.toList()));
                        this.addDistributeTemp(assistantList, cell);
                        assistantUnDistributed = assistantUnDistributed - count;
                    } else {
                        // 该供应商的足够分配配额
                        cell = assistantFree.stream().filter(e -> supplierId.equals(e.getSupplierId())).limit(assistantUnDistributed).collect(Collectors.toList());
                        userIdList.addAll(cell.stream().map(ArchivesSourceResult::getUserId).distinct().collect(Collectors.toList()));
                        this.addDistributeTemp(assistantList, cell);
                        break;
                    }
                }
                AllocationParam allocationParam = new AllocationParam();
                allocationParam.setRoleId(assistantRoleId);
                allocationParam.setUserIdList(userIdList);
                allocationParamList.add(allocationParam);
            }

            // 最后分配区域协调人
            Long regionUserId = null;
            if (coordinatorUnDistributed > 0) {
                if (CollectionUtils.isNotEmpty(effectList)) {
                    // 存在已经分配的实施工程师
                    List<Long> supplierIdList = effectList.stream().map(CrmArchivesAllocationResult::getSupplierId).distinct().collect(Collectors.toList());
                    if (supplierIdList.size() == 1) {
                        Long supplierId = supplierIdList.get(0);
                        List<ArchivesSourceResult> coordinator = coordinatorFree.stream()
                                .filter(e -> supplierId.equals(e.getSupplierId()))
                                .sorted(Comparator.comparing(ArchivesSourceResult::getRemainCount).reversed())
                                .collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(coordinator)) {
                            regionUserId = coordinator.get(0).getUserId();
                        }
                    }
                } else {
                    // 不存在实施工程师
                    List<ArchivesSourceResult> coordinator = coordinatorFree.stream()
                            .sorted(Comparator.comparing(ArchivesSourceResult::getRemainCount).reversed())
                            .collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(coordinator)) {
                        regionUserId = coordinator.get(0).getUserId();
                    }

                }
            }
            UserArchivesAllocationParam userArchivesAllocationParam = new UserArchivesAllocationParam();
            userArchivesAllocationParam.setAllocationParams(allocationParamList);
            userArchivesAllocationParam.setServiceUnitId(serviceUnitId);
            userArchivesAllocationParam.setCrmNo(crmNo);
            userArchivesAllocationParam.setRegionUserId(regionUserId);
            this.editCrmAllocation(userArchivesAllocationParam);
        }
    }

    @Override
    public void publishSop(String crmNo) throws InterruptedException {
        TBCrm tbCrm = tbCrmService.findByCrmNo(crmNo);
        Long serviceUnitId = tbCrm.getServiceId();
        if (serviceUnitId == null || serviceUnitId == 0) {
            throw ExceptionResultEnum.ERROR.exception("该派单还未绑定服务单元,不能发布");
        }
        if (!CrmStatusEnum.UN_PUBLISH.equals(tbCrm.getStatus())) {
            throw ExceptionResultEnum.ERROR.exception("只有'未发布'状态的派单才能发布,该派单当前状态为[" + tbCrm.getStatus() + "]");
        }
        Long crmId = tbCrm.getId();
        List<Long> crmIdList = new ArrayList<>();
        crmIdList.add(crmId);
        List<UserArchivesAllocationResult> crmSourceList = this.baseMapper.findCrmAllocationSubTotal(serviceUnitId, null, null, null, null, null, crmIdList, null, null,null);
        if (CollectionUtils.isEmpty(crmSourceList)) {
            throw ExceptionResultEnum.ERROR.exception("未找到派单信息");
        } else if (crmSourceList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception("派单信息异常");
        }
        UserArchivesAllocationResult crmSource = crmSourceList.get(0);
        ProductTypeEnum productType = crmSource.getCustomType();

        // 发布校验（至少有一名区域协调人和一名实施工程师）
        Integer coordinatorDistributed = crmSource.getCoordinatorDistributed();
        if (coordinatorDistributed < 1) {
            throw ExceptionResultEnum.ERROR.exception(String.format("派单号为[%s]的派单发布失败,派单至少要有一个区域协调人", crmNo));
        }
        Integer effectDistributed = crmSource.getEffectDistributed();
        if (effectDistributed < 1) {
            throw ExceptionResultEnum.ERROR.exception(String.format("派单号为[%s]的派单发布失败,派单至少要有一个实施工程师", crmNo));
        }

        List<TFCustomFlow> tfCustomFlowList = tfCustomFlowService.findFlowDeploymentList();
        String flowDeploymentId = null;
        switch (productType) {
            case OFFICE:
                List<String> ofl = tfCustomFlowList.stream()
                        .filter(e -> e.getType().equals(TFCustomTypeEnum.OFFICE_SOP_FLOW))
                        .map(TFCustomFlow::getFlowDeploymentId)
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(ofl)) {
                    throw ExceptionResultEnum.ERROR.exception("发布失败,未找到教务处SOP部署信息");
                } else if (ofl.size() > 1) {
                    throw ExceptionResultEnum.ERROR.exception("发布失败,教务处SOP部署信息异常");
                }
                flowDeploymentId = ofl.get(0);
                break;
            case CLOUD_MARK:
                List<String> cfl = tfCustomFlowList.stream()
                        .filter(e -> e.getType().equals(TFCustomTypeEnum.CLOUD_MARK_SOP_FLOW))
                        .map(TFCustomFlow::getFlowDeploymentId)
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(cfl)) {
                    throw ExceptionResultEnum.ERROR.exception("发布失败,未找到研究生SOP部署信息");
                } else if (cfl.size() > 1) {
                    throw ExceptionResultEnum.ERROR.exception("发布失败,研究生SOP部署信息异常");
                }
                flowDeploymentId = cfl.get(0);
                break;
        }
        SopPublishParam sopPublishParam = new SopPublishParam();
        sopPublishParam.setCrmNo(crmNo);
        sopPublishParam.setApprove(FlowApprovePassEnum.DRAFT);
        if (Objects.isNull(flowDeploymentId)) {
            throw ExceptionResultEnum.ERROR.exception("发布失败,未找到SOP部署信息");
        }
        sopPublishParam.setFlowDeploymentId(flowDeploymentId);
        tbSopInfoService.sopPublish(sopPublishParam);

        // 更新tbCrm状态为发布
        tbCrmService.updateCrmStatus(crmNo, CrmStatusEnum.PUBLISH);
    }

    @Override
    public void unPublishSop(String crmNo) {
        TBCrm tbCrm = tbCrmService.findByCrmNo(crmNo);
        if (!CrmStatusEnum.PUBLISH.equals(tbCrm.getStatus())) {
            throw ExceptionResultEnum.ERROR.exception("只有'已发布'状态的派单才能撤回,该派单当前状态为[" + tbCrm.getStatus() + "]");
        }
        tbCrmService.updateCrmStatus(crmNo, CrmStatusEnum.UN_PUBLISH);
        // 流程作废
        activitiService.flowEnd(crmNo);
    }

    /**
     * 处理临时新增的分配名单
     *
     * @param distribute 已分配的
     * @param insert     临时分配的
     */
    private void addDistributeTemp(List<CrmArchivesAllocationResult> distribute, List<ArchivesSourceResult> insert) {
        distribute.addAll(insert.stream().flatMap(e -> {
            CrmArchivesAllocationResult result = new CrmArchivesAllocationResult();
            result.setArchivesId(e.getArchivesId());
            result.setUserId(e.getUserId());
            result.setArchivesProvince(e.getProvince());
            result.setArchivesCity(e.getCity());
            result.setSupplierId(e.getSupplierId());
            return Stream.of(result);
        }).collect(Collectors.toList()));
    }
}