package com.ningdatech.pmapi.expert.manage;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.GenericResult;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.common.enumeration.BoolDisplayEnum;
import com.ningdatech.pmapi.common.helper.RegionLimitHelper;
import com.ningdatech.pmapi.common.model.CommonPage;
import com.ningdatech.pmapi.common.util.StrUtils;
import com.ningdatech.pmapi.expert.assembler.ExpertAdminExpertManageAssembler;
import com.ningdatech.pmapi.expert.assembler.ExpertInfoCmdAssembler;
import com.ningdatech.pmapi.expert.constant.ExpertAccountStatusEnum;
import com.ningdatech.pmapi.expert.constant.ExpertApplyStatusEnum;
import com.ningdatech.pmapi.expert.constant.ExpertApplyTypeEnum;
import com.ningdatech.pmapi.expert.constant.QueryExpertAccountStatusEnum;
import com.ningdatech.pmapi.expert.entity.ExpertMetaApply;
import com.ningdatech.pmapi.expert.helper.ExpertInfoSensitiveFieldModifyCheckHelper;
import com.ningdatech.pmapi.expert.helper.PermissionCheckHelper;
import com.ningdatech.pmapi.expert.model.*;
import com.ningdatech.pmapi.expert.model.bo.ExpertInfoSensitiveFieldCheckBO;
import com.ningdatech.pmapi.expert.model.cmd.ExpertAdminExpertManageQueryCmd;
import com.ningdatech.pmapi.expert.model.cmd.ExpertInfoModifyCmd;
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.req.AdminExpertBasicInfoModifyRequest;
import com.ningdatech.pmapi.expert.model.req.GetZzdInfoRequest;
import com.ningdatech.pmapi.expert.model.req.MetaApplyResultRequest;
import com.ningdatech.pmapi.expert.model.vo.ExpertAdminExpertManageListVO;
import com.ningdatech.pmapi.expert.model.vo.ExpertBasicInfoModifyResultVO;
import com.ningdatech.pmapi.expert.model.vo.ZzdInfoByMobileVO;
import com.ningdatech.pmapi.expert.service.ExpertAdminManageService;
import com.ningdatech.pmapi.expert.service.ExpertInfoService;
import com.ningdatech.pmapi.expert.service.IExpertMetaApplyService;
import com.ningdatech.pmapi.meta.constant.DictExpertInfoTypeEnum;
import com.ningdatech.pmapi.meta.constant.ExpertTagEnum;
import com.ningdatech.pmapi.meta.model.ExpertRegionInfo;
import com.ningdatech.pmapi.meta.model.bo.RegionContainsBO;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import com.ningdatech.zwdd.client.ZwddClient;
import com.ningdatech.zwdd.model.dto.DingInfoByMobileDTO;
import com.ningdatech.zwdd.model.dto.DingOrgInfoDTO;
import com.ningdatech.zwdd.model.dto.EmployeeInfoDTO;
import com.ningdatech.zwdd.model.dto.EmployeePositionsDTO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author liuxinxin
 * @date 2023/3/1 下午2:12
 */

@Component
@RequiredArgsConstructor
public class ExpertAdminManage {

    private final PermissionCheckHelper permissionCheckHelper;
    private final RegionLimitHelper regionLimitHelper;
    private final IExpertMetaApplyService iExpertMetaApplyService;
    private final ExpertInfoSensitiveFieldModifyCheckHelper expertInfoSensitiveFieldModifyCheckHelper;
    private final ExpertInfoService expertInfoService;
    private final ExpertMetaApplyManage expertMetaApplyManage;
    private final ExpertAdminManageService expertAdminManageService;
    private final ExpertAdminExpertManageAssembler expertAdminExpertManageAssembler;
    private final ZwddClient zwddClient;

    /**
     * 专家管理员使用 专家库列表查询
     *
     * @param query
     * @return
     */
    public PageVo<ExpertAdminExpertManageListVO> getExpertLibraryList(ExpertAdminExpertManageQuery query) {
        Long userId = LoginUserUtil.getUserId();
        ExpertAdminExpertManageQueryCmd queryCmd = buildExpertAdminExpertManageQueryCmd(query, userId);
        if (queryCmd.isHasNonData()) {
            return PageVo.empty();
        }
        CommonPage<ExpertAdminExpertManageListDTO> pageResult = expertAdminManageService.getExpertLibraryList(queryCmd);

        PageVo<ExpertAdminExpertManageListVO> pageVo = new PageVo<>();
        pageVo.setTotal(pageResult.getItemsTotal());
        pageVo.setRecords(expertAdminExpertManageAssembler.toExpertAdminExpertManageListVOList(pageResult.getItems()));
        return pageVo;
    }


    private ExpertAdminExpertManageQueryCmd buildExpertAdminExpertManageQueryCmd(ExpertAdminExpertManageQuery query, Long userId) {
        ExpertAdminExpertManageQueryCmd queryCmd = new ExpertAdminExpertManageQueryCmd();
        queryCmd.setPageNumber(query.getPageNumber());
        queryCmd.setPageSize(query.getPageSize());
        if (StrUtils.isNotBlank(query.getExpertName())) {
            queryCmd.setExpertName(query.getExpertName());
        }
        if (StrUtils.isNotBlank(query.getCompany())) {
            queryCmd.setCompany(query.getCompany());
        }
        List<ExpertDictionaryQuery> expertDictQueryList = new ArrayList<>();
        if (StringUtils.isNotBlank(query.getTitleLevelDictionaryCode())) {
            ExpertDictionaryQuery expertDictQuery = new ExpertDictionaryQuery();
            expertDictQuery.setExpertInfoField(DictExpertInfoTypeEnum.TITLE_LEVEL.getKey());
            expertDictQuery.setDictionaryCodeList(CollectionUtil.toList(query.getTitleLevelDictionaryCode()));
            expertDictQueryList.add(expertDictQuery);
        }
        if (StringUtils.isNotBlank(query.getCompanyAttributeDictionaryCode())) {
            ExpertDictionaryQuery expertDictQuery = new ExpertDictionaryQuery();
            expertDictQuery.setExpertInfoField(DictExpertInfoTypeEnum.COMPANY_ATTRIBUTE.getKey());
            expertDictQuery.setDictionaryCodeList(CollectionUtil.toList(query.getCompanyAttributeDictionaryCode()));
            expertDictQueryList.add(expertDictQuery);
        }
        if (StringUtils.isNotBlank(query.getExpertTypeDictionaryCode())) {
            ExpertDictionaryQuery expertDictQuery = new ExpertDictionaryQuery();
            expertDictQuery.setExpertInfoField(DictExpertInfoTypeEnum.EXPERT_TYPE.getKey());
            expertDictQuery.setDictionaryCodeList(CollectionUtil.toList(query.getExpertTypeDictionaryCode()));
            expertDictQueryList.add(expertDictQuery);
        }
        List<ExpertTagQuery> expertTagQueryList = new ArrayList<>();
        if (StringUtils.isNotBlank(query.getExpertSourceTagCode())) {
            ExpertTagQuery expertTagQuery = new ExpertTagQuery();
            expertTagQuery.setExpertInfoField(ExpertTagEnum.EXPERT_SOURCE.getKey());
            expertTagQuery.setTagCodeList(CollectionUtil.toList(query.getExpertSourceTagCode()));
            expertTagQueryList.add(expertTagQuery);
        }
        if (StringUtils.isNotBlank(query.getGoodAtTagCode())) {
            ExpertTagQuery expertTagQuery = new ExpertTagQuery();
            expertTagQuery.setExpertInfoField(ExpertTagEnum.GOOD_AT.getKey());
            expertTagQuery.setTagCodeList(CollectionUtil.toList(query.getGoodAtTagCode()));
            expertTagQueryList.add(expertTagQuery);
        }
        if (StringUtils.isNotBlank(query.getExpertAccountStatus())) {
            QueryExpertAccountStatusEnum queryExpertAccountStatus = QueryExpertAccountStatusEnum.of(query.getExpertAccountStatus());
            switch (queryExpertAccountStatus) {
                case NORMAL:
                    queryCmd.setExpertAccountStatusList(CollectionUtil.toList(ExpertAccountStatusEnum.AVAILABLE));
                    break;
                case FREEZING:
                    queryCmd.setExpertAccountStatusList(CollectionUtil.toList(ExpertAccountStatusEnum.FREEZE));
                    break;
                default:
                    break;
            }
        } else {
            queryCmd.setExpertAccountStatusList(CollectionUtil.toList(ExpertAccountStatusEnum.AVAILABLE, ExpertAccountStatusEnum.FREEZE));
        }

        List<RegionContainsBO> expertAdminContainsRegionList;
        // 如果为超级管理员，可以查看所有的专家，包括没有层级的专家
        boolean isSuperAdmin;
        if (!(isSuperAdmin = permissionCheckHelper.isSuperAdmin())) {
            expertAdminContainsRegionList = regionLimitHelper.getExpertAdminContainsRegion(userId);
        } else {
            expertAdminContainsRegionList = Collections.emptyList();
        }

        List<RegionContainsBO> containsRegion = null;
        if (Objects.nonNull(query.getExpertRegionInfo())) {
            RegionContainsBO containsRegionBo = regionLimitHelper.getContainsRegionBo(query.getExpertRegionInfo().getRegionLevel()
                    , query.getExpertRegionInfo().getRegionCode());
            if (isSuperAdmin) {
                containsRegion = Collections.singletonList(containsRegionBo);
            } else {
                containsRegion = regionLimitHelper.queryContainsRegionAssembler(containsRegionBo, expertAdminContainsRegionList);
                if (containsRegion.isEmpty()) {
                    queryCmd.setHasNonData(true);
                    return queryCmd;
                }
            }
        }

        List<RegionContainsBO> intentionRegions = null;
        if (query.getIntentionRegionInfo() != null) {
            ExpertRegionInfo intentionRegionInfo = query.getIntentionRegionInfo();
            RegionContainsBO containsRegionBo = regionLimitHelper.getContainsRegionBo(intentionRegionInfo.getRegionLevel()
                    , intentionRegionInfo.getRegionCode());
            if (isSuperAdmin) {
                intentionRegions = Collections.singletonList(containsRegionBo);
            } else {
                intentionRegions = regionLimitHelper.queryContainsRegionAssembler(containsRegionBo, expertAdminContainsRegionList);
                if (intentionRegions.isEmpty()) {
                    queryCmd.setHasNonData(true);
                    return queryCmd;
                }
            }
        }
        if (containsRegion == null && intentionRegions == null) {
            containsRegion = expertAdminContainsRegionList;
        }
        queryCmd.setExpertDictionaryQueryList(expertDictQueryList);
        queryCmd.setExpertTagQueryList(expertTagQueryList);
        queryCmd.setIsDingUser(query.getIsDingUser());
        queryCmd.setRegionContainsList(containsRegion);
        queryCmd.setIntentionRegionList(intentionRegions);
        queryCmd.setPageSize(query.getPageSize());
        queryCmd.setPageNumber(query.getPageNumber());
        return queryCmd;
    }


    /**
     * 专家管理员修改专家的个人信息接口(包含专家层级变更)
     *
     * @param request
     * @return
     */
    public ExpertBasicInfoModifyResultVO adminModifyExpertBasicInfo(AdminExpertBasicInfoModifyRequest request) {
        Long adminUserId = LoginUserUtil.getUserId();
        Long expertUserId = request.getExpertUserId();
        // 手机号不能更改
        request.getBasicInfo().setPhoneNo(null);

        // 校验当前是否有信息变更审核 如有，无法变更信息
        LambdaQueryWrapper<ExpertMetaApply> infoModifyEq = Wrappers.lambdaQuery(ExpertMetaApply.class)
                .eq(ExpertMetaApply::getUserId, expertUserId)
                .eq(ExpertMetaApply::getApplyType, ExpertApplyTypeEnum.EXPERT_INFO_MODIFY.getKey())
                .eq(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.PENDING_REVIEW.getKey())
                .eq(ExpertMetaApply::getDisplayEnable, BoolDisplayEnum.Y.name());
        ExpertMetaApply infoModifyApply = iExpertMetaApplyService.getOne(infoModifyEq);
        if (Objects.nonNull(infoModifyApply)) {
            throw new BizException("该账号还有信息修审核审核未审批，请撤销或审批后处理");
        }
        // 校验当前是否有层级变更审核,如有需要审核通过或撤销审核后重新提交
        LambdaQueryWrapper<ExpertMetaApply> expertStorageEq = Wrappers.lambdaQuery(ExpertMetaApply.class)
                .eq(ExpertMetaApply::getUserId, expertUserId)
                .eq(ExpertMetaApply::getApplyType, ExpertApplyTypeEnum.EXPERT_STORAGE.getKey())
                .eq(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.PENDING_REVIEW.getKey())
                .eq(ExpertMetaApply::getDisplayEnable, BoolDisplayEnum.Y.name());
        ExpertMetaApply expertStorageApply = iExpertMetaApplyService.getOne(expertStorageEq);
        if (Objects.nonNull(expertStorageApply)) {
            throw new BizException("当前账号还有入库审核未审批，请撤销或审批后处理");
        }

        ExpertBasicInfo basicInfo = request.getBasicInfo();
        ExpertEduInfo eduInfo = request.getEduInfo();
        ExpertJobInfo jobInfo = request.getJobInfo();
        ExpertProfessionalInfo professionalInfo = request.getProfessionalInfo();
        ExpertRecommendInfo recommendInfo = request.getRecommendInfo();
        ExpertOtherInfo otherInfo = request.getExpertOtherInfo();

        ExpertInfoSensitiveFieldCheckBO expertInfoSensitiveFieldCheckBO =
                expertInfoSensitiveFieldModifyCheckHelper.expertInfoSensitiveFieldModifyCheck(basicInfo, eduInfo, jobInfo, professionalInfo, expertUserId);
        ExpertInfoModifyCmd expertInfoModifyCmd = ExpertInfoCmdAssembler
                .buildExpertInfoModifyCmd(expertUserId, basicInfo, eduInfo, jobInfo, professionalInfo, recommendInfo, otherInfo, expertInfoSensitiveFieldCheckBO, null);
        List<Long> applyIdList = expertInfoService.adminModifyExpertInfo(expertInfoModifyCmd, adminUserId);

        // 批量通过专家管理员审核
        for (Long applyId : applyIdList) {
            MetaApplyResultRequest applyResult = new MetaApplyResultRequest();
            applyResult.setApplyId(applyId);
            applyResult.setAuditOpinion("同意");
            applyResult.setApplyResult(true);
            expertMetaApplyManage.metaApplyResult(applyResult);
        }
        return new ExpertBasicInfoModifyResultVO(false);
    }


    public ZzdInfoByMobileVO getZzdInfo(GetZzdInfoRequest request) {
        ZzdInfoByMobileVO zzdInfoByMobileVO = new ZzdInfoByMobileVO();
        String phoneNo = request.getPhoneNo();
        zzdInfoByMobileVO.setPhoneNo(phoneNo);

        GenericResult<DingInfoByMobileDTO> dingInfoByMobile = zwddClient.getDingInfoByMobile(phoneNo);
        DingInfoByMobileDTO dingInfo = dingInfoByMobile.getData();
        if (Objects.nonNull(dingInfo) && StringUtils.isNotBlank(dingInfo.getEmployeeCode())) {
            zzdInfoByMobileVO.setIsDingUser(true);
            String employeeCode = dingInfo.getEmployeeCode();
            GenericResult<List<EmployeePositionsDTO>> listGenericResult = zwddClient.listEmployeePositionsByEmployeeCode(employeeCode);
            List<EmployeePositionsDTO> employeePositionsDTOS = listGenericResult.getData();
            if (CollectionUtils.isNotEmpty(employeePositionsDTOS)) {
                EmployeePositionsDTO employeePositionsDTO = employeePositionsDTOS.get(0);
                String organizationCode = employeePositionsDTO.getOrganizationCode();
                GenericResult<DingOrgInfoDTO> dingOrgInfoDTOGenericResult = zwddClient.getOrganizationByCode(organizationCode);
                DingOrgInfoDTO organizationByCode = dingOrgInfoDTOGenericResult.getData();
                String organizationName = organizationByCode.getOrganizationName();
                zzdInfoByMobileVO.setCompanyName(organizationName);
            }
            GenericResult<EmployeeInfoDTO> infoDTOGenericResult = zwddClient.getEmployeeByCode(employeeCode);
            EmployeeInfoDTO employeeInfoDTO = infoDTOGenericResult.getData();
            if (Objects.nonNull(employeeInfoDTO)) {
                String employeeName = employeeInfoDTO.getEmployeeName();
                zzdInfoByMobileVO.setName(employeeName);
            }
        } else {
            zzdInfoByMobileVO.setIsDingUser(false);
        }
        return zzdInfoByMobileVO;
    }
}
