package com.ningdatech.pmapi.expert.assembler;


import com.ningdatech.pmapi.expert.model.*;
import com.ningdatech.pmapi.expert.model.cmd.ExpertFullInfoSaveCmd;
import com.ningdatech.pmapi.expert.model.dto.*;
import com.ningdatech.pmapi.meta.constant.DictExpertInfoTypeEnum;
import com.ningdatech.pmapi.meta.constant.ExpertTagEnum;
import com.ningdatech.pmapi.meta.model.ExpertRegionInfo;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author liuxinxin
 * @date 2022/7/22 下午5:19
 */

public class ExpertInfoCmdAssembler {

    public static ExpertFullInfoSaveCmd buildExpertFullInfoSaveCmd(Long userId
            , ExpertBasicInfo expertBasicInfo, ExpertEduInfo expertEduInfo
            , ExpertJobInfo expertJobInfo, ExpertProfessionalInfo expertProfessionalInfo) {

        ExpertFullInfoSaveCmd expertFullInfoSaveCmd = new ExpertFullInfoSaveCmd();
        ExpertUserFullInfoDTO expertUserInfoDTO = buildExpertUserFullInfoDTO(
                expertBasicInfo, expertEduInfo, expertJobInfo, expertProfessionalInfo, null, null);
        List<ExpertDictionaryDTO> expertDictionaryList =
                buildExpertDictionaryList(expertBasicInfo, expertEduInfo, expertJobInfo, expertProfessionalInfo, null);
        List<ExpertTagDTO> expertTagList = buildExpertTagList(expertProfessionalInfo, expertBasicInfo, null);
        // 专家履职意向(区域编码）
        List<ExpertRegionDTO> expertIntentionWorkRegionInfo = buildExpertRegionList(expertBasicInfo);
        List<ExpertAvoidCompanyDTO> expertAvoidCompanyList = buildExpertAvoidCompanyList(expertProfessionalInfo);

        expertFullInfoSaveCmd.setUserId(userId);
        expertFullInfoSaveCmd.setExpertUserInfoDTO(expertUserInfoDTO);
        expertFullInfoSaveCmd.setExpertDictionaryList(expertDictionaryList);
        expertFullInfoSaveCmd.setExpertTagList(expertTagList);
        expertFullInfoSaveCmd.setExpertIntentionWorkRegionInfo(expertIntentionWorkRegionInfo);
        expertFullInfoSaveCmd.setExpertAvoidCompanyList(expertAvoidCompanyList);

        return expertFullInfoSaveCmd;
    }




    private static List<ExpertAvoidCompanyDTO> buildExpertAvoidCompanyList(ExpertProfessionalInfo professionalInfo) {
        List<ExpertAvoidCompanyDTO> expertAvoidCompanyList = new ArrayList<>();
        List<ExpertAvoidCompanyInfo> avoidCompanyList = professionalInfo.getAvoidCompanyList();
        if (CollectionUtils.isNotEmpty(avoidCompanyList)) {
            expertAvoidCompanyList = avoidCompanyList.stream().map(r -> {
                ExpertAvoidCompanyDTO expertAvoidCompanyDTO = new ExpertAvoidCompanyDTO();
                expertAvoidCompanyDTO.setCompanyName(r.getCompanyName());
                expertAvoidCompanyDTO.setCompanyUniqCode(r.getCompanyUniqCode());
                return expertAvoidCompanyDTO;
            }).collect(Collectors.toList());
        }
        return expertAvoidCompanyList;
    }

    private static List<ExpertRegionDTO> buildExpertRegionList(ExpertBasicInfo basicInfo) {
        List<ExpertRegionInfo> expertIntentionWorkRegions = basicInfo.getExpertIntentionWorkRegions();
        if (CollectionUtils.isEmpty(expertIntentionWorkRegions)) {
            return new ArrayList<>();
        }
        return expertIntentionWorkRegions.stream().map(r -> {
            ExpertRegionDTO expertRegionDTO = new ExpertRegionDTO();
            expertRegionDTO.setRegionCode(r.getRegionCode());
            expertRegionDTO.setRegionLevel(r.getRegionLevel());
            return expertRegionDTO;
        }).collect(Collectors.toList());
    }

    private static List<ExpertTagDTO> buildExpertTagList(ExpertProfessionalInfo professionalInfo
            , ExpertBasicInfo basicInfo, ExpertOtherInfo otherInfo) {
        List<TagFieldInfo> goodAt = professionalInfo.getGoodAt();
        List<TagFieldInfo> technicalExpertise = professionalInfo.getTechnicalExpertise();
        List<TagFieldInfo> industrySector = professionalInfo.getIndustrySector();
        List<TagFieldInfo> expertSource = basicInfo.getExpertSource();
        List<TagFieldInfo> other = new ArrayList<>();
        if (Objects.nonNull(otherInfo)) {
            other = otherInfo.getOther();
        }
        List<TagFieldInfo> tagFieldInfoList = new ArrayList<>();
        assemblerTagExpertInfoFieldName(tagFieldInfoList, goodAt, ExpertTagEnum.GOOD_AT);
        assemblerTagExpertInfoFieldName(tagFieldInfoList, technicalExpertise, ExpertTagEnum.TECHNICAL_EXPERTISE);
        assemblerTagExpertInfoFieldName(tagFieldInfoList, industrySector, ExpertTagEnum.INDUSTRY_SECTOR);
        assemblerTagExpertInfoFieldName(tagFieldInfoList, expertSource, ExpertTagEnum.EXPERT_SOURCE);
        assemblerTagExpertInfoFieldName(tagFieldInfoList, other, ExpertTagEnum.OTHER);

        return tagFieldInfoList.stream().map(r -> {
            ExpertTagDTO expertTagDTO = new ExpertTagDTO();
            expertTagDTO.setTagCode(r.getTagCode());
            expertTagDTO.setExpertInfoField(r.getTagFieldName());
            return expertTagDTO;
        }).collect(Collectors.toList());
    }

    private static void assemblerTagExpertInfoFieldName(List<TagFieldInfo> allTagFieldInfoList
            , List<TagFieldInfo> originalTagFieldInfoList, ExpertTagEnum tagExpertInfoFieldEnum) {
        if (CollectionUtils.isNotEmpty(originalTagFieldInfoList)) {
            originalTagFieldInfoList = originalTagFieldInfoList.stream().map(r -> {
                r.setTagFieldName(tagExpertInfoFieldEnum.getKey());
                return r;
            }).collect(Collectors.toList());
            allTagFieldInfoList.addAll(originalTagFieldInfoList);
        }
    }

    private static List<ExpertDictionaryDTO> buildExpertDictionaryList(ExpertBasicInfo basicInfo, ExpertEduInfo eduInfo
            , ExpertJobInfo jobInfo, ExpertProfessionalInfo professionalInfo, ExpertRecommendInfo recommendInfo) {
        List<DictionaryFieldInfo> political = basicInfo.getPolitical();
        List<DictionaryFieldInfo> expertType = basicInfo.getExpertType();
        List<DictionaryFieldInfo> edu = eduInfo.getEdu();
        List<DictionaryFieldInfo> degree = eduInfo.getDegree();
        List<DictionaryFieldInfo> jobStatus = jobInfo.getJobStatus();
        List<DictionaryFieldInfo> companyAttribute = jobInfo.getCompanyAttribute();
        List<DictionaryFieldInfo> administrativeRank = jobInfo.getAdministrativeRank();
        List<DictionaryFieldInfo> titleLevel = professionalInfo.getTitleLevel();

        List<DictionaryFieldInfo> recommendedWay = new ArrayList<>();
        if (Objects.nonNull(recommendInfo)) {
            recommendedWay = recommendInfo.getRecommendedWay();
        }
        List<DictionaryFieldInfo> dictionaryFieldInfoList = new ArrayList<>();
        assemblerDictionaryFieldName(dictionaryFieldInfoList, political, DictExpertInfoTypeEnum.POLITICAL);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, expertType, DictExpertInfoTypeEnum.EXPERT_TYPE);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, edu, DictExpertInfoTypeEnum.EDU);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, degree, DictExpertInfoTypeEnum.DEGREE);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, jobStatus, DictExpertInfoTypeEnum.JOB_STATUS);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, companyAttribute, DictExpertInfoTypeEnum.COMPANY_ATTRIBUTE);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, administrativeRank, DictExpertInfoTypeEnum.ADMINISTRATIVE_RANK);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, titleLevel, DictExpertInfoTypeEnum.TITLE_LEVEL);
        assemblerDictionaryFieldName(dictionaryFieldInfoList, recommendedWay, DictExpertInfoTypeEnum.RECOMMENDED_WAY);

        return dictionaryFieldInfoList.stream().map(r -> {
            ExpertDictionaryDTO expertDictionaryDTO = new ExpertDictionaryDTO();
            expertDictionaryDTO.setDictionaryCode(r.getDictionaryCode());
            expertDictionaryDTO.setExpertInfoField(r.getDictionaryFieldName());
            return expertDictionaryDTO;
        }).collect(Collectors.toList());
    }

    private static void assemblerDictionaryFieldName(
            List<DictionaryFieldInfo> allDictionaryFieldInfoList, List<DictionaryFieldInfo> originalDictionaryFieldInfoList
            , DictExpertInfoTypeEnum dictExpertInfoTypeEnum) {
        if (CollectionUtils.isNotEmpty(originalDictionaryFieldInfoList)) {
            originalDictionaryFieldInfoList = originalDictionaryFieldInfoList.stream().map(r -> {
                r.setDictionaryFieldName(dictExpertInfoTypeEnum.getKey());
                return r;
            }).collect(Collectors.toList());
            allDictionaryFieldInfoList.addAll(originalDictionaryFieldInfoList);
        }
    }

    private static ExpertUserFullInfoDTO buildExpertUserFullInfoDTO(ExpertBasicInfo basicInfo, ExpertEduInfo eduInfo
            , ExpertJobInfo jobInfo, ExpertProfessionalInfo professionalInfo, ExpertRecommendInfo recommendInfo, ExpertOtherInfo otherInfo) {
        ExpertUserFullInfoDTO expertUserFullInfoDTO = new ExpertUserFullInfoDTO();

        expertUserFullInfoDTO.setIsDingUser(basicInfo.getIsDingUser());
        expertUserFullInfoDTO.setPhoneNo(basicInfo.getPhoneNo());
        expertUserFullInfoDTO.setGender(basicInfo.getGender());
        expertUserFullInfoDTO.setName(basicInfo.getName());
        if (Objects.nonNull(basicInfo.getAvatarFile())) {
            expertUserFullInfoDTO.setAvatarFileId(basicInfo.getAvatarFile().getFileId());
        }
        expertUserFullInfoDTO.setIdCard(basicInfo.getIdCard());
        expertUserFullInfoDTO.setOfficePhone(basicInfo.getOfficePhone());
        expertUserFullInfoDTO.setBirth(basicInfo.getBirth());
        expertUserFullInfoDTO.setBankNo(basicInfo.getBankNo());
        expertUserFullInfoDTO.setBank(basicInfo.getBank());
        expertUserFullInfoDTO.setEmail(basicInfo.getEmail());
        expertUserFullInfoDTO.setHometown(basicInfo.getHometown());
        expertUserFullInfoDTO.setNationality(basicInfo.getNationality());
        if (Objects.nonNull(otherInfo)) {
            expertUserFullInfoDTO.setRemark(otherInfo.getRemark());
        }
        expertUserFullInfoDTO.setSchool(eduInfo.getSchool());
        expertUserFullInfoDTO.setGraduatedAt(eduInfo.getGraduatedAt());
        expertUserFullInfoDTO.setAcademicTitle(eduInfo.getAcademicTitle());

        if (CollectionUtils.isNotEmpty(eduInfo.getGraduationCertificateFile())) {
            expertUserFullInfoDTO.setGraduationCertificateFileIdList(eduInfo.getGraduationCertificateFile().stream().map(FileBasicInfo::getFileId).collect(Collectors.toList()));
        }
        if (CollectionUtils.isNotEmpty(eduInfo.getDegreeCertificateFile())) {

            expertUserFullInfoDTO.setDegreeCertificateFileIdList(eduInfo.getDegreeCertificateFile().stream().map(FileBasicInfo::getFileId).collect(Collectors.toList()));
        }

        expertUserFullInfoDTO.setRetiredAt(jobInfo.getRetiredAt());
        expertUserFullInfoDTO.setCompany(jobInfo.getCompany());
        expertUserFullInfoDTO.setLegalEntityCode(jobInfo.getLegalEntityCode());
        expertUserFullInfoDTO.setAdministrativeDuties(jobInfo.getAdministrativeDuties());
        expertUserFullInfoDTO.setStartWorkAt(jobInfo.getStartWorkAt());
        expertUserFullInfoDTO.setAddress(jobInfo.getAddress());
        expertUserFullInfoDTO.setExperience(jobInfo.getExperience());

        expertUserFullInfoDTO.setTechnicalTitles(professionalInfo.getTechnicalTitles());
        if (CollectionUtils.isNotEmpty(professionalInfo.getTitleCertificateFile())) {
            expertUserFullInfoDTO.setTitleCertificateFileIdList(professionalInfo.getTitleCertificateFile().stream().map(FileBasicInfo::getFileId).collect(Collectors.toList()));
        }
        expertUserFullInfoDTO.setAwards(professionalInfo.getAwards());
        expertUserFullInfoDTO.setRecognitionReward(professionalInfo.getRecognitionReward());

        if (Objects.nonNull(basicInfo.getExpertRegionInfo())) {
            expertUserFullInfoDTO.setRegionCode(basicInfo.getExpertRegionInfo().getRegionCode());
            expertUserFullInfoDTO.setRegionLevel(basicInfo.getExpertRegionInfo().getRegionLevel());
        }
        // 推荐证明材料单独装配
        if (Objects.nonNull(recommendInfo)) {
            List<FileBasicInfo> recommendationProofFile = recommendInfo.getRecommendationProofFile();
            if (CollectionUtils.isNotEmpty(recommendationProofFile)) {
                expertUserFullInfoDTO
                        .setRecommendationProofFileIdList(
                                recommendationProofFile.stream().map(FileBasicInfo::getFileId).collect(Collectors.toList()));

            }
        }
        return expertUserFullInfoDTO;
    }

}
