package jnpf.cultivate.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jnpf.base.entity.ModuleEntity;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.cultivate.mapper.CultivateIdentifyTableMapper;
import jnpf.cultivate.mapper.FtbCultivatePositionStatisticesMapper;
import jnpf.cultivate.mapper.FtbCultivatePromotionNewMapper;
import jnpf.cultivate.service.FtbCultivateExamUserService;
import jnpf.cultivate.service.FtbCultivatePositionAssessmentService;
import jnpf.cultivate.utils.CultivatePerUtils;
import jnpf.cultivate.utils.UserApiV2Util;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.exception.LoginException;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.dto.position.FtbCultivatePositionOrgStatisticesDTO;
import jnpf.model.cultivate.vo.position.FtbCultivatePositionAssessmentOrgStatisticVO;
import jnpf.model.cultivate.vo.position.FtbCultivatePositionOrgStatisticesVO;
import jnpf.model.cultivate.vo.position.PersonStatisticesDto;
import jnpf.model.cultivate.vo.position.web.*;
import jnpf.permission.dto.v2.user.QueryPageUserDTO;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerFilterNodeVO;
import jnpf.permission.vo.v2.position.PositionBaseInfoVO;
import jnpf.permission.vo.v2.position.PositionBoundOrganizeVO;
import jnpf.permission.vo.v2.position.PositionVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.permission.vo.v2.user.UserPageListVO;
import jnpf.permission.vo.v2.user.UserRelationBaseVO;
import jnpf.util.UserProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: peng.hao
 * @create: 2024/7/22:16:01
 */
@Service
public class FtbCultivatePositionAssessmentServiceImpl implements FtbCultivatePositionAssessmentService {

    @Autowired
    CultivatePerUtils cultivatePerUtils;

    @Autowired
    FtbCultivatePositionStatisticesMapper ftbCultivatePositionStatisticesMapper;

    @Resource
    private FtbCultivateExamUserService ftbCultivateExamUserService;

    @Resource
    CultivateIdentifyTableMapper cultivateIdentifyTableMapper;

    @Autowired
    FtbCultivatePromotionNewMapper cultivatePromotionNewMapper;

    @Autowired
    UserApiV2Util userApiV2Util;


    @Autowired
    private UserProvider userProvider;

    /**
     * 返回一个空的分页结果列表
     *
     * @param statisticDTO 统计查询参数DTO
     * @return 空的分页结果列表
     */
    private PageListVO<FtbCultivatePositionAssessmentOrgStatisticVO> returnEmptyList(FtbCultivatePositionOrgStatisticesDTO statisticDTO) {
        PageListVO<FtbCultivatePositionAssessmentOrgStatisticVO> pageInfo = new PageListVO<>();
        PaginationVO pagination = new PaginationVO();
        pagination.setCurrentPage(statisticDTO.getCurrentPage());
        pagination.setPageSize(statisticDTO.getPageSize());
        pagination.setTotal(0);
        pageInfo.setList(new ArrayList<>());
        pageInfo.setPagination(pagination);
        return pageInfo;
    }

    @Override
    public PageListVO<FtbCultivatePositionAssessmentOrgStatisticVO> organizationListStatistics(FtbCultivatePositionOrgStatisticesDTO statisticDTO) {
        Page<FtbCultivatePositionAssessmentOrgStatisticVO> page = statisticDTO.coverCultivatePage();
        // 多选组织情况 根据每一个组织维度统计
        List<String> orgIds = new ArrayList<>();
        List<String> powerOrgList = userApiV2Util.queryPowerOrgList();
        if (CollUtil.isEmpty(powerOrgList)){
            return returnEmptyList(statisticDTO);
        }
        // 勾选

        if ("1".equals(statisticDTO.getSelectLogo()) && CollUtil.isNotEmpty(statisticDTO.getOrgId())) {
            List<String> allOrg = new ArrayList<>(statisticDTO.getOrgId());
            List<String> allOrganize = cultivatePerUtils.getAllOrganizationInformation(statisticDTO.getOrgId());
            if (CollUtil.isNotEmpty(allOrganize)) {
                allOrg.addAll(allOrganize);
            }
            List<String> intersection = UserApiV2Util.getIntersection(powerOrgList, allOrg);
            if(CollUtil.isEmpty( intersection)){
                return returnEmptyList(statisticDTO);
            }
            orgIds = intersection;
        }else if(CollUtil.isNotEmpty(statisticDTO.getOrgId())){
            List<String> intersection = UserApiV2Util.getIntersection(powerOrgList, statisticDTO.getOrgId());
            if(CollUtil.isEmpty( intersection)){
                return returnEmptyList(statisticDTO);
            }
            orgIds = intersection;
        }else{
            orgIds  = powerOrgList;
        }

        // 默认情况
        String orgIdBySpecial = statisticDTO.getOrgIdBySpecial();
        if (StringUtils.isNotEmpty(orgIdBySpecial) && !orgIds.contains(orgIdBySpecial)) {
            orgIds.add(orgIdBySpecial);
        }
        // 手动输入
        String dtoOrgIds = statisticDTO.getOrgIds();
        if (StringUtils.isNotEmpty(dtoOrgIds)) {
            List<PositionBaseInfoVO> positionBaseInfoVOS = userApiV2Util.listPositionBaseInfoByEncodes(Arrays.asList(dtoOrgIds.split(",")), null);
            if(CollUtil.isEmpty(positionBaseInfoVOS)){
                return returnEmptyList(statisticDTO);
            }
            List<String> intersection = UserApiV2Util.getIntersection(orgIds, positionBaseInfoVOS.stream().map(PositionBaseInfoVO::getId).collect(Collectors.toList()));
            if(CollUtil.isEmpty( intersection)){
                return returnEmptyList(statisticDTO);
            }
            orgIds = intersection;
        }
        // 选择岗位 反向查询那些组织下有这个岗位
        String postId = statisticDTO.getPostId();
        List<String> chooseATypes = new ArrayList<>();
        if (StringUtils.isNotEmpty(postId)) {
            chooseATypes = List.of(postId.split(","));
            List<OrganizeGeneralDetailVO> organizeGeneralDetailVOS = userApiV2Util.organizeInfoListByPositionIds(chooseATypes, null);
            if (CollUtil.isNotEmpty(organizeGeneralDetailVOS)) {
                List<String> dimensionByIds = organizeGeneralDetailVOS.stream().map(OrganizeGeneralDetailVO::getId).collect(Collectors.toList());
                List<String> intersection = UserApiV2Util.getIntersection(orgIds, dimensionByIds);
                if (CollUtil.isEmpty(intersection)) {
                    return returnEmptyList(statisticDTO);
                }
                orgIds = intersection;
            } else {
                return returnEmptyList(statisticDTO);
            }
        }
        orgIds = UserApiV2Util.uniqueStringList(orgIds);
        if (orgIds.isEmpty()) {
            return returnEmptyList(statisticDTO);
        }
        List<FtbCultivatePositionAssessmentOrgStatisticVO> records = new ArrayList<>();
        List<OrganizeGeneralDetailVO> organizeEntityList = userApiV2Util.organizesByOrganizeIds(orgIds, null);
        Map<String, OrganizeGeneralDetailVO> orgMap = organizeEntityList.stream().collect(Collectors.toMap(OrganizeGeneralDetailVO::getId, v -> v));
        // 根据组织查询岗位
//        Map<String, List<String>> batchListByOrganizeIds = positionApi.batchListByOrganizeIds(orgIds);
//        Map<String, List<PositionBaseInfoVO>> batchListByOrganizeIds = userApiV2Util.listPositionBaseInfoByIdsReturnMap(orgIds, null);
        List<PositionBoundOrganizeVO> positionBoundOrganizeVOS = userApiV2Util.batchQueryPositionForOrgIdsReturnList(orgIds, null);
        Map<String, List<PositionBoundOrganizeVO>> batchListByOrganizeIds= new HashMap<>();//组织id 到岗位信息
        if(CollUtil.isNotEmpty(positionBoundOrganizeVOS)){
            batchListByOrganizeIds = positionBoundOrganizeVOS.stream().collect(Collectors.groupingBy(PositionBoundOrganizeVO::getOrganizeId));
        }

        List<String> allPostId = new ArrayList<>();
        for (PositionBoundOrganizeVO positionBoundOrganizeVO : positionBoundOrganizeVOS) {
            allPostId.add(positionBoundOrganizeVO.getId());
        }
        List<String>  dbExiestPostId = new ArrayList<>();
        if(CollUtil.isNotEmpty(allPostId)) {
            dbExiestPostId = ftbCultivatePositionStatisticesMapper.getPostIds(allPostId);
        }
        if(CollUtil.isNotEmpty(chooseATypes)){
            allPostId.addAll(chooseATypes);
        }
        String tenantId = UserProvider.getUser().getTenantId();
        Map<String, PositionVO> stringPositionVOMap = userApiV2Util.listPositionDetailInfoByIdsReturnMap(allPostId, tenantId);

        List<UserPageListVO> userListForOrgIds = userApiV2Util.getUserListForOrgIds(orgIds, tenantId);
        Map<String,List<UserPageListVO>> userMap = new HashMap<>();//组织id_岗位id ->用户
        if(CollUtil.isNotEmpty(userListForOrgIds)){
            for (UserPageListVO userListForOrgId : userListForOrgIds) {
                String k = userListForOrgId.getOrganizeId() +"_" + userListForOrgId.getPositionId();
                List<UserPageListVO> list = userMap.get(k);
                if (list == null) {
                    list = new ArrayList<>();
                }
                list.add(userListForOrgId);
                userMap.put(k, list);
            }
        }

        // 岗位学习岗位
        for (String orgId : orgIds) {
            List<String> orgIdsCollect = new ArrayList<>();
            if (CollUtil.isNotEmpty(batchListByOrganizeIds.get(orgId))) {
                for (PositionBaseInfoVO positionBaseInfoVO : batchListByOrganizeIds.get(orgId)) {
                    orgIdsCollect.add(positionBaseInfoVO.getId());
                }
            }
            if (CollUtil.isEmpty(orgIdsCollect)) continue;
//            if (CollUtil.isNotEmpty(chooseATypes)) {
//                postIds = chooseATypes;
//            } else {
//                postIds = ftbCultivatePositionStatisticesMapper.getPostIds(orgIdsCollect);
//            }
            List<String>  postIds = UserApiV2Util.getIntersection(dbExiestPostId, orgIdsCollect);
            if(CollUtil.isNotEmpty(chooseATypes)){
                postIds = UserApiV2Util.getIntersection(postIds, chooseATypes);
            }
            if (CollUtil.isEmpty(postIds)) continue;
            postIds.forEach(dbPostId -> {
                List<UserPageListVO> userBoundVOS = userMap.get(orgId+"_"+dbPostId);//userApiV2Util.getUserListForOrgIdAndPositionId(orgId,dbPostId, tenantId);

                FtbCultivatePositionAssessmentOrgStatisticVO orgStatisticVO = new FtbCultivatePositionAssessmentOrgStatisticVO();
                // 组织名称和组织id
                OrganizeGeneralDetailVO organizeGeneralDetailVO = orgMap.get(orgId);
                if(organizeGeneralDetailVO!=null) {
                    orgStatisticVO.setOrganizationCustomId(organizeGeneralDetailVO.getEnCode());
                    orgStatisticVO.setOrganization(organizeGeneralDetailVO.getName());
                }
                orgStatisticVO.setOrgId(orgId);

                List<String> userIdsByGradesId = new ArrayList<>();
                if (CollUtil.isNotEmpty(userBoundVOS)) {
                    userIdsByGradesId = userBoundVOS.stream().map(UserPageListVO::getId).collect(Collectors.toList());
                }
                // 展示id
                PositionVO positionInfoDimensionVO = stringPositionVOMap.get(dbPostId);
                if (positionInfoDimensionVO != null) {
                    orgStatisticVO.setPositionCustomId(positionInfoDimensionVO.getEnCode());
                    orgStatisticVO.setPositionTitle(positionInfoDimensionVO.getFullName());
                }
                orgStatisticVO.setPositionId(dbPostId);
                // 获取该岗位下所有人
                // 岗位所有人员数
                orgStatisticVO.setNumberOfPositions(userIdsByGradesId.size());
                // 查询这些人是否产生岗位学习记录
                // 根据岗位查询
                if (CollUtil.isNotEmpty(userIdsByGradesId)) {

                    // 考试合格率
                    // 考试合格人数
                    FtbCultivatePositionExamVO examAndIdentifyVO = ftbCultivateExamUserService.queryExamPassingInformation(dbPostId, userIdsByGradesId);
                    orgStatisticVO.setNumberExam(examAndIdentifyVO.getNumberExam());
                    orgStatisticVO.setExamPassRate(examAndIdentifyVO.getExamPassRate());
                    // 鉴定合格率
                    // 鉴定合格人数
                    FtbCultivatePositionIdentifyVO cultivatePositionIdentifyVO = cultivateIdentifyTableMapper.queryQualificationInformation(userIdsByGradesId, dbPostId);
                    orgStatisticVO.setNumberAppraisal(cultivatePositionIdentifyVO.getNumberAppraisal());
                    orgStatisticVO.setAppraisalPassRate(cultivatePositionIdentifyVO.getAppraisalPassRate());
                }
                records.add(orgStatisticVO);
            });
        }
        return CultivatePage.paginate(records, page);
    }

    @Override
    public FtbCultivatePositionAssessmentVO jobAssessmentList(String orgId, String positionId, CultivatePage page) {
        FtbCultivatePositionAssessmentVO assessmentVO = new FtbCultivatePositionAssessmentVO();
        QueryPageUserDTO dto = new QueryPageUserDTO();
        dto.setTenantId(userProvider.get().getTenantId());

        dto.setPageSize(100000L);
        dto.setCurrentPage(1L);
        dto.setOrganizeId(orgId);
        dto.setPositionId(positionId);
        PageListVO<UserBoundVO> userBoundVOPageListVO = userApiV2Util.pageListUserForWhere(dto);
        List<String> stringList = new ArrayList<>();
        if (userBoundVOPageListVO != null && CollectionUtil.isNotEmpty(userBoundVOPageListVO.getList())) {
            stringList = userBoundVOPageListVO.getList().stream().map(UserBoundVO::getId).collect(Collectors.toList());
        } else {
            return assessmentVO;
        }

        Page<FtbCultivatePositionAssessmentListVO> cultivatePage = page.coverCultivatePage();
        // 根据组织岗位查询下面所有的人
        // 根据查询岗位查询对应的岗位考试合格分
        BigDecimal examPassingScore = ftbCultivatePositionStatisticesMapper.qualifyingPointsForJobRelatedExaminations(positionId);
        // 根据查询岗位查询对应的岗位实操合格分
        BigDecimal appraisalPassingPoints = ftbCultivatePositionStatisticesMapper.qualifyingPointsForJobRelatedAppraisal(positionId);

        assessmentVO.setExamPassingScore(examPassingScore);
        assessmentVO.setAppraisalPassingPoints(appraisalPassingPoints);
        //根据组织和岗位id查询人


//        Map<String, String> userNameMap = cultivatePerUtils.queryRosterNameBasedOnUserId(stringList);
        Map<String, UserBoundVO> userNameMap = userApiV2Util.getUserPrimaryBoundBatch(stringList, null);
        List<FtbCultivatePositionAssessmentListVO> list = new ArrayList<>();
//        OrganizeEntity infoById = organizeApi.getInfoById(orgId);
        OrganizeGeneralDetailVO infoById = userApiV2Util.organizeInfoById(orgId, null);

        PositionVO entity = userApiV2Util.infoPosition(positionId, null);
        // 查询岗位下人的完课情况
        // 1 课程完成数 2为全部
        Map<String, PersonStatisticesDto> map1 = batchQueryCount(stringList, 1, positionId);
        Map<String, PersonStatisticesDto> map2 = batchQueryCount(stringList, 2, positionId);
        stringList.forEach(userId -> {
            FtbCultivatePositionAssessmentListVO vo = new FtbCultivatePositionAssessmentListVO();
            UserBoundVO userBoundVO = userNameMap.get(userId);
            if(userBoundVO!=null) {
                vo.setAppraiser(userBoundVO.getUserName());
            }
            if (infoById != null) {
                vo.setOrgName(infoById.getName());
            }
            if (ObjectUtil.isNotEmpty(entity)) {
                vo.setPostName(entity.getFullName());
            }
            List<String> exmIds = cultivatePromotionNewMapper.checkIfThereAreExamsForThisPositionWithNew(positionId, userId);
            // 是否有岗位学习考试
            boolean thereIsAnExam = CollUtil.isNotEmpty(exmIds);
            // 查询这些人是否产生岗位学习记录
            // 考试合格率
            // 考试合格人数
            if (thereIsAnExam) {
                FtbCultivatePositionExamPersonVO personVO = ftbCultivateExamUserService.queryTheListOfQualifiedPersons(List.of(userId), positionId, exmIds);
                if (ObjectUtil.isNotEmpty(personVO)) {
                    vo.setJobExamScores(personVO.getTestScores());
                    vo.setIsPassJobExamination(personVO.getIsPassTheExam());
                }
            }
            List<String> applyIds = cultivatePromotionNewMapper.checkWhetherThereIsAPracticalAppraisalWithNew(positionId, userId);
            boolean identified = CollUtil.isNotEmpty(applyIds);
            if (identified) {
                FtbCultivatePositionIdentifyPersonVO personVO = cultivateIdentifyTableMapper.currentPersonSAssessmentInformation(userId, applyIds);
                if (ObjectUtil.isNotEmpty(personVO)) {
                    vo.setJobAppraisalScore(personVO.getIdentificationScore());
                    Integer identification = personVO.getIsPassTheIdentification();
                    if (identification == 0) {
                        vo.setIsPassJobAppraisalScore("合格");
                    } else if (identification == 1) {
                        vo.setIsPassJobAppraisalScore("优秀");
                    } else {
                        vo.setIsPassJobAppraisalScore("不合格");
                    }
                }
            }
            //  [1:已经完成考试或者合格   2:未完成考试, 3:考试未合格]
            Integer i = ftbCultivateExamUserService.queryExamIsCompleteForUserIdAndPostion(userId, positionId, 0);
            // 当前考试已经完成
            boolean finishExam = false;
            if (thereIsAnExam && 1 == i) {
                // 当前考试已经完成
                finishExam = true;
            }
            Integer count = 0;
            // 查询当前鉴定是否完成
            boolean finishIdentification = false;
            if (!applyIds.isEmpty())
                count = cultivatePromotionNewMapper.queryTheNumberOfPracticalAppraisalStudies(List.of(positionId), userId, applyIds, 0);
            if (!applyIds.isEmpty() && count > 0) {
                finishIdentification = true;
            }
            // 岗位完课率
            // 完课率 已经学习完的课程书/（未学习的课程数+学习中的课程数+已学习的课程数）
            PersonStatisticesDto count1 = map1.get(userId);
            Integer numberOfCourses = 0;
            // 岗位学习数
            boolean courseBloo = false;
            if (null != count1) {
                numberOfCourses = count1.getNum();
                courseBloo = true;
            }
            PersonStatisticesDto count2 = map2.get(userId);
            Integer totalOfCourses = 0;
            if (null != count2) {
                totalOfCourses = count2.getNum();
            }
            vo.setJobCompletionRate(FtbCultivatePositionStatisticesServiceImpl.computeDivision(numberOfCourses, totalOfCourses));
            //同时绑定有鉴定和考试时，要两个都合格岗位考核才算合格
            //只绑定了鉴定时，鉴定合格岗位考核算合格
            //只绑定了考试时，考试合格岗位考核算合格
            //只绑定了课程时，课程学习完岗位考核算合格
            extracted(vo, thereIsAnExam, identified, courseBloo, finishExam, finishIdentification);
            list.add(vo);
        });
        long count = list.stream().filter(item -> "合格".equals(item.getIsPassJobAssessment())).count();
        assessmentVO.setQualifiedNumberOfPeople(count);
        assessmentVO.setList(CultivatePage.paginate(list, cultivatePage));
        return assessmentVO;
    }

    /**
     * @param vo
     * @param thereIsAnExam        是否有考试
     * @param identified           是否有鉴定
     * @param courseBloo           是否完成课程
     * @param finishExam           是否已经完成考试
     * @param finishIdentification 是否已经完成鉴定
     */
    private void extracted(FtbCultivatePositionAssessmentListVO vo, boolean thereIsAnExam, boolean identified, boolean courseBloo, boolean finishExam, boolean finishIdentification) {
        // 有考试和鉴定
        if (thereIsAnExam && identified && finishExam && finishIdentification && StringUtils.isNotEmpty(vo.getIsPassJobExamination()) && StringUtils.isNotEmpty(vo.getIsPassJobAppraisalScore())) {
            String string = (!"不合格".equals(vo.getIsPassJobExamination()) && !"不合格".equals(vo.getIsPassJobAppraisalScore())) ? "合格" : "不合格";
            vo.setIsPassJobAssessment(string);
            // 有考试没有鉴定
        } else if (thereIsAnExam && finishExam && !identified && StringUtils.isNotEmpty(vo.getIsPassJobExamination())) {
            //  String string = "不合格".equals(vo.getIsPassJobExamination())  ? "不合格" : "合格";
            //vo.setIsPassJobAssessment(string);
            // 有鉴定没有考试
        } else if (!thereIsAnExam && identified && finishIdentification && StringUtils.isNotEmpty(vo.getIsPassJobAppraisalScore())) {
            //    String string =  "不合格".equals(vo.getIsPassJobAppraisalScore())  ? "不合格" : "合格";
            // vo.setIsPassJobAssessment(string);
            //只绑定了课程时，课程学习完岗位考核算合格
        } else if (!thereIsAnExam && !identified && courseBloo) {
            // vo.setIsPassJobAssessment("合格");
        }
    }

    /**
     * 查询岗位下课程完成情况
     *
     * @param idsByGradesId
     * @param type
     * @param positionId
     * @return
     */
    private Map<String, PersonStatisticesDto> batchQueryCount(List<String> idsByGradesId, int type, String positionId) {
        Map<String, PersonStatisticesDto> ret = new HashMap<>();
        if (CollectionUtil.isEmpty(idsByGradesId)) {
            return ret;
        }
        List<PersonStatisticesDto> list = ftbCultivatePositionStatisticesMapper.queryCourseCompletionStatusOfThePosition(positionId, idsByGradesId, type);
        if (CollectionUtil.isEmpty(list)) {
            return ret;
        }
        ret = list.stream().collect(Collectors.toMap(PersonStatisticesDto::getUserId, Function.identity(), (k1, k2) -> k1));
        return ret;
    }

}
