package nckd.jxccl.hr.hstu.business;

import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDBizException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.enums.PerfPlanRoleEnum;
import nckd.jxccl.base.common.exception.ValidationException;
import nckd.jxccl.base.common.schedule.ProgressCallback;
import nckd.jxccl.base.common.utils.ConvertUtil;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.base.entity.helper.EntityHelper;
import nckd.jxccl.base.org.helper.PersonHelper;
import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
import nckd.jxccl.hr.hstu.common.HonorStudentConstant;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * 【优秀生】-生成评价问卷服务类（生成优秀生评价预计打分人员核心逻辑）
 * @author W.Y.C
 * @date 2025/7/2 16:41
 * @version 1.0
 */
public class CreateEvalQuestService {

    private static final Log logger = LogFactory.getLog(CreateEvalQuestService.class);

    /** 最大递归层级 */
    private static final int MAX_RECURSION_DEPTH = 10;

    /**
     * 批量生成评价问卷
     * @param selectedEvalRule 评价问卷模板
     * @param selectedEvalRule 评价规则
     * @param selectedPerson 被评价人
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/02 17:24
     */
    public static void batchGenerateEvalQuest(DynamicObject evalQuestTpl, DynamicObject selectedEvalRule, DynamicObjectCollection selectedPerson, ProgressCallback callback, Long userId,Long orgId) {
        logger.info("【优秀生考评】-生成综合评测问卷-参数: evalQuestTplId={},selectedEvalRule={} ,selectedPersonSize={}", evalQuestTpl.getLong(FormConstant.ID_KEY), selectedEvalRule.getLong(FormConstant.ID_KEY),selectedPerson.size());
        try {
            // 获取当前用户ID和主组织ID（创建组织）
            Long currUserId = userId;
            if(currUserId == null) {
                currUserId = RequestContext.get().getCurrUserId();
            }
            Long currOrgId = orgId;
            if(currOrgId == null) {
                currOrgId = RequestContext.get().getOrgId();
            }
            //当前登录用户
            DynamicObject currUser = UserServiceHelper.getUserInfoByID(currUserId, HonorStudentConstant.ID_KEY);

            // 获取实体元数据
            MainEntityType bosOrgEntityType = EntityMetadataCache.getDataEntityType(FormConstant.BOS_ORG);
            // 基于元数据创建 DynamicObject
            DynamicObject org = new DynamicObject(bosOrgEntityType);
            org.set(FormConstant.ID_KEY,currOrgId);

            // 配置操作选项（忽略警告）
            OperateOption option = OperateOption.create();
            // 忽略警告
            option.setVariableValue(OperateOptionConst.IGNOREWARN, Boolean.TRUE.toString());
            // 忽略交互提示
            option.setVariableValue(OperateOptionConst.IGNOREINTERACTION, Boolean.TRUE.toString());
            //单据页面操作
            //option.setVariableValue(OperateOptionConst.ISFORMVIEWOPERATION, Boolean.TRUE.toString());

            //查询模板
            evalQuestTpl = BusinessDataServiceHelper.loadSingle(evalQuestTpl.getLong(HonorStudentConstant.ID_KEY),HonorStudentConstant.NCKD_EVALQUESTTPL_ENTITYID);


            StringJoiner ruleColum = new StringJoiner(",");
            ruleColum.add(FormConstant.ID_KEY);
            //其他同级评分人比例
            ruleColum.add(HonorStudentConstant.NCKD_PROPORTION);
            //同级评分人上限人数
            ruleColum.add(HonorStudentConstant.NCKD_UPPER);
            //同级评分人下限人数
            ruleColum.add(HonorStudentConstant.NCKD_LOWER);
            //查询评价规则
            long selectedEvalRuleId = selectedEvalRule.getLong(HonorStudentConstant.ID_KEY);
            selectedEvalRule = BusinessDataServiceHelper.loadSingle(selectedEvalRuleId,HonorStudentConstant.EVALUATIONRULE_ENTITYID);
            if (selectedEvalRule == null) {
                throw new ValidationException("评价规则未找到");
            }
            
            int proportion = selectedEvalRule.getInt(HonorStudentConstant.NCKD_PROPORTION);
            int upper = selectedEvalRule.getInt(HonorStudentConstant.NCKD_UPPER);
            int lower = selectedEvalRule.getInt(HonorStudentConstant.NCKD_LOWER);
            
            // 参数验证
            if (proportion < 0 || proportion > 100) {
                throw new ValidationException("其他同级评分人比例必须在0-100之间");
            }
            if (lower < 0 || upper < lower) {
                throw new ValidationException("同级评分人上限人数必须大于等于下限人数且都大于等于0");
            }
            
            //根据比例计算出的其他部门同级评分人的最小人数（同级评分人下限人数*其他同级评分人比例/100=其他同级评分人下限人数）
            int otherLower = (lower * proportion) / 100;

            List<DynamicObject> evalQuestList = new ArrayList<>();
            for (int i = 0; i < selectedPerson.size(); i++) {
                DynamicObject row = selectedPerson.get(i);
                Long personId = null;
                String personName = null;
                if(row.containsProperty(FormConstant.BASEDATAID_KEY)){
                    //获取页面选择的多选基础数据可能会被存放在fbasedataid中
                    DynamicObject depEmpRow = (DynamicObject)row.getDynamicObject(FormConstant.BASEDATAID_KEY);
                    if (depEmpRow == null) {
                        logger.warn("【优秀生考评】-生成综合评测问卷-跳过无效的人员数据，索引：{}", i);
                        continue;
                    }
                    personId = ConvertUtil.toLong(depEmpRow.getPkValue());
                    personName = depEmpRow.getString("person.name");
                }else{
                    personId = row.getLong(HonorStudentConstant.ID_KEY);
                    personName = row.getString("person.name");
                }

                if (personId == null) {
                    logger.warn("【优秀生考评】-生成综合评测问卷-跳过人员ID为空的数据，索引：{}", i);
                    continue;
                }

                MainEntityType depEmpEntityType = EntityMetadataCache.getDataEntityType(PersonHelper.DEP_EMP_ENTITY_ID);
                DynamicObject person = new DynamicObject(depEmpEntityType);
                person.set(FormConstant.ID_KEY,personId);

                //表头构建
                DynamicObject mainObj = prepareMainObject(person, org, currUser, selectedEvalRule, evalQuestTpl);
                //分录构建
                DynamicObjectCollection entryEntity = fetchExpectedScorers(row, proportion, upper, lower, otherLower, Boolean.TRUE);
                if (entryEntity == null || entryEntity.isEmpty()) {
                    logger.warn("【优秀生考评】-生成综合评测问卷-未能获取到有效的评分人列表，人员ID：{}", personId);
                    continue;
                }
                mainObj.set(HonorStudentConstant.NCKD_EVALQUESTENTRY,entryEntity);
                //保存
                saveQuest(mainObj, option, personName);
                if(callback != null) {
                    //回调进度控件
                    callback.onProgress(i);
                }
            }
            logger.info("【优秀生考评】-生成综合评测问卷-完成");
        }catch (KDBizException e){
            logger.error("【优秀生考评】-生成综合评测问卷-业务异常",e);
            throw e;
        } catch (Exception e){
            logger.error("【优秀生考评】-生成综合评测问卷-系统异常",e);
            throw e;
        }

    }

    /**
     * 保存问卷
     * @param mainObj 主单
     * @param option 操作选项
     * @param personName 评价对象名称
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/15 16:06
     */
    private static void saveQuest(DynamicObject mainObj, OperateOption option, String personName) {
        OperationResult operationResult = SaveServiceHelper.saveOperate(FormConstant.SAVE_OP,HonorStudentConstant.NCKD_EVALQUEST_ENTITYID, new DynamicObject[]{mainObj}, option);
        if (!operationResult.isSuccess()) {
            StringJoiner errorMsg = new StringJoiner("；");
            for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
                errorMsg.add(error.getMessage());
                logger.error("【优秀生考评】-评价对象【{}】生成综合评测问卷-异常，异常信息：{}", personName,error.getMessage());
            }
            throw new KDBizException(StrFormatter.format("评价对象【{}】生成综合评测问卷失败，原因：{}", personName,errorMsg.toString()));
        }
    }

    /**
     * 构建表头
     * @param person
     * @param org
     * @param currUser
     * @param selectedEvalRule
     * @param evalQuestTpl
     * @return: kd.bos.dataentity.entity.DynamicObject
     * @author W.Y.C
     * @date: 2025/07/14 09:44
     */
    private static DynamicObject prepareMainObject(DynamicObject person, DynamicObject org, DynamicObject currUser, DynamicObject selectedEvalRule, DynamicObject evalQuestTpl) {
        DynamicObject mainObj = EntityHelper.newAvailableBasicEntity(HonorStudentConstant.NCKD_EVALQUEST_ENTITYID,org,currUser);
        mainObj.set(HonorStudentConstant.NCKD_EVALPERSON, person);
        mainObj.set(HonorStudentConstant.NCKD_PERIODSTATE, "0");
        mainObj.set(HonorStudentConstant.NCKD_EVALUATIONRULE, selectedEvalRule);
        mainObj.set(HonorStudentConstant.NCKD_EVALQUESTTPL, evalQuestTpl);
        return mainObj;
    }

    /**
     * 获取预计参与问卷打分的用户列表
     * @param person 评分人员
     * @param proportion 其他同级评分人比例
     * @param upper 同级评分人上限人数
     * @param lower 同级评分人下限人数
     * @param otherLower 根据比例计算出的其他部门同级评分人的最小人数（同级评分人下限人数*其他同级评分人比例/100=其他同级评分人下限人数）
     * @param isLeadAndSuperior 是否获取上级和领导
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/10 17:38
     */
    public static DynamicObjectCollection fetchExpectedScorers(DynamicObject person,int proportion,int upper,int lower,int otherLower,boolean isLeadAndSuperior) {
        return fetchExpectedScorers(person, null,null, proportion, upper, lower, otherLower, isLeadAndSuperior);
    }
    /**
     * 获取预计参与问卷打分的用户列表
     * @param person 评分人员
     * @param adminColl 需要圈定的组织范围
     * @param excludePersonList 需要排除的人员
     * @param proportion 其他同级评分人比例
     * @param upper 同级评分人上限人数
     * @param lower 同级评分人下限人数
     * @param otherLower 根据比例计算出的其他部门同级评分人的最小人数（同级评分人下限人数*其他同级评分人比例/100=其他同级评分人下限人数）
     * @param isLeadAndSuperior 是否获取上级和领导
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/10 17:38
     */
    public static DynamicObjectCollection fetchExpectedScorers(DynamicObject person,DynamicObjectCollection adminColl,List<Long> excludePersonList,int proportion,int upper,int lower,int otherLower,boolean isLeadAndSuperior) {
        Long personId = null;
        if(person.containsProperty(FormConstant.BASEDATAID_KEY)){
            //获取页面选择的数据可能会被存放在fbasedataid中
            DynamicObject depEmpRow = (DynamicObject)person.getDynamicObject(FormConstant.BASEDATAID_KEY);
            if (depEmpRow == null) {
                logger.warn("【优秀生考评】-获取人员信息失败，BASEDATAID_KEY为空");
                return new DynamicObjectCollection();
            }
            personId = ConvertUtil.toLong(depEmpRow.getPkValue());
        }else{
            personId = person.getLong(HonorStudentConstant.ID_KEY);
        }
        
        if (personId == null) {
            logger.warn("【优秀生考评】-人员ID为空");
            return new DynamicObjectCollection();
        }

        // Map<String, Object> depEmp = HRPIDepempServiceHelper.getDepemp(personId);
        // TODO 【待修改】新架构没有HRPIDepempServiceHelper类
        Map<String, Object> depEmp = null;
        if (depEmp == null) {
            logger.warn("【优秀生考评】-获取人员信息失败，人员ID：{}", personId);
            return new DynamicObjectCollection();
        }
        
        Long id = ConvertUtil.toLong(depEmp.get(FormConstant.ID_KEY));
        //获取当前人员的组织
        Long adminOrgId = ConvertUtil.toLong(depEmp.get("adminorg_id"));
        //获取当前人员的岗位
        Long positionId = ConvertUtil.toLong(depEmp.get("position_id"));

        DynamicObjectCollection leadColl = new DynamicObjectCollection();
        DynamicObjectCollection superiorColl = new DynamicObjectCollection();
        if(isLeadAndSuperior) {
            //1：获取领导（获取上上级岗位中的人员作为领导）
            DynamicObject parentParentPosition = QueryServiceHelper.queryOne("hbpm_positionhr", "parent.parent.id as parentId", new QFilter[]{QFilterCommonHelper.getIdEqFilter(positionId)});
            if (parentParentPosition != null && parentParentPosition.getLong("parentId") != 0) {
                QFilter positionFilter = new QFilter("position.id", QCP.equals, parentParentPosition.getLong("parentId"));
                DynamicObjectCollection leadTempColl = PersonHelper.getDepEmpEffectivePerson("id,person.name", positionFilter);
                Collections.shuffle(leadTempColl);
                if(!leadTempColl.isEmpty()){
                    DynamicObject lead = leadTempColl.get(0);
                    leadColl.add(lead);
                }
            }

            //2：获取上级（获取上级岗位中的人员作为上级）
            DynamicObject parentPosition = QueryServiceHelper.queryOne("hbpm_positionhr", "parent.id as parentId", new QFilter[]{QFilterCommonHelper.getIdEqFilter(positionId)});
            if (parentPosition != null && parentPosition.getLong("parentId") != 0) {
                QFilter positionFilter = new QFilter("position.id", QCP.equals, parentPosition.getLong("parentId"));
                DynamicObjectCollection superiorTempColl = PersonHelper.getDepEmpEffectivePerson("id,person.name", positionFilter);
                Collections.shuffle(superiorTempColl);
                if(!superiorTempColl.isEmpty()){
                    DynamicObject superior = superiorTempColl.get(0);
                    superiorColl.add(superior);
                }
            }
        }

        /*
        同级人数取数逻辑
        │
        ├─ 读取评价规则：proportion（其他同级评分人比例）, upper（同级评分人上限人数）, lower（同级评分人下限人数） → 计算 otherlower
        │
        ├─ 1：查询当前组织内的同级员工（排除上级、自己）
        │   ├─ 1.1：若人数 >= lower → 只取前 upper 个
        │   └─ 1.2：否则 继续向上级组织查找【上级组织的人员】（最多 10 层）
        │
        ├─ 2：查询同级其他部门在职人员
        │   ├─ 2.1：若人数 >= otherLower → 只取前 otherLower 个
        │   └─ 2.2：否则 继续向上级组织查找【上级组织下所有组织的人员】（最多 10 层）
        │
        └─ 返回最终的同级评分人列表
        */
        //3：查询当前组织内的同级员工
        Set<Long> excludePersons = new HashSet<>();
        if(excludePersonList != null && !excludePersonList.isEmpty()){
            excludePersons.addAll(excludePersonList);
        }
        excludePersons.add(id);
        if(isLeadAndSuperior) {
            leadColl.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong(HonorStudentConstant.ID_KEY)));
            superiorColl.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong(HonorStudentConstant.ID_KEY)));
        }
        //如果有选择组织范围则查询组织范围内的人员，否则使用评价对象的组织
        List<Long> adminOrgIds = new ArrayList<>();
        if(adminColl != null && !adminColl.isEmpty()){
            adminColl.forEach(map ->{
                DynamicObject baseData = map.getDynamicObject(HonorStudentConstant.BASEDATAID_KEY);
                adminOrgIds.add(baseData.getLong(HonorStudentConstant.ID_KEY));
            } );
        }else{
            adminOrgIds.add(adminOrgId);
        }
        DynamicObjectCollection peers = getPeers(adminOrgIds,excludePersons, proportion,upper, lower, otherLower);
        peers.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong(HonorStudentConstant.ID_KEY)));

        //4：同级其他部门在职人员
        DynamicObjectCollection otherPeers = new DynamicObjectCollection();
        if(otherLower > 0) {
            otherPeers = getOtherPeers(adminOrgId, excludePersons, otherLower);
        }


        // 主单据创建
        DynamicObject mainObj = BusinessDataServiceHelper.newDynamicObject(HonorStudentConstant.NCKD_EVALQUEST_ENTITYID);
        //分录创建
        DynamicObjectCollection entryEntity = mainObj.getDynamicObjectCollection(HonorStudentConstant.NCKD_EVALQUESTENTRY);
        ////1：领导、2：上级、3：同级
        if(isLeadAndSuperior) {
            builderEvalQuestEntry(leadColl, PerfPlanRoleEnum.LEAD, entryEntity);
            builderEvalQuestEntry(superiorColl, PerfPlanRoleEnum.SUPERIOR, entryEntity);
        }
        builderEvalQuestEntry(peers, PerfPlanRoleEnum.PEERS, entryEntity);
        builderEvalQuestEntry(otherPeers, PerfPlanRoleEnum.OTHER_PEERS, entryEntity);


        return entryEntity;
    }

    /**
     * 获取同级人员
     *  1.最新一条党政职务履历为副处级及以上人员不作为同级取数
     *  2.工作性质大类过滤掉编码为H01（居休）、H02（退养）、H03（随任）、H04（女工长假）、H05（长期工伤病休）、H06（长期病休）、H07（其他不在岗）、J（外派）的员工,不做为同级
     *  3.除去领导和上级
     *  4.入职超半年、职位非协理员
     * @param adminOrgIds 当前组织ID或自定义选择的组织
     * @param excludePersons 排除的ID
     * @return: kd.bos.dataentity.entity.DynamicObjectCollection
     * @author W.Y.C
     * @date: 2025/07/08 17:48
     */
    private static DynamicObjectCollection getPeers(List<Long> adminOrgIds,Set<Long> excludePersons,int proportion,int upper,int lower,int otherLower){
        //最终的结果
        DynamicObjectCollection finalResult = new DynamicObjectCollection();

        //------ 基本条件 begin------
        QFilter baseFilter = getBaseFilter(excludePersons);
        //------ 基本条件 end------

        //1.查询当前组织内的同级员工
        QFilter adminOrgFilter = new QFilter("adminorg.id", QCP.in, adminOrgIds);
        DynamicObjectCollection depEmpEffectivePerson = PersonHelper.getDepEmpEffectivePerson("id,person.name", baseFilter, adminOrgFilter);
        depEmpEffectivePerson.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong("id")));
        //2.当前组织人数小于下限人数，继续向上级组织查找直到 >= lower
        for (Long adminOrgId : adminOrgIds) {
            if(depEmpEffectivePerson.size() < lower){
                Integer count = recursionGetPeers(adminOrgId, depEmpEffectivePerson, baseFilter, lower, 1);
                depEmpEffectivePerson.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong("id")));
                logger.info("【优秀生考评】-向上级组织查找次数：{}",count);
            }
        }

        //打乱顺序随机抽取前 upper 个
        Collections.shuffle(depEmpEffectivePerson);
        int endIndex = Math.min(depEmpEffectivePerson.size(), upper);
        List<DynamicObject> dynamicObjects = depEmpEffectivePerson.subList(0, endIndex);
        finalResult.addAll(dynamicObjects);

        return finalResult;
    }

    /**
     * 查询同级行政组织下的人员（排除同级确认的人员）
     * @param adminOrgId 当前人员的行政组织id
     * @param excludePersons 需要排除的人员
     * @param otherLower
     * @return: kd.bos.dataentity.entity.DynamicObjectCollection
     * @author W.Y.C
     * @date: 2025/07/10 15:14
     */
    private static DynamicObjectCollection getOtherPeers(Long adminOrgId,Set<Long> excludePersons,int otherLower){
        //最终的结果
        DynamicObjectCollection finalResult = new DynamicObjectCollection();

        //------ 基本条件 begin------
        QFilter baseFilter = getBaseFilter(excludePersons);
        //------ 基本条件 end------
//        Long parentOrg = AdminOrgHelper.getParentOrg(adminOrgId);
        Long parentOrg = null;
        QFilter adminOrgFilter = new QFilter("adminorg.parent.id", QCP.equals, parentOrg);
        //排除自己部门下的人员
        adminOrgFilter.and(new QFilter("adminorg.id", QCP.not_equals, adminOrgId));
        DynamicObjectCollection depEmpEffectivePerson = PersonHelper.getDepEmpEffectivePerson("id,person.name,adminorg.name", baseFilter, adminOrgFilter);
        depEmpEffectivePerson.forEach(dynamicObject -> excludePersons.add(dynamicObject.getLong("id")));

        //2.当前组织人数小于下限人数，继续向上级组织查找直到 >= lower
        if(depEmpEffectivePerson.size() < otherLower){
            Integer count = recursionGetParentPeers(parentOrg, depEmpEffectivePerson, baseFilter, otherLower, 1);
            logger.info("【优秀生考评】-向上级组织查找次数：{}",count);
        }
        Collections.shuffle(depEmpEffectivePerson);
        int endIndex = Math.min(depEmpEffectivePerson.size(), otherLower);
        List<DynamicObject> dynamicObjects = depEmpEffectivePerson.subList(0, endIndex);
        finalResult.addAll(dynamicObjects);
        return finalResult;
    }

    /**
     * 递归上级组织获取人员
     * @param adminOrgId 组织id
     * @param persons 已获取的同级人员
     * @param baseFilter 基本条件
     * @param lower 同级评分人下限人数
     * @param count 递归累计
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/09 16:03
     */
    private static Integer recursionGetPeers(Long adminOrgId,DynamicObjectCollection persons,QFilter baseFilter,int lower,Integer count){
        if(count > MAX_RECURSION_DEPTH) {
            logger.warn("【优秀生考评】-达到最大递归深度：{}。结束递归, 组织ID: {}", MAX_RECURSION_DEPTH, adminOrgId);
            return count;
        }
        
//        Long parentOrg = AdminOrgHelper.getParentOrg(adminOrgId);
        Long parentOrg = null;
        if(parentOrg == null){
            logger.warn("【优秀生考评】-达到最大递归深度或组织为空");
            return count;
        }
        // 创建一个查询条件，用于筛选属于上级组织的人员
        QFilter adminOrgFilter = new QFilter("adminorg.id", QCP.equals, parentOrg);
        DynamicObjectCollection depEmpEffectivePerson = PersonHelper.getDepEmpEffectivePerson("id,person.name,adminorg.name", baseFilter, adminOrgFilter);
        persons.addAll(depEmpEffectivePerson);
        if(persons.size() >= lower){
            return count;
        }else{
            count++;
            if(count == MAX_RECURSION_DEPTH) {
                logger.warn("【优秀生考评】-即将达到最大递归深度, 组织ID: {}", adminOrgId);
            }
            return recursionGetPeers(parentOrg,persons,baseFilter,lower,count);
        }
    }

    /**
     * 递归获取指定管理组织及其所有上级管理组织下的有效人员
     *
     * 该方法从指定的管理组织开始，向上遍历其所有上级管理组织，并收集每个管理组织下的有效人员
     * 直到达到指定的人员数量下限或超过最大递归深度时停止
     *
     * @param adminOrgId 当前管理组织的ID，用于启动递归
     * @param persons 用于存储收集到的所有有效人员的集合
     * @param baseFilter 基础过滤条件，用于筛选有效人员
     * @param lower 人员数量下限，当收集到的人员数量达到或超过这个值时停止递归
     * @param count 当前递归计数，用于防止无限递归，最大为10
     * @return: java.lang.Integer
     * @author W.Y.C
     * @date: 2025/07/10 16:02
     */
    private static Integer recursionGetParentPeers(Long adminOrgId,DynamicObjectCollection persons,QFilter baseFilter,int lower,Integer count){
        if(count > MAX_RECURSION_DEPTH) {
            logger.warn("【优秀生考评】-达到最大递归深度：{}。结束递归, 组织ID: {}", MAX_RECURSION_DEPTH, adminOrgId);
            return count;
        }
        
//        Long parentOrg = AdminOrgHelper.getParentOrg(adminOrgId);
        Long parentOrg = null;
        if(parentOrg == null){
            logger.warn("【优秀生考评】-达到最大递归深度或组织为空");
            return count;
        }
        // 构建用于筛选上级管理组织下有效人员的过滤条件
        QFilter adminOrgFilter = new QFilter("adminorg.parent.id", QCP.equals, parentOrg);
        DynamicObjectCollection depEmpEffectivePerson = PersonHelper.getDepEmpEffectivePerson("id,person.name,adminorg.name", baseFilter, adminOrgFilter);
        persons.addAll(depEmpEffectivePerson);
        if(persons.size() >= lower){
            return count;
        }else{
            count++;
            if(count == MAX_RECURSION_DEPTH) {
                logger.warn("【优秀生考评】-即将达到最大递归深度, 组织ID: {}", adminOrgId);
            }
            return recursionGetParentPeers(parentOrg,persons,baseFilter,lower,count);
        }
    }

    /**
     * 构建问卷分录
     * @param persons 评分人
     * @param perfPlanRole 评分角色
     * @param entryEntity 分录集合
     * @return: void
     * @author W.Y.C
     * @date: 2025/07/13 18:52
     */
    private static void builderEvalQuestEntry(DynamicObjectCollection persons,PerfPlanRoleEnum perfPlanRole,DynamicObjectCollection entryEntity){
        List<Long> personIds = new ArrayList<>(persons.size());
        persons.forEach(person -> personIds.add(person.getLong(HonorStudentConstant.ID_KEY)));
        //获取任职经历
        // List<Map<String, Object>> empOrgRelList = HRPIDepempServiceHelper.listEmpOrgrels(personIds);
        //TODO 【待修改】新架构没有HRPIDepempServiceHelper类
        List<Map<String, Object>> empOrgRelList = null;
        //根据ID分组，获取所属公司和职位
        Map<Long, Map<String, DynamicObject>> empOrgRelMap = empOrgRelList.stream()
                .filter(item -> item.get(FormConstant.DEP_EMP) != null)
                .collect(Collectors.toMap(
                        item -> ConvertUtil.toLong(item.get(FormConstant.DEP_EMP)),
                        item -> {
                            Map<String, DynamicObject> innerMap = new HashMap<>(2);
                            Long companyId = ConvertUtil.toLong(item.get("company"));
                            if(companyId != null && companyId > 0){
                                DynamicObject company = BusinessDataServiceHelper.loadSingle(companyId, FormConstant.ADMINORG_ENTITYID);
                                innerMap.put("company", company);
                            }
                            Long jobId = ConvertUtil.toLong(item.get("job"));
                            if(jobId != null && jobId > 0){
                                DynamicObject job = BusinessDataServiceHelper.loadSingle(jobId, "hbjm_jobhr");
                                innerMap.put("job", job);
                            }
                            return innerMap;
                        },
                        (existing, replacement) -> replacement
                ));
        //获取人员对象
        DynamicObject[] dbPersons = BusinessDataServiceHelper.load(PersonHelper.DEP_EMP_ENTITY_ID,
                "id,person.id,person.name,person.number,adminorg.number,adminorg.name,position.name,position.number",
                new QFilter[]{new QFilter(FormConstant.ID_KEY, QCP.in, personIds)});
        Map<Long, DynamicObject> personMap = new HashMap<>(dbPersons.length);
        for (DynamicObject obj : dbPersons) {
            personMap.put(obj.getLong(FormConstant.ID_KEY), obj);
        }

        persons.forEach(dynamicObject -> {
            DynamicObject evalQuest = entryEntity.addNew();
            long depEmpId = dynamicObject.getLong(HonorStudentConstant.ID_KEY);
            DynamicObject person = personMap.get(depEmpId);
            evalQuest.set(HonorStudentConstant.NCKD_PERSON, person);
            evalQuest.set(HonorStudentConstant.NCKD_PERFPLANROLE, perfPlanRole.getCode());
            //获取任职经历
            Map<String, DynamicObject> empOrgRel = empOrgRelMap.get(depEmpId);
            evalQuest.set(HonorStudentConstant.NCKD_COMPANY, empOrgRel.get("company"));
            evalQuest.set(HonorStudentConstant.NCKD_JOB, empOrgRel.get("job"));
            //备注生成人员对应的角色
            evalQuest.set(HonorStudentConstant.NCKD_REMARK, StrFormatter.format("系统生成：{}",perfPlanRole.getName()));

        });
    }

    /**
     * 查询人员打分人员基本条件
     * @param excludePersons
     * @return: kd.bos.orm.query.QFilter
     * @author W.Y.C
     * @date: 2025/07/10 11:34
     */
    private static QFilter getBaseFilter(Set<Long> excludePersons){
        QFilter baseFilter = new QFilter(HonorStudentConstant.ID_KEY, QCP.not_in, excludePersons);
        //入职超半年
        baseFilter.and(new QFilter("startdate",QCP.less_equals, DateUtil.minusMonths(DateUtil.now(),6)));
        //职位非协理员
        baseFilter.and(new QFilter("position.name", QCP.not_like, "%协理员%"));
        // TODO 1.最新一条党政职务履历为副处级及以上人员不作为同级取数 2.工作性质大类过滤掉编码为H01（居休）、H02（退养）、H03（随任）、H04（女工长假）、H05（长期工伤病休）、H06（长期病休）、H07（其他不在岗）、J（外派）的员工,不做为同级
        return baseFilter;
    }
}