package com.ningdatech.pmapi.expert.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.model.CommonPage;
import com.ningdatech.pmapi.expert.assembler.ExpertUserInfoAssembler;
import com.ningdatech.pmapi.expert.constant.ExpertAccountStatusEnum;
import com.ningdatech.pmapi.expert.constant.ExpertUserInfoStepEnum;
import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo;
import com.ningdatech.pmapi.expert.mapper.ExpertAdminManageMapper;
import com.ningdatech.pmapi.expert.model.cmd.ExpertAdminExpertManageQueryCmd;
import com.ningdatech.pmapi.expert.model.dto.ExpertAdminExpertManageListDTO;
import com.ningdatech.pmapi.expert.model.query.ExpertDictionaryQuery;
import com.ningdatech.pmapi.expert.model.query.ExpertTagQuery;
import com.ningdatech.pmapi.expert.model.query.ListExpertQuery;
import com.ningdatech.pmapi.expert.service.ExpertAdminManageService;
import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService;
import com.ningdatech.pmapi.meta.model.entity.ExpertDictionary;
import com.ningdatech.pmapi.meta.model.entity.ExpertTag;
import com.ningdatech.pmapi.meta.service.IExpertDictionaryService;
import com.ningdatech.pmapi.meta.service.IExpertTagService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author liuxinxin
 * @date 2023/3/10 上午10:37
 */
@Service
@RequiredArgsConstructor
public class ExpertAdminManageServiceImpl implements ExpertAdminManageService {

    private final IExpertUserFullInfoService iExpertUserFullInfoService;
    private final IExpertDictionaryService iExpertDictionaryService;
    private final IExpertTagService iExpertTagService;
    private final ExpertAdminManageMapper expertAdminManageMapper;

    private List<Long> listExpertUserId(ListExpertQuery listExpertQuery) {
        List<Long> userIdList = expertAdminManageMapper.listExpertUserId(listExpertQuery);

        List<ExpertTagQuery> expertTagQueryList = listExpertQuery.getExpertTagQueryList();
        if (CollectionUtils.isNotEmpty(expertTagQueryList)) {
            List<Long> tagUserIdList = expertAdminManageMapper.listExpertTagUserId(listExpertQuery);
            userIdList.retainAll(tagUserIdList);
        }

        List<ExpertDictionaryQuery> expertDictQueryList = listExpertQuery.getExpertDictionaryQueryList();
        if (CollectionUtils.isNotEmpty(expertDictQueryList)) {
            List<Long> dictionaryUserIdList = expertAdminManageMapper.listExpertDictionaryUserId(listExpertQuery);
            userIdList.retainAll(dictionaryUserIdList);
        }
        return userIdList;
    }


    @Override
    public CommonPage<ExpertAdminExpertManageListDTO> getExpertLibraryList(ExpertAdminExpertManageQueryCmd req) {
        ListExpertQuery listExpertQuery = buildListExpertQuery(req);
        List<Long> userIdList = listExpertUserId(listExpertQuery);

        List<ExpertUserFullInfo> evidenceHasBeenSubmittedExpertInfoList = iExpertUserFullInfoService.list(Wrappers.lambdaQuery(ExpertUserFullInfo.class)
                .eq(ExpertUserFullInfo::getUserInfoStep, ExpertUserInfoStepEnum.EVIDENCE_HAS_BEEN_SUBMITTED.getKey()));
        List<Long> evidenceHasBeenSubmittedExpertUserIdList = evidenceHasBeenSubmittedExpertInfoList
                .stream().map(ExpertUserFullInfo::getUserId)
                .distinct().collect(Collectors.toList());

        Iterator<Long> iterator = userIdList.iterator();
        while (iterator.hasNext()) {
            if (!evidenceHasBeenSubmittedExpertUserIdList.contains(iterator.next())) {
                userIdList.remove(iterator.next());
            }
        }

        CommonPage<ExpertAdminExpertManageListDTO> commonPage = new CommonPage<>();
        commonPage.setCurrentPageNumber(req.getPageNumber());
        commonPage.setItemsTotal((long) userIdList.size());

        List<ExpertAdminExpertManageListDTO> recordList = new ArrayList<>();

        if (userIdList.size() != 0) {
            List<Long> currPageUserIdList = CollUtil.page(req.getPageNumber() - 1, req.getPageSize(), userIdList);
            List<ExpertUserFullInfo> expertUserList = iExpertUserFullInfoService.listByUserIds(currPageUserIdList);

            // 获取专家字典数据
            LambdaQueryWrapper<ExpertDictionary> in = Wrappers.lambdaQuery(ExpertDictionary.class)
                    .in(ExpertDictionary::getUserId, userIdList);
            List<ExpertDictionary> expertDictionaryList = iExpertDictionaryService.list(in);
            Map<Long, List<ExpertDictionary>> expertDictMap = CollUtils.group(expertDictionaryList, ExpertDictionary::getUserId);

            // 获取专家标签数据
            LambdaQueryWrapper<ExpertTag> tagIn = Wrappers.lambdaQuery(ExpertTag.class)
                    .in(ExpertTag::getUserId, userIdList);
            List<ExpertTag> expertTagList = iExpertTagService.list(tagIn);
            Map<Long, List<ExpertTag>> expertTagMap = CollUtils.group(expertTagList, ExpertTag::getUserId);
            for (ExpertUserFullInfo expertUserFullInfo : expertUserList) {
                ExpertAdminExpertManageListDTO expertAdminExpertManageListDTO =
                        ExpertUserInfoAssembler.buildExpertAdminExpertManageListDTO(expertUserFullInfo, expertDictMap, expertTagMap);
                recordList.add(expertAdminExpertManageListDTO);
            }
        }
        commonPage.setItems(recordList);
        return commonPage;
    }

    public ListExpertQuery buildListExpertQuery(ExpertAdminExpertManageQueryCmd queryCmd) {
        ListExpertQuery listExpertQuery = new ListExpertQuery();
        listExpertQuery.setExpertName(queryCmd.getExpertName());
        listExpertQuery.setCompany(queryCmd.getCompany());
        listExpertQuery.setExpertDictionaryQueryList(queryCmd.getExpertDictionaryQueryList());
        listExpertQuery.setExpertTagQueryList(queryCmd.getExpertTagQueryList());
        listExpertQuery.setRegionContainsList(queryCmd.getRegionContainsList());
        listExpertQuery.setIntentionRegionList(queryCmd.getIntentionRegionList());
        listExpertQuery.setIsDingUser(queryCmd.getIsDingUser());
        listExpertQuery.setLimit(queryCmd.getLimit());
        listExpertQuery.setOffset(queryCmd.getOffset());
        listExpertQuery.setIsDingUser(queryCmd.getIsDingUser());
        if (CollectionUtils.isNotEmpty(queryCmd.getExpertAccountStatusList())) {
            listExpertQuery.setExpertAccountStatusList(
                    queryCmd.getExpertAccountStatusList().stream().map(ExpertAccountStatusEnum::getKey).collect(Collectors.toList()));
        }
        return listExpertQuery;
    }

    @Override
    public List<Long> filterExpertUserIdList(ExpertAdminExpertManageQueryCmd queryCmd) {
        ListExpertQuery listExpertQuery = buildListExpertQuery(queryCmd);
        return listExpertUserId(listExpertQuery);
    }
}
