package nckd.jxccl.opmc.pm.plugin.operate.cycle;

import kd.bos.algo.Algo;
import kd.bos.algo.AlgoContext;
import kd.bos.algo.DataSet;
import kd.bos.algo.Row;
import kd.bos.bd.pojo.CtrlStrategyEnum;
import kd.bos.common.enums.EnableEnum;
import kd.bos.consts.PermItemConst;
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.QueryEntityType;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
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.model.PermissionStatus;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
import kd.hr.hbp.common.model.AuthorizedOrgResultWithSub;
import kd.hr.hbp.common.model.OrgSubInfo;
import kd.sdk.hr.hbp.business.helper.permission.HRPermissionServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.constant.QueryConstant;
import nckd.jxccl.base.common.enums.AppraisalResultEnum;
import nckd.jxccl.base.common.exception.ValidationException;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.base.entity.helper.EntityHelper;
import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
* 周期生成
* 实体标识：nckd_cyclegenerate
* @author W.Y.C
* @date 2025/11/5 17:10
* @version 1.0
*/
public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implements Plugin {

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

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        logger.info("开始执行周期生成操作");
        //获取待生成新周期人员
        Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> pendingCyclePersonnelMap = getPendingCyclePersonnel();
        logger.info("获取到待生成新周期人员数量: {}", pendingCyclePersonnelMap.size());
        
        List<Long> perfManagerId = pendingCyclePersonnelMap.values().stream()
                .map(PerfManagerSaveOpPlugin.PersonPerfInfo::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        //先结束当前周期
       /* QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PerfManagerFormConstant.NCKD_WHYEND)
                .add(PerfManagerFormConstant.NCKD_WAGEEXPLAIN)
                .add(PerfManagerFormConstant.NCKD_THESTATUS)
                .add(PerfManagerFormConstant.NCKD_ACTENDYEAR)
                .addIdNumberName(FormConstant.NCKD_PERSON);

        QFilter filter = QFilterCommonHelper.getIdInFilter(perfManagerId);
        DynamicObject[] dbPerfManagerArray = BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
        for (DynamicObject dbPerfManager : dbPerfManagerArray) {
            long personId = dbPerfManager.getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
            PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = pendingCyclePersonnelMap.get(personId);
            //结束原因
            dbPerfManager.set(PerfManagerFormConstant.NCKD_WHYEND, personPerfInfo.getWhyEnd());
            dbPerfManager.set(PerfManagerFormConstant.NCKD_THESTATUS, "3");
            //实际结束时间（如果endYear大于当前时间（年）则使用endYear否则使用当前时间（年））
            dbPerfManager.set(PerfManagerFormConstant.NCKD_ACTENDYEAR,DateUtil.toDate(personPerfInfo.getActEndYear()));
        }
        SaveServiceHelper.update(dbPerfManagerArray);*/


        //调用save-op
        List<DynamicObject> savePerfManager = new ArrayList<>();
        for (PerfManagerSaveOpPlugin.PersonPerfInfo value : pendingCyclePersonnelMap.values()) {
            DynamicObject newPerfManager = EntityHelper.newEntity(PerfManagerFormConstant.PERFMANAGER_ENTITYID);
            String personName = value.getPerson().getString(FormConstant.NAME_KEY);
            newPerfManager.set(FormConstant.NCKD_EMPPOSORGREL, value.getEmpPosOrgRel());
            newPerfManager.set(FormConstant.NCKD_DEP, value.getAdminOrg());
            newPerfManager.set(FormConstant.NCKD_PERSON, value.getPerson());
            newPerfManager.set(PerfManagerFormConstant.NCKD_BEGINYEAR, DateUtil.toDate(value.getBeginYear()));
            newPerfManager.set(PerfManagerFormConstant.NCKD_ENDYEAR, DateUtil.toDate(value.getEndYear()));
            newPerfManager.set(PerfManagerFormConstant.DESCRIPTION_KEY, value.getDescription());
            newPerfManager.set(PerfManagerFormConstant.CTRLSTRATEGY_KEY, CtrlStrategyEnum.GLOBAL_SHARE.getCtrlStrategy());
            newPerfManager.set(FormConstant.NAME_KEY, StrFormatter.format("【{}】{}~{}的考核周期",personName,value.getBeginYear().getYear(),value.getEndYear().getYear()));
            savePerfManager.add(newPerfManager);
        }
        
        logger.info("准备保存 {} 条新的绩效管理记录", savePerfManager.size());
        
        if(savePerfManager.isEmpty()){
            logger.warn("生成周期完成，本次没有需要生成周期的人员");
            this.operationResult.setShowMessage(true);
            this.operationResult.setSuccess(true);
            this.operationResult.setMessage("生成周期完成，本次没有需要生成周期的人员");
            this.operationResult.setMessageType(1);
        }else {
            OperateOption option = OperateOption.create();
            option.setVariableValue(OperateOptionConst.IGNOREINTERACTION, Boolean.TRUE + "");
            option.setVariableValue("cyclegenerate", Boolean.TRUE + "");
            logger.info("开始执行保存操作，实体ID: {}", PerfManagerFormConstant.PERFMANAGER_ENTITYID);
            OperationResult operationResult = OperationServiceHelper.executeOperate(FormConstant.SAVE_OP, PerfManagerFormConstant.PERFMANAGER_ENTITYID, savePerfManager.toArray(new DynamicObject[0]), option);

            if (!operationResult.isSuccess()) {
                StringJoiner errorMsg = new StringJoiner(StrFormatter.LINE_SEPARATOR);
                for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
                    errorMsg.add(error.getMessage());
                }
                logger.error("周期生成失败，错误信息: {}", errorMsg.toString());
                throw new ValidationException(errorMsg.toString());
            }else{
                //周期生成成功，以下是本次周期生成的人员：
                this.operationResult.setSuccess(true);
                StringJoiner msg = new StringJoiner(StrFormatter.LINE_SEPARATOR);
                msg.add(StrFormatter.format("周期生成成功，本次生成人数【{}】人，以下是本次周期生成的人员：",savePerfManager.size()));
                AtomicInteger index = new AtomicInteger(1);
                for (PerfManagerSaveOpPlugin.PersonPerfInfo value : pendingCyclePersonnelMap.values()) {
                    String personName = value.getPerson().getString(FormConstant.NAME_KEY);
                    String description = value.getDescription();
                    msg.add(StrFormatter.format("{}、【{}】{}",index.getAndIncrement(),personName,value.getWhyEnd()));
                }
                logger.info("周期生成成功，生成了 {} 条记录", savePerfManager.size());
                this.operationResult.setMessage(msg.toString());
            }
        }

    }
    /**
     * 获取待生成新周期人员
     * 入职次年生成：新员工入职后的次年，系统自动生成一个三年考评周期。
     * 上年度绩效结果不合格或基本合格：如果员工上年度绩效结果为"基本合格"或"不合格"，系统会重算考核周期，生成新的三年考评周期。
     * 三年考评周期结束：当一个三年考评周期结束后，次年会自动生成新的三年考评周期。
     *
     * @return: java.util.Map<java.lang.Long, nckd.jxccl.opmc.pm.plugin.operate.cycle.PerfManagerSaveOpPlugin.PersonPerfInfo>
     * @author W.Y.C
     * @date: 2025/11/06 14:19
     */
    public static Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> getPendingCyclePersonnel() {
        logger.info("开始获取待生成新周期人员");
        LocalDateTime now = DateUtil.beginOfYear(DateUtil.now());
        // LocalDateTime lastDate = now;
        LocalDateTime lastDate = DateUtil.minusYears(now, 1);
        LocalDateTime lastBegin = DateUtil.beginOfYear(lastDate);
        LocalDateTime lastEnd = DateUtil.endOfYear(lastDate);

        Long currUserId = RequestContext.get().getCurrUserId();
        Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> personPerfInfoMap = new HashMap<>();

        //查询岗位工资制单位
       /* DynamicObjectCollection postWageUnitList = QueryServiceHelper.query(PerfManagerFormConstant.POSTWAGEUNITLIST_ENTITYID, QueryFieldBuilder.create().addIdNumberName(FormConstant.NCKD_ORG).buildSelect(), null);
        List<Long> postWageUnitIds = postWageUnitList.stream().map(postWageUnit -> postWageUnit.getLong(String.join(".", FormConstant.NCKD_ORG, FormConstant.ID_KEY))).collect(Collectors.toList());*/
        // 在职并去年入职的人员
        QFilter newHireFilter = buildNewHireFilter(lastBegin, lastEnd);


        /*if(!postWageUnitIds.isEmpty()){
            newHireFilter.and(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.COMPANY_KEY), QCP.in, postWageUnitIds);
        }else{
            return personPerfInfoMap;
        }*/



        DynamicObjectCollection newHirePersonList = queryNewHirePersons(newHireFilter);

        // 构建考核周期查询条件
        QFilter perfManagerFilter = buildPerfManagerFilter();
        QueryFieldBuilder perfManagerQueryFieldBuilder = buildPerfManagerQueryFieldBuilder();
        QueryEntityType perfManagerQueryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityTypeNoCache("nckd_perfmanager_query");

        Set<Long> personIds = new HashSet<>();
        try (AlgoContext context = Algo.newContext()) {
            // 查询权限范围内的考核周期
            DataSet perfManagerQueryDataSet = HRQueryEntityHelper.getInstance().getQueryDataSet(
                    perfManagerQueryEntityType, perfManagerQueryFieldBuilder.buildSelectLowerCase(),
                    new QFilter[]{perfManagerFilter}, perfManagerQueryFieldBuilder.buildOrder());

            // 收集所有人员ID
            collectPersonIds(personIds, perfManagerQueryDataSet.copy());

            // 1、去年入职人员生成周期
            logger.info("开始处理去年入职人员生成周期");
            generateCycleForNewHires(personPerfInfoMap, newHirePersonList, personIds, now);
            logger.info("去年入职人员生成周期处理完成，当前待处理人员数: {}", personPerfInfoMap.size());

            // 2、上年度绩效结果不合格或基本合格的人员，并且当前周期是最新的
            logger.info("开始处理上年度绩效结果不合格或基本合格的人员");
            handleUnqualifiedLastYearResults(personPerfInfoMap, perfManagerQueryDataSet.copy(),
                    perfManagerQueryFieldBuilder, lastBegin, now);
            logger.info("上年度绩效结果不合格或基本合格的人员处理完成，当前待处理人员数: {}", personPerfInfoMap.size());

            // 3、上年度无绩效结果（周期开始及结束年份含上年）
            logger.info("开始处理上年度无绩效结果的人员");
            handleMissingLastYearResults(personPerfInfoMap, perfManagerQueryDataSet.copy(),
                    perfManagerQueryFieldBuilder, lastBegin, now);
            logger.info("上年度无绩效结果的人员处理完成，当前待处理人员数: {}", personPerfInfoMap.size());

            // 4、三年考评周期结束（周期结束年份为去年，不管有没有结果）
            logger.info("开始处理三年考评周期结束的人员");
            handleEndedThreeYearCycles(personPerfInfoMap, perfManagerQueryDataSet.copy(),
                    perfManagerQueryFieldBuilder, lastBegin, now);
            logger.info("三年考评周期结束的人员处理完成，最终待处理人员数: {}", personPerfInfoMap.size());
        }
        
        logger.info("获取待生成新周期人员完成，共 {} 人", personPerfInfoMap.size());
        return personPerfInfoMap;
    }

    /**
     * 构建新入职员工查询条件
     */
    private static QFilter buildNewHireFilter(LocalDateTime lastBegin, LocalDateTime lastEnd) {
        QFilter filter = new QFilter(String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.ENTRYDATE), QCP.large_equals, lastBegin)
                .and(String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.ENTRYDATE), QCP.less_equals, lastEnd)
                .and(String.join(".", FormConstant.HRPI_EMPENTREL, FormConstant.LABOR_REL_STATUS, FormConstant.IS_HIRED),
                        QCP.equals, EnableEnum.YES.getCode())
                //岗位绩效工资制
                .and(String.join(".", FormConstant.POSITION_KEY, FormConstant.NCKD_PAYSTDPLAN, FormConstant.NUMBER_KEY), QCP.equals, FormConstant.POST_PERF_WAGE_SYS);
        //数据范围过滤（考评周期有什么权限那么就能生成什么范围的人员）
        QFilter dataRule = HRPermissionServiceHelper.getDataRule(
                RequestContext.get().getCurrUserId(), "nckd_pm",  PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                PermItemConst.ITEM_VIEW, new HashMap<>());
        if (dataRule != null) {
            Object value = dataRule.getValue();
            filter.and(FormConstant.ADMINORG,QCP.in, value);
        }
        return filter;

    }

    /**
     * 提取组织ID列表
     */
    private static List<Long> extractOrgIds(List<OrgSubInfo> orgSubInfos) {
        return orgSubInfos.stream()
                .map(OrgSubInfo::getOrgId)
                .collect(Collectors.toList());
    }

    /**
     * 查询新入职员工信息
     */
    private static DynamicObjectCollection queryNewHirePersons(QFilter filter) {
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .addIdNumberName(FormConstant.HRPI_EMPLOYEE)
                .add(FormConstant.ID_KEY)
                .addIdNumberName(FormConstant.ADMINORG);
        QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType("personfilequery");
        return HRQueryEntityHelper.getInstance().getQueryDyoColl(queryEntityType, queryFieldBuilder.buildSelect(), new QFilter[]{filter}, null);
    }

    /**
     * 构建考核周期查询条件
     */
    private static QFilter buildPerfManagerFilter() {
        QFilter perfManagerFilter = QFilter.of("1=1");
        // 只处理权限范围内的人员
        QFilter dataRule = HRPermissionServiceHelper.getDataRule(
                RequestContext.get().getCurrUserId(), "nckd_pm",  PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                PermItemConst.ITEM_VIEW, new HashMap<>());
        if (dataRule != null) {
            perfManagerFilter.and(dataRule);
        }
//        perfManagerFilter.and(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.IS_SEQLATESTRECORD), QCP.equals,EnableEnum.YES.getCode());
        //岗位绩效工资制
//        perfManagerFilter.and(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.POSITION_KEY,FormConstant.NCKD_PAYSTDPLAN, FormConstant.NUMBER_KEY),QCP.equals,FormConstant.POST_PERF_WAGE_SYS);
        return perfManagerFilter;
    }

    /**
     * 构建考核周期查询字段
     */
    private static QueryFieldBuilder buildPerfManagerQueryFieldBuilder() {
        return QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PerfManagerFormConstant.NCKD_ISCURRENTNEWEST)
                .add(PerfManagerFormConstant.NCKD_BEGINYEAR)
                .add(PerfManagerFormConstant.NCKD_ENDYEAR)
                .addIdNumberName(FormConstant.NCKD_PERSON)
                .addGroup(new String[]{FormConstant.HRPI_EMPPOSORGREL},FormConstant.ID_KEY)
                .addGroup(new String[]{FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG},FormConstant.ID_KEY)
                .addGroup(new String[]{PerfManagerFormConstant.PERFMANAGERENTRY}, FormConstant.ID_KEY, PerfManagerFormConstant.NCKD_APPRAISALYEAR)
                .addIdNumberName(PerfManagerFormConstant.PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALRESULT);
    }

    /**
     * 收集所有人员ID
     */
    private static void collectPersonIds(Set<Long> personIds, DataSet dataSet) {
        while (dataSet.hasNext()) {
            Row next = dataSet.next();
            Long personId = next.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
            personIds.add(personId);
        }
    }

    /**
     * 为新入职员工生成考核周期
     */
    private static void generateCycleForNewHires(Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> personPerfInfoMap,
                                                 DynamicObjectCollection newHirePersonList,
                                                 Set<Long> personIds,
                                                 LocalDateTime now) {
        logger.debug("开始为新入职员工生成考核周期，新入职员工总数: {}", newHirePersonList.size());
        for (DynamicObject person : newHirePersonList) {
            long personId = person.getLong(String.join(".", FormConstant.HRPI_EMPLOYEE, FormConstant.ID_KEY));
            long empPosOrgRelId = person.getLong(FormConstant.ID_KEY);
            long adminOrgId = person.getLong(String.join(".", FormConstant.ADMINORG, FormConstant.ID_KEY));
            // 判断是否已有周期，如果有则不生成
            if (!personIds.contains(personId)) {
                DynamicObject empPosOrgRel = EntityHelper.newEntity(FormConstant.HRPI_EMPPOSORGREL);
                empPosOrgRel.set(FormConstant.ID_KEY, empPosOrgRelId);

                DynamicObject adminOrg = EntityHelper.newEntity(FormConstant.ADMINORG_ENTITYID);
                adminOrg.set(FormConstant.ID_KEY, adminOrgId);

                String personName = person.getString(String.join(".", FormConstant.HRPI_EMPLOYEE, FormConstant.NAME_KEY));
                DynamicObject cyclePerson = EntityHelper.newEntity(FormConstant.HRPI_EMPLOYEE);
                cyclePerson.set(FormConstant.ID_KEY, personId);
                cyclePerson.set(FormConstant.NAME_KEY, personName);
                PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = new PerfManagerSaveOpPlugin.PersonPerfInfo(
                        cyclePerson,empPosOrgRel,adminOrg, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成（新入职）");
                personPerfInfo.setWhyEnd("新入职员工");
                personPerfInfoMap.put(personId, personPerfInfo);
                logger.debug("为新员工 {} 添加周期生成记录", personName);
            } else {
                logger.debug("员工ID {} 已存在周期，跳过生成", personId);
            }
        }
        logger.debug("新入职员工考核周期生成完成，新增 {} 条记录", personPerfInfoMap.size());
    }

    /**
     * 处理上年度绩效不合格或基本合格的人员
     */
    private static void handleUnqualifiedLastYearResults(Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> personPerfInfoMap,
                                                         DataSet perfManagerQueryDataSet,
                                                         QueryFieldBuilder perfManagerQueryFieldBuilder,
                                                         LocalDateTime lastBegin,
                                                         LocalDateTime now) {
        logger.debug("开始处理上年度绩效不合格或基本合格的人员");
        DataSet lastYearFailFilter = perfManagerQueryDataSet.copy().filter(
                        "perfmanagerentry.nckd_appraisalresult.number in ('" + AppraisalResultEnum.UN_QUALIFIED.getCode() + "','" +
                                AppraisalResultEnum.BASICALLY_QUALIFIED.getCode() + "') " +
                                "and YEAR(perfmanagerentry.nckd_appraisalyear) = " + lastBegin.getYear() +
                                " and nckd_iscurrentnewest = true")
                .select(perfManagerQueryFieldBuilder.buildSelect());
        
        int count = 0;
        while (lastYearFailFilter.hasNext()) {
            Row next = lastYearFailFilter.next();
            Long id = next.getLong(FormConstant.ID_KEY);
            Long personId = next.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
            Long empPosOrgRelId = next.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ID_KEY));
            Long adminOrgId = next.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG, FormConstant.ID_KEY));
            String personName = next.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY));
            String appraisalResult = next.getString(String.join(".", PerfManagerFormConstant.PERFMANAGERENTRY,
                    PerfManagerFormConstant.NCKD_APPRAISALRESULT, FormConstant.NUMBER_KEY));
            Date endYear = next.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);

            DynamicObject empPosOrgRel = EntityHelper.newEntity(FormConstant.HRPI_EMPPOSORGREL);
            empPosOrgRel.set(FormConstant.ID_KEY, empPosOrgRelId);

            DynamicObject adminOrg = EntityHelper.newEntity(FormConstant.ADMINORG_ENTITYID);
            adminOrg.set(FormConstant.ID_KEY, adminOrgId);

            DynamicObject person = EntityHelper.newEntity(FormConstant.HRPI_EMPLOYEE);
            person.set(FormConstant.ID_KEY, personId);
            person.set(FormConstant.NAME_KEY, personName);

            PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = new PerfManagerSaveOpPlugin.PersonPerfInfo(
                    person,empPosOrgRel,adminOrg ,DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
            personPerfInfo.setId(id);

            LocalDateTime endYearLocalDateTime = DateUtil.toLocalDateTime(endYear);
            LocalDateTime actualEndYear = endYearLocalDateTime.getYear() > now.getYear() ? now : endYearLocalDateTime;
            personPerfInfo.setActEndYear(actualEndYear);

            if (AppraisalResultEnum.UN_QUALIFIED.getCode().equalsIgnoreCase(appraisalResult)) {
                personPerfInfo.setWhyEnd("上年度绩效【不合格】");
            } else {
                personPerfInfo.setWhyEnd("上年度绩效【基本合格】");
            }

            personPerfInfoMap.put(personId, personPerfInfo);
            count++;
            logger.debug("添加上年度绩效不合格或基本合格人员: {} ({})", personName, appraisalResult);
        }
        logger.debug("上年度绩效不合格或基本合格人员处理完成，共处理 {} 条记录", count);
    }

    /**
     * 处理上年度无绩效结果的人员
     */
    private static void handleMissingLastYearResults(Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> personPerfInfoMap,
                                                     DataSet perfManagerQueryDataSet,
                                                     QueryFieldBuilder perfManagerQueryFieldBuilder,
                                                     LocalDateTime lastBegin,
                                                     LocalDateTime now) {
        logger.debug("开始处理上年度无绩效结果的人员");
        DataSet lastYearNoPerfFilter = perfManagerQueryDataSet.copy().filter(
                        "YEAR(NCKD_BEGINYEAR) <= " + lastBegin.getYear() +
                                " AND YEAR(NCKD_ENDYEAR) >= " + lastBegin.getYear() +
                                " and nckd_iscurrentnewest = true ")
                .select(perfManagerQueryFieldBuilder.buildSelect());

        // 临时存储人员对应的考核结果。key：personId，Value：考核结果编码
        Map<Long, String> personIdAndAppraisalYearMap = new HashMap<>();
        Map<Long, String> personIdAndPersonNameMap = new HashMap<>();
        Map<Long, Long> personIdAndIdMap = new HashMap<>();
        Map<Long, Date> personIdAndEndDateMap = new HashMap<>();
        Map<Long, Long> personIdAndEmpPosOrgRelMap = new HashMap<>();
        Map<Long, Long> personIdAndAdminOrgMap = new HashMap<>();

        int filterCount = 0;
        while (lastYearNoPerfFilter.hasNext()) {
            Row next = lastYearNoPerfFilter.next();
            Long id = next.getLong(FormConstant.ID_KEY);
            Long personId = next.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
            Long empPosOrgRelId = next.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ID_KEY));
            Long adminOrgId = next.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG, FormConstant.ID_KEY));
            String personName = next.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY));
            String appraisalResultNumber = next.getString(String.join(".", PerfManagerFormConstant.PERFMANAGERENTRY,
                    PerfManagerFormConstant.NCKD_APPRAISALRESULT, FormConstant.NUMBER_KEY));
            Date appraisalYear = next.getDate(String.join(".", PerfManagerFormConstant.PERFMANAGERENTRY,
                    PerfManagerFormConstant.NCKD_APPRAISALYEAR));
            Date endYear = next.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);

            if (appraisalYear == null || lastBegin.getYear() == DateUtil.getYear(appraisalYear)) {
                // 没有绩效记录或等于上年度则记录到临时变量
                personIdAndAppraisalYearMap.put(personId, appraisalResultNumber);
                personIdAndPersonNameMap.put(personId, personName);
                personIdAndIdMap.put(personId, id);
                personIdAndEndDateMap.put(personId, endYear);
                personIdAndEmpPosOrgRelMap.put(personId, empPosOrgRelId);
                personIdAndAdminOrgMap.put(personId, adminOrgId);
                filterCount++;
            }
        }
        logger.debug("筛选出 {} 条上年度绩效记录", filterCount);

        // 找出上年度绩效记录为空或等于"无"的人员
        List<Long> filteredPersonIds = personIdAndAppraisalYearMap.entrySet().stream()
                .filter(entry -> AppraisalResultEnum.NONE.getCode().equals(entry.getValue()) || entry.getValue() == null)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
        logger.debug("筛选出 {} 条上年度无绩效结果的人员", filteredPersonIds.size());

        for (Long filteredPersonId : filteredPersonIds) {
            String personName = personIdAndPersonNameMap.get(filteredPersonId);
            DynamicObject empPosOrgRel = EntityHelper.newEntity(FormConstant.HRPI_EMPPOSORGREL);
            empPosOrgRel.set(FormConstant.ID_KEY, personIdAndEmpPosOrgRelMap.get(filteredPersonId));

            DynamicObject adminOrg = EntityHelper.newEntity(FormConstant.ADMINORG_ENTITYID);
            adminOrg.set(FormConstant.ID_KEY, personIdAndAdminOrgMap.get(filteredPersonId));

            DynamicObject person = EntityHelper.newEntity(FormConstant.HRPI_EMPLOYEE);
            person.set(FormConstant.ID_KEY, filteredPersonId);
            person.set(FormConstant.NAME_KEY, personName);

            PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = new PerfManagerSaveOpPlugin.PersonPerfInfo(
                    person,empPosOrgRel,adminOrg, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
            personPerfInfo.setId(personIdAndIdMap.get(filteredPersonId));
            personPerfInfo.setWhyEnd("上年度无绩效结果");

            LocalDateTime endYearLocalDateTime = DateUtil.toLocalDateTime(personIdAndEndDateMap.get(filteredPersonId));
            LocalDateTime actualEndYear = endYearLocalDateTime.getYear() > now.getYear() ? now : endYearLocalDateTime;
            personPerfInfo.setActEndYear(actualEndYear);

            personPerfInfoMap.put(filteredPersonId, personPerfInfo);
            logger.debug("添加上年度无绩效结果人员: {}", personName);
        }
        logger.debug("上年度无绩效结果人员处理完成");
    }

    /**
     * 处理三年考评周期结束的人员
     */
    private static void handleEndedThreeYearCycles(Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> personPerfInfoMap,
                                                   DataSet perfManagerQueryDataSet,
                                                   QueryFieldBuilder perfManagerQueryFieldBuilder,
                                                   LocalDateTime lastBegin,
                                                   LocalDateTime now) {
        logger.debug("开始处理三年考评周期结束的人员");
        DataSet yearEvalEndFilter = perfManagerQueryDataSet.copy().filter(
                        "YEAR(nckd_endyear) = " + lastBegin.getYear() + " and nckd_iscurrentnewest = true ")
                .select(perfManagerQueryFieldBuilder.buildSelect());
        
        int processedCount = 0;
        while (yearEvalEndFilter.hasNext()) {
            Row next = yearEvalEndFilter.next();
            Long id = next.getLong(FormConstant.ID_KEY);
            Long personId = next.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
            Long empPosOrgRelId = next.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ID_KEY));
            Long adminOrgId = next.getLong(String.join(".", FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG, FormConstant.ID_KEY));
            String personName = next.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY));
            Date endYear = next.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);

            if (personPerfInfoMap.get(personId) == null) {
                DynamicObject empPosOrgRel = EntityHelper.newEntity(FormConstant.HRPI_EMPPOSORGREL);
                empPosOrgRel.set(FormConstant.ID_KEY, empPosOrgRelId);

                DynamicObject adminOrg = EntityHelper.newEntity(FormConstant.ADMINORG_ENTITYID);
                adminOrg.set(FormConstant.ID_KEY, adminOrgId);

                DynamicObject person = EntityHelper.newEntity(FormConstant.HRPI_EMPLOYEE);
                person.set(FormConstant.ID_KEY, personId);
                person.set(FormConstant.NAME_KEY, personName);

                PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = new PerfManagerSaveOpPlugin.PersonPerfInfo(
                        person,empPosOrgRel,adminOrg, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
                personPerfInfo.setId(id);
                personPerfInfo.setWhyEnd("三年考评周期结束（周期生成）");

                LocalDateTime endYearLocalDateTime = DateUtil.toLocalDateTime(endYear);
                LocalDateTime actualEndYear = endYearLocalDateTime.getYear() > now.getYear() ? now : endYearLocalDateTime;
                personPerfInfo.setActEndYear(actualEndYear);

                personPerfInfoMap.put(personId, personPerfInfo);
                processedCount++;
                logger.debug("添加三年考评周期结束人员: {}", personName);
            } else {
                logger.debug("人员 {} 已在其他规则中处理，跳过", personName);
            }
        }
        logger.debug("三年考评周期结束人员处理完成，共处理 {} 条记录", processedCount);
    }

}