package com.hz.pm.api.expert.manage;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hz.pm.api.common.enumeration.BoolDisplayEnum;
import com.hz.pm.api.common.helper.RegionCacheHelper;
import com.hz.pm.api.common.helper.RegionLimitHelper;
import com.hz.pm.api.common.helper.UserInfoHelper;
import com.hz.pm.api.common.util.BizUtils;
import com.hz.pm.api.expert.constant.ExpertApplyStatusEnum;
import com.hz.pm.api.expert.constant.ExpertApplyTypeEnum;
import com.hz.pm.api.expert.constant.ExpertApplyTypeQueryEnum;
import com.hz.pm.api.expert.entity.ExpertMetaApply;
import com.hz.pm.api.expert.entity.ExpertUserFullInfo;
import com.hz.pm.api.expert.model.DictFieldInfoDTO;
import com.hz.pm.api.expert.model.TagFieldInfo;
import com.hz.pm.api.expert.model.cmd.*;
import com.hz.pm.api.expert.model.dto.ExpertDictionaryDTO;
import com.hz.pm.api.expert.model.dto.ExpertTagDTO;
import com.hz.pm.api.expert.model.query.ExpertDictionaryQuery;
import com.hz.pm.api.expert.model.req.MetaApplyResultRequest;
import com.hz.pm.api.expert.model.req.MetaApplyResultRequest.StorageApplyResultExtraInfo;
import com.hz.pm.api.expert.model.vo.ExpertApplyMetaVO;
import com.hz.pm.api.expert.model.vo.MetaApplyResultVo;
import com.hz.pm.api.expert.service.ExpertAdminManageService;
import com.hz.pm.api.expert.service.ExpertInfoService;
import com.hz.pm.api.expert.service.IExpertMetaApplyService;
import com.hz.pm.api.expert.service.IExpertUserFullInfoService;
import com.hz.pm.api.meta.constant.ExpertDictTypeEnum;
import com.hz.pm.api.meta.helper.DictionaryCache;
import com.hz.pm.api.meta.model.ExpertRegionInfo;
import com.hz.pm.api.meta.model.bo.RegionContainsBO;
import com.hz.pm.api.meta.model.dto.DictionaryDTO;
import com.hz.pm.api.meta.model.entity.ExpertDictionary;
import com.hz.pm.api.meta.service.IExpertDictionaryService;
import com.hz.pm.api.user.util.LoginUserUtil;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author liuxinxin
 * @date 2023/3/1 上午10:38
 */

@Component
@RequiredArgsConstructor
public class ExpertMetaApplyManage {

    private final IExpertMetaApplyService iMetaApplyService;
    private final IExpertDictionaryService expertDictionaryService;
    private final RegionCacheHelper regionCacheHelper;
    private final IExpertUserFullInfoService userFullInfoService;
    private final DictionaryCache dictionaryCache;
    private final ExpertInfoService expertInfoService;
    private final UserInfoHelper userInfoHelper;
    private final RegionLimitHelper regionLimitHelper;
    private final ExpertAdminManageService expertAdminManageService;
    private final IExpertDictionaryService iExpertDictionaryService;

    public PageVo<ExpertApplyMetaVO> metaApplyListQuery(MetaApplyListQuery req) {
        // 筛选符合专家类型的用户id
        List<Long> filterExpertTypeUserIdList = null;
        DictFieldInfoDTO expertType = req.getExpertType();
        if (Objects.nonNull(expertType) && StringUtils.isNotBlank(expertType.getDictionaryCode())) {
            List<ExpertDictionary> expertTypeDictionaryList = iExpertDictionaryService.list(Wrappers.lambdaQuery(ExpertDictionary.class)
                    .eq(ExpertDictionary::getDictionaryCode, expertType.getDictionaryCode()));
            filterExpertTypeUserIdList = expertTypeDictionaryList.stream().map(ExpertDictionary::getUserId).distinct().collect(Collectors.toList());
        }

        // 查找符合专家条件的用户id
        ExpertAdminExpertManageQueryCmd queryCmd = buildExpertAdminExpertManageQueryCmd(req);
        List<Long> filterExpertUserIdList = expertAdminManageService.filterExpertUserIdList(queryCmd);

        // 取交集
        List<Long> finalFilterExpertUserIdList = new ArrayList<>();
        if (Objects.nonNull(filterExpertTypeUserIdList)) {
            for (Long userId : filterExpertUserIdList) {
                if (filterExpertTypeUserIdList.contains(userId)) {
                    finalFilterExpertUserIdList.add(userId);
                }
            }
        } else {
            finalFilterExpertUserIdList = filterExpertUserIdList;
        }

        if (CollUtil.isEmpty(finalFilterExpertUserIdList)) {
            return PageVo.empty();
        }

        LambdaQueryWrapper<ExpertMetaApply> expertMetaApplyListQuery =
                buildMetaApplyListQueryWrapper(req, finalFilterExpertUserIdList);
        Page<ExpertMetaApply> pageResult = iMetaApplyService.page(req.page(), expertMetaApplyListQuery);
        PageVo<ExpertApplyMetaVO> result = new PageVo<>();
        result.setTotal(pageResult.getTotal());
        BizUtils.notEmpty(pageResult.getRecords(), records -> {
            List<Long> expertIds = CollUtils.fieldList(records, ExpertMetaApply::getUserId);
            // 根据用户id 获取专家基本信息
            List<ExpertUserFullInfo> expertList = userFullInfoService.listByUserIds(expertIds);
            Map<Long, ExpertUserFullInfo> expertMap = CollUtils.listToMap(expertList, ExpertUserFullInfo::getUserId);
            List<ExpertDictionary> titleLevelDictList = expertDictionaryService.listByUserId(expertIds, ExpertDictTypeEnum.TITLE_LEVEL);
            Map<Long, List<ExpertDictionary>> titleLevelDictMap = CollUtils.group(titleLevelDictList, ExpertDictionary::getUserId);

            List<ExpertDictionary> expertTypeDictList = expertDictionaryService.listByUserId(expertIds, ExpertDictTypeEnum.EXPERT_TYPE);
            Map<Long, List<ExpertDictionary>> expertTypeDictMap = CollUtils.group(expertTypeDictList, ExpertDictionary::getUserId);
            result.setRecords(buildExpertApplyMetaVOList(records, expertMap, titleLevelDictMap, expertTypeDictMap));
        });
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public void metaApplyResult(MetaApplyResultRequest req) {
        Long applyId = req.getApplyId();
        ExpertMetaApply expertMetaApply = iMetaApplyService.getById(applyId);
        Long userId = LoginUserUtil.getUserId();
        // 校验专家管理员区域权限，是否可以审核当前专家申请
        // permissionCheckHelper.operationPermissionsCheck(userId, expertMetaApply.getUserId());
        String applyStatus = expertMetaApply.getApplyStatus();
        if (!ExpertApplyStatusEnum.PENDING_REVIEW.getKey().equals(applyStatus)) {
            throw BizException.wrap("apply is already processed");
        }
        ExpertApplyTypeEnum applyType = ExpertApplyTypeEnum.of(expertMetaApply.getApplyType());
        boolean applyResult = req.getApplyResult();

        switch (applyType) {
            // 专家入库
            case EXPERT_STORAGE: {
                ExpertStorageDealCmd expertStorageDealCmd = buildExpertStorageDealCmd(req, expertMetaApply.getUserId(), expertMetaApply);
                expertInfoService.expertStorageDeal(expertStorageDealCmd);
                // 专家入库时，需要先审核专家入库，入库成功后，再履职意向审核，如果履职意向跟专家层级是同一层级的，就直接同意不需要审核
                if (applyResult) {
                    Long expertUserId = expertMetaApply.getUserId();
                    List<ExpertMetaApply> joinApplyList = iMetaApplyService.list(Wrappers.lambdaQuery(ExpertMetaApply.class)
                            .eq(ExpertMetaApply::getUserId, expertUserId)
                            .eq(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.PENDING_REVIEW.getKey())
                            .eq(ExpertMetaApply::getApplyType, ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN.getKey())
                            .eq(ExpertMetaApply::getDisplayEnable, BoolDisplayEnum.N.name()));
                    BizUtils.notEmpty(joinApplyList, list -> list.forEach(r -> {
                        MetaApplyResultRequest resultRequest = new MetaApplyResultRequest();
                        resultRequest.setApplyId(r.getId());
                        resultRequest.setApplyResult(true);
                        resultRequest.setAuditOpinion("同意");
                        metaApplyResult(resultRequest);
                    }));
                }
            }
            break;
            // 专家出库
            case EXPERT_DELIVERY:
                // ExpertDeliveryDealCmd expertDeliveryDealCmd = buildExpertDeliveryDealCmd(req, expertMetaApply.getUserId());
                // expertInfoService.expertDeliveryDeal(expertDeliveryDealCmd);
                break;
            // 长期请假
            case LONG_TERM_LEAVE:
                // leaveManage.leaveAuditCallback(req.getApplyResult(), applyId);
                break;
            // 专家信息审核
            case EXPERT_INFO_MODIFY:
                ExpertInfoModifyApplyDealCmd applyDealCmd = buildExpertInfoModifyApplyDealCmd(req, expertMetaApply.getUserId(), applyId);
                expertInfoService.expertInfoModifyDeal(applyDealCmd);
                break;
            // 专家履职意向加入/离开
            case EXPERT_INTENTION_JOIN:
            case EXPERT_INTENTION_LEAVE:
                ExpertIntentionApplyDealCmd expertIntentionApplyDealCmd = buildExpertIntentionApplyDealCmd(req, expertMetaApply);
                expertInfoService.expertIntentionApplyDeal(expertIntentionApplyDealCmd);
                break;
            default:
                break;
        }

        String auditOpinion = req.getAuditOpinion();
        // 发送审核结果短信
        // sendApplyResultNotify(applyType, applyResult, auditOpinion, expertUserId);
        // 更新申请结果
        expertMetaApply.setApproverUserId(userId);
        String adminUserName = userInfoHelper.getUserName(userId);
        expertMetaApply.setApprover(adminUserName);
        expertMetaApply.setAuditOpinion(auditOpinion);
        expertMetaApply.setApplyStatus(applyResult ? ExpertApplyStatusEnum.PASSED.getKey() : ExpertApplyStatusEnum.REFUSED.getKey());
        expertMetaApply.setReviewTime(LocalDateTime.now());
        expertMetaApply.setUpdateOn(LocalDateTime.now());
        iMetaApplyService.saveOrUpdate(expertMetaApply);
    }

    public MetaApplyResultVo metaApplyResult(Long applyId) {
        ExpertMetaApply metaApply = iMetaApplyService.getById(applyId);
        if (Objects.isNull(metaApply)) {
            throw BizException.wrap("当前审核不存在");
        }
        MetaApplyResultVo metaApplyResultVo = MetaApplyResultVo.builder()
                .applyTime(metaApply.getCreateOn())
                .auditor(metaApply.getApprover())
                .expertUserId(metaApply.getUserId())
                .auditOption(metaApply.getAuditOpinion())
                .auditStatus(metaApply.getApplyStatus())
                .auditTime(metaApply.getReviewTime())
                .build();
        String applyType = metaApply.getApplyType();
        ExpertApplyTypeEnum applyTypeEnum = ExpertApplyTypeEnum.of(applyType);
        switch (applyTypeEnum) {
            case EXPERT_INTENTION_JOIN:
            case EXPERT_INTENTION_LEAVE:
                buildIntentionApplyDisplayVO(metaApplyResultVo, metaApply, applyTypeEnum);
                break;
            case EXPERT_DELIVERY:
            case LONG_TERM_LEAVE:
            case EXPERT_STORAGE:
            default:
                break;
        }
        metaApplyResultVo.setApplyType(applyTypeTrans(applyTypeEnum));
        return metaApplyResultVo;
    }


    public void metaApplyRevoke(Long applyId) {
        Long userId = LoginUserUtil.getUserId();
        ExpertMetaApply expertMetaApply = iMetaApplyService.getById(applyId);
        if (Objects.isNull(expertMetaApply)) {
            throw new BizException("apply not exist");
        }
        if (!expertMetaApply.getUserId().equals(userId)) {
            throw new BizException("has not right to operate");
        }
        String applyStatus = expertMetaApply.getApplyStatus();
        ExpertApplyStatusEnum expertApplyStatusEnum = ExpertApplyStatusEnum.of(applyStatus);
        if (!ExpertApplyStatusEnum.PENDING_REVIEW.equals(expertApplyStatusEnum)) {
            throw new BizException("apply is already deal");
        }
        expertMetaApply.setApplyStatus(ExpertApplyStatusEnum.REVOKED.getKey());
        expertMetaApply.setUpdateOn(LocalDateTime.now());
        iMetaApplyService.updateById(expertMetaApply);
    }


    private void buildIntentionApplyDisplayVO(MetaApplyResultVo metaApplyResultVo, ExpertMetaApply metaApply, ExpertApplyTypeEnum applyTypeEnum) {
        String regionCode = metaApply.getRegionCode();
        Integer regionLevel = metaApply.getRegionLevel();
        MetaApplyResultVo.IntentionApplyDisplayVO intentionApplyDisplayVO = new MetaApplyResultVo.IntentionApplyDisplayVO();
        intentionApplyDisplayVO.setExpertApplyId(metaApply.getId());
        ExpertRegionInfo expertRegionInfo = new ExpertRegionInfo();
        expertRegionInfo.setRegionCode(regionCode);
        expertRegionInfo.setRegionLevel(regionLevel);
        switch (applyTypeEnum) {
            case EXPERT_INTENTION_LEAVE: {
                intentionApplyDisplayVO.setReduceExpertRegion(expertRegionInfo);
            }
            break;
            case EXPERT_INTENTION_JOIN: {
                intentionApplyDisplayVO.setAddExpertRegion(expertRegionInfo);
            }
            break;
            default:
                break;
        }
        metaApplyResultVo.setIntentionApplyDisplayVo(intentionApplyDisplayVO);
    }

    private String applyTypeTrans(ExpertApplyTypeEnum applyTypeEnum) {
        switch (applyTypeEnum) {
            case EXPERT_INTENTION_JOIN:
            case EXPERT_INTENTION_LEAVE: {
                return ExpertApplyTypeQueryEnum.EXPERT_INTENTION_CHANGE.getKey();
            }
            case EXPERT_INFO_MODIFY: {
                return ExpertApplyTypeQueryEnum.EXPERT_INFO_MODIFY.getKey();
            }
            case LONG_TERM_LEAVE: {
                return ExpertApplyTypeQueryEnum.LONG_TERM_LEAVE.getKey();
            }
            case EXPERT_DELIVERY: {
                return ExpertApplyTypeQueryEnum.EXPERT_DELIVERY.getKey();
            }
            case EXPERT_STORAGE: {
                return ExpertApplyTypeQueryEnum.EXPERT_STORAGE.getKey();
            }
            default:
                return null;
        }
    }

    private List<String> applyTypeTrans(ExpertApplyTypeQueryEnum applyTypeQueryEnum) {
        List<String> applyTypeList = new ArrayList<>();
        switch (applyTypeQueryEnum) {
            case EXPERT_INTENTION_CHANGE: {
                applyTypeList.add(ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN.getKey());
                applyTypeList.add(ExpertApplyTypeEnum.EXPERT_INTENTION_LEAVE.getKey());
            }
            break;
            case EXPERT_INFO_MODIFY: {
                applyTypeList.add(ExpertApplyTypeEnum.EXPERT_INFO_MODIFY.getKey());
            }
            break;
            case LONG_TERM_LEAVE: {
                applyTypeList.add(ExpertApplyTypeEnum.LONG_TERM_LEAVE.getKey());
            }
            break;
            case EXPERT_DELIVERY: {
                applyTypeList.add(ExpertApplyTypeEnum.EXPERT_DELIVERY.getKey());
            }
            break;
            case EXPERT_STORAGE: {
                applyTypeList.add(ExpertApplyTypeEnum.EXPERT_STORAGE.getKey());
            }
            break;
            default:
                break;
        }
        return applyTypeList;
    }

    private ExpertAdminExpertManageQueryCmd buildExpertAdminExpertManageQueryCmd(MetaApplyListQuery query) {
        ExpertAdminExpertManageQueryCmd expertAdminExpertManageQueryCmd = new ExpertAdminExpertManageQueryCmd();
        expertAdminExpertManageQueryCmd.setPageNumber(query.getPageNumber());
        expertAdminExpertManageQueryCmd.setPageSize(query.getPageSize());
        if (StringUtils.isNotBlank(query.getExpertName())) {
            expertAdminExpertManageQueryCmd.setExpertName(query.getExpertName());
        }
        if (StringUtils.isNotBlank(query.getCompanyName())) {
            expertAdminExpertManageQueryCmd.setCompany(query.getCompanyName());
        }
        List<ExpertDictionaryQuery> expertDictionaryQueryList = new ArrayList<>();
        if (StringUtils.isNotBlank(query.getTitleLevelDictionaryCode())) {
            ExpertDictionaryQuery expertDictionaryQuery = new ExpertDictionaryQuery();
            expertDictionaryQuery.setExpertInfoField(ExpertDictTypeEnum.TITLE_LEVEL.getKey());
            expertDictionaryQuery.setDictionaryCodeList(CollectionUtil.toList(query.getTitleLevelDictionaryCode()));
            expertDictionaryQueryList.add(expertDictionaryQuery);
        }

        List<RegionContainsBO> containsRegion = null;
        if (Objects.nonNull(query.getExpertRegionInfo())) {
            RegionContainsBO containsRegionBo = regionLimitHelper.getContainsRegionBo(query.getExpertRegionInfo().getRegionLevel()
                    , query.getExpertRegionInfo().getRegionCode());
            containsRegion = CollUtil.toList(containsRegionBo);
        }

        expertAdminExpertManageQueryCmd.setExpertDictionaryQueryList(expertDictionaryQueryList);
        expertAdminExpertManageQueryCmd.setRegionContainsList(containsRegion);
        expertAdminExpertManageQueryCmd.setPageSize(query.getPageSize());
        expertAdminExpertManageQueryCmd.setPageNumber(query.getPageNumber());
        return expertAdminExpertManageQueryCmd;
    }

    /**
     * 装配 专家审核列表筛选返回VO
     *
     * @param expertMetaApplyList
     * @param expertUserFullInfoMap
     * @param titleLevelDictMap
     * @param expertTypeDictMap
     * @return
     */
    private List<ExpertApplyMetaVO> buildExpertApplyMetaVOList(List<ExpertMetaApply> expertMetaApplyList
            , Map<Long, ExpertUserFullInfo> expertUserFullInfoMap
            , Map<Long, List<ExpertDictionary>> titleLevelDictMap
            , Map<Long, List<ExpertDictionary>> expertTypeDictMap) {
        List<ExpertApplyMetaVO> expertApplyMetaVOList = new ArrayList<>();
        for (ExpertMetaApply expertMetaApply : expertMetaApplyList) {
            ExpertApplyMetaVO expertApplyMetaVO = new ExpertApplyMetaVO();
            Long userId = expertMetaApply.getUserId();
            ExpertUserFullInfo expertUserFullInfo = expertUserFullInfoMap.get(userId);
            expertApplyMetaVO.setId(expertMetaApply.getId());
            expertApplyMetaVO.setUserId(userId);
            expertApplyMetaVO.setApplyStatus(expertMetaApply.getApplyStatus());

            String applyType = expertMetaApply.getApplyType();
            if (Objects.nonNull(applyType)) {
                expertApplyMetaVO.setApplyType(applyTypeTrans(ExpertApplyTypeEnum.of(applyType)));
            }
            expertApplyMetaVO.setName(expertUserFullInfo.getExpertName());

            List<ExpertDictionary> titleLevelDictionaryList = titleLevelDictMap.get(userId);
            if (CollectionUtils.isNotEmpty(titleLevelDictionaryList)) {
                expertApplyMetaVO.setTitleLevel(titleLevelDictionaryList.stream().map(r -> {
                    Optional<DictionaryDTO> dictionaryDTO = dictionaryCache.getByCode(r.getDictionaryCode());
                    DictFieldInfoDTO dictionaryFieldInfo = new DictFieldInfoDTO();
                    dictionaryFieldInfo.setDictionaryCode(r.getDictionaryCode());
                    dictionaryFieldInfo.setDictionaryFieldName(r.getExpertInfoField());
                    dictionaryDTO.ifPresent(dictDTO -> dictionaryFieldInfo.setDictionaryName(dictDTO.getName()));
                    return dictionaryFieldInfo;
                }).collect(Collectors.toList()));
            }

            // 装配专家类型
            List<ExpertDictionary> expertTypeDictionaryList = expertTypeDictMap.get(userId);
            if (CollectionUtils.isNotEmpty(titleLevelDictionaryList)) {
                expertApplyMetaVO.setExpertType(expertTypeDictionaryList.stream().map(r -> {
                    Optional<DictionaryDTO> dictionaryDTO = dictionaryCache.getByCode(r.getDictionaryCode());
                    DictFieldInfoDTO dictionaryFieldInfo = new DictFieldInfoDTO();
                    dictionaryFieldInfo.setDictionaryCode(r.getDictionaryCode());
                    dictionaryFieldInfo.setDictionaryFieldName(r.getExpertInfoField());
                    dictionaryDTO.ifPresent(dictDTO -> dictionaryFieldInfo.setDictionaryName(dictDTO.getName()));
                    return dictionaryFieldInfo;
                }).collect(Collectors.toList()));
            }

            expertApplyMetaVO.setCompany(expertUserFullInfo.getCompany());
            expertApplyMetaVO.setPhoneNo(expertUserFullInfo.getPhoneNo());
            expertApplyMetaVO.setApplyTime(expertMetaApply.getCreateOn());
            expertApplyMetaVOList.add(expertApplyMetaVO);
        }
        return expertApplyMetaVOList;
    }

    private LambdaQueryWrapper<ExpertMetaApply> buildMetaApplyListQueryWrapper(MetaApplyListQuery applyListReq,
                                                                               List<Long> expertIdList) {
        // 审核类型
        List<String> applyTypeList = new ArrayList<>();
        if (CollUtil.isNotEmpty(applyListReq.getApplyTypeList())) {
            List<ExpertApplyTypeQueryEnum> applyTypeQueryEnumList = applyListReq.getApplyTypeList();
            for (ExpertApplyTypeQueryEnum applyTypeQueryEnum : applyTypeQueryEnumList) {
                applyTypeList.addAll(applyTypeTrans(applyTypeQueryEnum));
            }
        }
        // 审核结果
        List<String> applyStatusList;
        if (CollUtil.isNotEmpty(applyListReq.getApplyStatusList())) {
            applyStatusList = CollUtils.fieldList(applyListReq.getApplyStatusList(), ExpertApplyStatusEnum::getKey);
        } else {
            applyStatusList = null;
        }

        LocalDateTime applyStartTime = applyListReq.getApplyStartTime();
        LocalDateTime applyEndTime = applyListReq.getApplyEndTime();

        // 不展示撤回的申请记录
        return Wrappers.lambdaQuery(ExpertMetaApply.class)
                .in(CollUtil.isNotEmpty(applyTypeList), ExpertMetaApply::getApplyType, applyTypeList)
                .in(CollUtil.isNotEmpty(applyStatusList), ExpertMetaApply::getApplyStatus, applyStatusList)
                .in(ExpertMetaApply::getDisplayEnable, BoolDisplayEnum.Y.name())
                .in(CollUtil.isNotEmpty(expertIdList), ExpertMetaApply::getUserId, expertIdList)
                .gt(Objects.nonNull(applyStartTime), ExpertMetaApply::getCreateOn, applyStartTime)
                .lt(Objects.nonNull(applyEndTime), ExpertMetaApply::getCreateOn, applyEndTime)
                .ne(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.REVOKED.getKey())
                .orderByDesc(ExpertMetaApply::getCreateOn);
    }

    private ExpertStorageDealCmd buildExpertStorageDealCmd(MetaApplyResultRequest applyResultRequest,
                                                           Long expertUserId,
                                                           ExpertMetaApply expertMetaApply) {
        StorageApplyResultExtraInfo extraInfo = applyResultRequest.getStorageApplyResultExtraInfo();
        ExpertStorageDealCmd expertStorageDealCmd = new ExpertStorageDealCmd();
        Boolean applyResult = applyResultRequest.getApplyResult();
        expertStorageDealCmd.setApplyResult(applyResult);

        if (Objects.nonNull(extraInfo)) {
            List<DictFieldInfoDTO> expertType = extraInfo.getExpertType();
            if (CollUtil.isNotEmpty(expertType)) {
                expertStorageDealCmd.setExpertType(extraInfo.getExpertType().stream().map(r -> {
                    ExpertDictionaryDTO expertDictionaryDTO = new ExpertDictionaryDTO();
                    expertDictionaryDTO.setExpertInfoField(r.getDictionaryFieldName());
                    expertDictionaryDTO.setDictionaryCode(r.getDictionaryCode());
                    return expertDictionaryDTO;
                }).collect(Collectors.toList()));
            }
            List<TagFieldInfo> other = extraInfo.getOther();
            if (CollUtil.isNotEmpty(other)) {
                expertStorageDealCmd.setOther(extraInfo.getOther().stream().map(r -> {
                    ExpertTagDTO expertTagDTO = new ExpertTagDTO();
                    expertTagDTO.setExpertInfoField(r.getTagFieldName());
                    expertTagDTO.setTagCode(r.getTagCode());
                    return expertTagDTO;
                }).collect(Collectors.toList()));
            }
            expertStorageDealCmd.setRemark(extraInfo.getRemark());
        }
        expertStorageDealCmd.setExpertUserId(expertUserId);
        expertStorageDealCmd.setJoinRegionCode(expertMetaApply.getRegionCode());
        expertStorageDealCmd.setJoinRegionLevel(expertMetaApply.getRegionLevel());
        return expertStorageDealCmd;
    }


    private ExpertInfoModifyApplyDealCmd buildExpertInfoModifyApplyDealCmd(MetaApplyResultRequest applyResultRequest,
                                                                           Long userId, Long applyId) {
        ExpertInfoModifyApplyDealCmd expertInfoModifyApplyDealCmd = new ExpertInfoModifyApplyDealCmd();
        Boolean applyResult = applyResultRequest.getApplyResult();
        expertInfoModifyApplyDealCmd.setApplyResult(applyResult);
        expertInfoModifyApplyDealCmd.setExpertUserId(userId);
        expertInfoModifyApplyDealCmd.setApplyId(applyId);
        return expertInfoModifyApplyDealCmd;
    }

    private ExpertIntentionApplyDealCmd buildExpertIntentionApplyDealCmd(MetaApplyResultRequest applyResultRequest,
                                                                         ExpertMetaApply expertMetaApply) {
        Boolean applyResult = applyResultRequest.getApplyResult();
        String applyType = expertMetaApply.getApplyType();
        ExpertApplyTypeEnum applyTypeEnum = ExpertApplyTypeEnum.of(applyType);

        ExpertIntentionApplyDealCmd expertIntentionApplyDealCmd = new ExpertIntentionApplyDealCmd();
        expertIntentionApplyDealCmd.setApplyResult(applyResult);
        expertIntentionApplyDealCmd.setApplyTypeEnum(applyTypeEnum);
        expertIntentionApplyDealCmd.setExpertUserId(expertMetaApply.getUserId());
        expertIntentionApplyDealCmd.setExpertRegionCode(expertMetaApply.getRegionCode());
        expertIntentionApplyDealCmd.setExpertRegionLevel(expertMetaApply.getRegionLevel());
        return expertIntentionApplyDealCmd;
    }

    /**
     * 专家管理员 新增专家使用使用
     *
     * @param expertUserId \
     */
    @Transactional(rollbackFor = Exception.class)
    public void autoPassExpertApply(Long expertUserId) {
        final List<String> applyTypes = Arrays.asList(ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN.getKey(),
                ExpertApplyTypeEnum.EXPERT_STORAGE.getKey());
        LambdaQueryWrapper<ExpertMetaApply> query = Wrappers.lambdaQuery(ExpertMetaApply.class)
                .eq(ExpertMetaApply::getUserId, expertUserId)
                .in(ExpertMetaApply::getApplyType, applyTypes)
                .eq(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.PENDING_REVIEW.getKey());
        List<ExpertMetaApply> expertIntentionJoinApplyList = iMetaApplyService.list(query);
        for (ExpertMetaApply expertMetaApply : expertIntentionJoinApplyList) {
            MetaApplyResultRequest applyResult = new MetaApplyResultRequest();
            applyResult.setApplyId(expertMetaApply.getId());
            applyResult.setAuditOpinion("同意");
            applyResult.setApplyResult(true);
            metaApplyResult(applyResult);
        }
    }
}
