package nckd.jxccl.hr.psms.plugin.operate.performance.validate;

import akka.routing.FromConfig;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.QueryServiceHelper;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.enums.AppraisalResultEnum;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.hr.psms.common.PerfRankMgmtConstant;
import nckd.jxccl.hr.psms.common.PositionStructureConstant;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
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;
import kd.bos.dataentity.utils.ObjectUtils;

/**
* 绩效排名管理保存验证插件
* @author W.Y.C
* @date 2025/10/21 22:39
* @version 1.0
*/
public class PerfRankMgmtSaveValidate extends AbstractValidator {

    private final Map<String, BigDecimal> appraisalResultRatioMap = new HashMap<>();
    @Override
    public void validate() {
        boolean dataMigration = false;
        Object invoker = this.getOption().getVariables().get(FormConstant.HR_INVOKER_PARAM_INVOKER);
        if(ObjectUtils.isEmpty(invoker)){
            Object invoker1 = this.getOption().getVariables().get("hr_hrdmvalidatetag_of_datasource");
            Object invoker2 = this.getOption().getVariables().get("hr_hrdmsynctag_of_datasource");
            if(!ObjectUtils.isEmpty(invoker1) || !ObjectUtils.isEmpty(invoker2)){
                dataMigration = true;
            }
        } else{
            dataMigration = FormConstant.DATA_MIGRATION.equalsIgnoreCase(invoker.toString());
        }
        if(!dataMigration) {
            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                    .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY}, PerfRankMgmtConstant.NCKD_RATIO)
                    .addGroup(new String[]{FormConstant.NCKD_ENTRYENTITY, PositionStructureConstant.NCKD_APPRAISALRESULT}, FormConstant.NUMBER_KEY);
            DynamicObjectCollection query = QueryServiceHelper.query(PerfRankMgmtConstant.RANKRATIOCONF_ENTITYID, queryFieldBuilder.buildSelect(), null);

            query.forEach(dynamicObject -> {
                String key = dynamicObject.getString(String.join(".", FormConstant.NCKD_ENTRYENTITY, PositionStructureConstant.NCKD_APPRAISALRESULT, FormConstant.NUMBER_KEY));
                BigDecimal value = dynamicObject.getBigDecimal(String.join(".", FormConstant.NCKD_ENTRYENTITY, PerfRankMgmtConstant.NCKD_RATIO));
                appraisalResultRatioMap.put(key, value);
            });
            for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                if (appraisalResultRatioMap.isEmpty()) {
                    this.addFatalErrorMessage(rowDataEntity, "没有配置【排名考核结果比例】");
                    return;
                }
                DynamicObject data = rowDataEntity.getDataEntity();
                // 年份校验
                if (validateYear(data, rowDataEntity)) {
                    // 获取明细数据并验证是否为空
                    DynamicObjectCollection entries = data.getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY);
                    if (entries.isEmpty()) {
                        String operateKey = this.getOperateKey();
                        // if (!operateKey.equals(FormConstant.SAVE_OP)) {
                            this.addFatalErrorMessage(rowDataEntity, "请添加排名名单");
                            // continue;
                        // }
                    }
                    int step = data.getInt(PerfRankMgmtConstant.NCKD_STEP);

                    //当步骤为导入考核结果时需校验明细数据

                    // 验证明细数据
                    ValidationContext context = validateEntries(entries, rowDataEntity);

                    // 校验人员是否在其他分组中排名
                    validateRepetition(data, rowDataEntity, context);

                    // 校验人员是否有对应考核周期
                    validatePerfManager(data,entries,rowDataEntity, context);
                    if(step == 1) {
                        // 验证统计数据一致性
                        validateDataConsistency(data, context, rowDataEntity);
                    }
                }
            }
        }
    }

    //校验考核结果人数比例
    private void validateRatio(ValidationContext context, ExtendedDataEntity rowDataEntity) {
        // 总人数
        int totalRankCount = context.totalRankCount;
        // 优秀人数
        int excellentCount = context.excellentCount;
        // 合格人数
        int qualifiedCount = context.qualifiedCount;
        // 基本合格人数
        int basicCount = context.basicCount;
        // 不合格人数
        int failCount = context.failCount;

      /*  // 获取配置比例
        BigDecimal excellentRatio = appraisalResultRatioMap.get(AppraisalResultEnum.EXCELLENT.getCode());
        BigDecimal qualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.QUALIFIED.getCode());
        BigDecimal basicallyQualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.BASICALLY_QUALIFIED.getCode());
        BigDecimal unQualifiedRatio = appraisalResultRatioMap.get(AppraisalResultEnum.UN_QUALIFIED.getCode());*/

        // 计算各等级的理论人数（四舍五入）
       /* int expectedExcellent = calculateExpectedCount(totalRankCount, excellentRatio);
        int expectedQualified = calculateExpectedCount(totalRankCount, qualifiedRatio);
        int expectedBasic = calculateExpectedCount(totalRankCount, basicallyQualifiedRatio);
        int expectedFail = calculateExpectedCount(totalRankCount, unQualifiedRatio);*/

        DynamicObject data = rowDataEntity.getDataEntity();
        int topRanks = data.getInt(PerfRankMgmtConstant.NCKD_TOPRANKS);
        int expectedExcellent = data.getInt(PerfRankMgmtConstant.NCKD_EXCELLENTS);
        int expectedBasic = data.getInt(PerfRankMgmtConstant.NCKD_BASICS);
        int expectedFail = data.getInt(PerfRankMgmtConstant.NCKD_FAILS);
        int expectedQualified = topRanks - expectedExcellent - expectedBasic - expectedFail;



        // 集团本部不校验
        DynamicObject adminOrg = data.getDynamicObject(FormConstant.NCKD_ADMINORG);
        DynamicObject secondOrg = adminOrg.getDynamicObject(FormConstant.NCKD_SECONDORG);
        if(secondOrg == null || !secondOrg.getString(FormConstant.NUMBER_KEY).contains("0101")){
            // 校验各等级人数是否在合理范围内（允许±1的差异）
            /*validateCountRange(AppraisalResultEnum.EXCELLENT.getName(), excellentCount, expectedExcellent, totalRankCount,rowDataEntity);
            validateCountRange(AppraisalResultEnum.QUALIFIED.getName(), qualifiedCount, expectedQualified, totalRankCount,rowDataEntity);
            validateCountRange(AppraisalResultEnum.BASICALLY_QUALIFIED.getName(), basicCount, expectedBasic, totalRankCount,rowDataEntity);
            validateCountRange(AppraisalResultEnum.UN_QUALIFIED.getName(), failCount, expectedFail, totalRankCount,rowDataEntity);*/
        }


    }

    /**
     * 计算理论人数（四舍五入）
     */
    private int calculateExpectedCount(int totalCount, BigDecimal ratio) {
        // 将百分比转换为小数进行计算
        BigDecimal decimalRatio = ratio.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
        BigDecimal expected = decimalRatio.multiply(BigDecimal.valueOf(totalCount));
        return expected.setScale(0, RoundingMode.HALF_UP).intValue();
    }

    /**
     * 校验人数范围（允许±1的差异）
     */
    private void validateCountRange(String levelName, int actualCount, int expectedCount, int totalCount,ExtendedDataEntity rowDataEntity) {
        int difference = Math.abs(actualCount - expectedCount);
        // 允许的差异阈值，可以根据总人数动态调整
        int allowedDifference = Math.max(1, totalCount / 100); // 至少允许1人差异，或总人数的1%

        if (difference > allowedDifference) {

            this.addFatalErrorMessage(rowDataEntity,
                    StrFormatter.format("{}人数与配置比例不符，应为{}人，实际为{}人",
                            levelName, expectedCount,actualCount));
        }
    }


    /**
     * 验证年份字段有效性
     * @param data 数据对象
     * @param rowDataEntity 行数据实体
     * @return: void
     * @author W.Y.C
     * @date: 2025/10/21 22:40
     */
    private boolean validateYear(DynamicObject data, ExtendedDataEntity rowDataEntity) {
        int theYear = data.getInt(PerfRankMgmtConstant.NCKD_THEYEAR);
        int currentYear = DateUtil.now().getYear();
        if (theYear < 1900 || theYear > currentYear) {
            this.addFatalErrorMessage(rowDataEntity, "年份不合法或超过当前年份");
            return false;
        }
        return true;
    }

    /**
     * 验证明细数据
     * @param entries 分录
     * @param rowDataEntity 行数据实体
     * @return: nckd.jxccl.hr.psms.plugin.operate.performance.validate.PerfRankMgmtSaveValidate.ValidationContext
     * @author W.Y.C
     * @date: 2025/10/21 22:40
     */
    private ValidationContext validateEntries(DynamicObjectCollection entries, ExtendedDataEntity rowDataEntity) {
        ValidationContext context = new ValidationContext();
        Set<Long> personIds = new HashSet<>();

        for (int i = 0; i < entries.size(); i++) {
            DynamicObject entry = entries.get(i);
            if(entry.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING)) {
                validateEntry(entry, rowDataEntity, i + 1, personIds, context);
            }
        }
        context.personIds = personIds;

        return context;
    }


    private void validateRepetition(DynamicObject data, ExtendedDataEntity rowDataEntity, ValidationContext context) {
        //根据年度校验人员只能在同一个组
        long id = data.getLong(FormConstant.ID_KEY);
        int theYear = data.getInt(PerfRankMgmtConstant.NCKD_THEYEAR);
        QFilter filter = new QFilter(String.join(".", PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY, PerfRankMgmtConstant.NCKD_PERSON), QCP.in, context.personIds);
        if(id > 0){
            filter.and(FormConstant.ID_KEY, QCP.not_equals, id);
        }
        filter.and(PerfRankMgmtConstant.NCKD_THEYEAR,QCP.equals,theYear);
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.NAME_KEY)
                .add(PerfRankMgmtConstant.NCKD_THEYEAR)
                .addIdNumberName(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY, PerfRankMgmtConstant.NCKD_PERSON);
        DynamicObjectCollection query = QueryServiceHelper.query(PerfRankMgmtConstant.NCKD_PERFRANKMGMT_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
        StringJoiner msgJoiner = new StringJoiner(StrFormatter.LINE_SEPARATOR);
        for (DynamicObject dynamicObject : query) {
            String name = dynamicObject.getString(FormConstant.NAME_KEY);
            String personName = dynamicObject.getString(String.join(".", PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY, PerfRankMgmtConstant.NCKD_PERSON,FormConstant.NAME_KEY));
            msgJoiner.add(StrFormatter.format("人员【{}】已在排名单元【{}】中排名；", personName,name));
        }
        if(msgJoiner.length() > 0){
            this.addFatalErrorMessage(rowDataEntity, msgJoiner.toString());
        }
    }



    private void validatePerfManager(DynamicObject data,DynamicObjectCollection entries, ExtendedDataEntity rowDataEntity, ValidationContext context) {
        //根据年度校验人员只能在同一个组
        int theYear = data.getInt(PerfRankMgmtConstant.NCKD_THEYEAR);
        LocalDate startDate = LocalDate.of(theYear, 1, 1);
        QFilter filter = new QFilter(PerfRankMgmtConstant.NCKD_PERSON, QCP.in, context.personIds);
        filter.and(PerfRankMgmtConstant.NCKD_BEGINYEAR,QCP.less_equals,startDate);
        filter.and(PerfRankMgmtConstant.NCKD_ENDYEAR,QCP.large_equals,startDate);
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .addIdNumberName(PerfRankMgmtConstant.NCKD_PERSON);
        DynamicObjectCollection query = QueryServiceHelper.query(PerfRankMgmtConstant.PERFMANAGER_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
        Map<Long, List<DynamicObject>> personMap = query.stream()
                .filter(obj -> obj.getLong(String.join(".", PerfRankMgmtConstant.NCKD_PERSON, FormConstant.ID_KEY)) > 0)
                .collect(Collectors.groupingBy(
                        obj -> obj.getLong(String.join(".", PerfRankMgmtConstant.NCKD_PERSON, FormConstant.ID_KEY))
                ));
//        StringJoiner msgJoiner = new StringJoiner(StrFormatter.LINE_SEPARATOR);
        for (DynamicObject entry : entries) {
            if(entry.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING)) {
                long person = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY);
                if (!personMap.containsKey(person)) {
                    String personName = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY);
                    this.addFatalErrorMessage(rowDataEntity, StrFormatter.format("人员【{}】没有【{}】年度的考核周期；", personName, theYear));
                }
            }
        }
        /*if(msgJoiner.length() > 0){
            this.addFatalErrorMessage(rowDataEntity, msgJoiner.toString());
        }*/
    }

    /**
     * 验证单条明细数据
     * @param entry 分录
     * @param rowDataEntity 行数据实体
     * @param rowIndex 行索引
     * @param personIds 已处理人员ID集合（用于去重检查）
     *
     * @param context 验证上下文
     * @return: void
     * @author W.Y.C
     * @date: 2025/10/21 22:41
     */
    private void validateEntry(DynamicObject entry, ExtendedDataEntity rowDataEntity,
                               int rowIndex, Set<Long> personIds, ValidationContext context) {
        boolean dataMigration = false;
        Object invoker = this.getOption().getVariables().get(FormConstant.HR_INVOKER_PARAM_INVOKER);
        if(ObjectUtils.isEmpty(invoker)){
            Object invoker1 = this.getOption().getVariables().get("hr_hrdmvalidatetag_of_datasource");
            Object invoker2 = this.getOption().getVariables().get("hr_hrdmsynctag_of_datasource");
            if(!ObjectUtils.isEmpty(invoker1) || !ObjectUtils.isEmpty(invoker2)){
                dataMigration = true;
            }
        } else{
            dataMigration = FormConstant.DATA_MIGRATION.equalsIgnoreCase(invoker.toString());
        }
        DynamicObject person = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON);
        if (person == null) {
            this.addFatalErrorMessage(rowDataEntity, StrFormatter.format("第{}行，请选择人员\n", rowIndex));
        } else {
            // 人员重复校验
            long personId = person.getLong(FormConstant.ID_KEY);
            if (personIds.contains(personId)) {
                this.addFatalErrorMessage(rowDataEntity, StrFormatter.format("第{}行，人员【{}】重复；\n", rowIndex, person.getString(FormConstant.NAME_KEY)));
            } else {
                personIds.add(personId);
            }

            // 统计各类人数
            boolean isRanking = entry.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING);
            boolean postAllowance = entry.getBoolean(PerfRankMgmtConstant.NCKD_POSTALLOWANCE);
            DynamicObject appraisalResult = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_APPRAISALRESULT);

            if (isRanking) {
                context.totalRankCount++;

                if (postAllowance) {
                    context.allowanceRankCount++;
                }
            }

            if (isRanking && appraisalResult != null) {
                String appraisalResultNumber = appraisalResult.getString(FormConstant.NUMBER_KEY);
                AppraisalResultEnum appraisalResultEnum = AppraisalResultEnum.getByCode(appraisalResultNumber);

                if (appraisalResultEnum != null) {
                    switch (appraisalResultEnum) {
                        case EXCELLENT:
                            context.excellentCount++;
                            break;
                        case BASICALLY_QUALIFIED:
                            context.basicCount++;
                            break;
                        case UN_QUALIFIED:
                            context.failCount++;
                            break;
                        case QUALIFIED:
                            context.qualifiedCount++;
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }

    /**
     * 验证数据一致性
     * @param data 数据对象
     * @param context 验证上下文
     * @param rowDataEntity 行数据实体
     * @return: void
     * @author W.Y.C
     * @date: 2025/10/21 22:41
     */
    private void validateDataConsistency(DynamicObject data, ValidationContext context,
                                         ExtendedDataEntity rowDataEntity) {
        // 各类人数一致性校验
        checkCountConsistency(data, context, rowDataEntity);

        // 排名范围校验
        validateRankRanges(data.getDynamicObjectCollection(PerfRankMgmtConstant.NCKD_PERFRANKMGMTENTRY),
                data.getInt(PerfRankMgmtConstant.NCKD_TOPRANKS), rowDataEntity);

        validateRatio(context, rowDataEntity);
    }

    /**
     * 检查统计数据一致性
     * @param data 数据对象
     * @param context 验证上下文
     * @param rowDataEntity 行数据实体
     * @return: void
     * @author W.Y.C
     * @date: 2025/10/21 22:42
     */
    private void checkCountConsistency(DynamicObject data, ValidationContext context,
                                       ExtendedDataEntity rowDataEntity) {
        DynamicObject adminOrg = data.getDynamicObject(FormConstant.NCKD_ADMINORG);
        DynamicObject secondOrg = adminOrg.getDynamicObject(FormConstant.NCKD_SECONDORG);
        if(secondOrg == null || !secondOrg.getString(FormConstant.NUMBER_KEY).contains("0101")) {
            int topRanks = data.getInt(PerfRankMgmtConstant.NCKD_TOPRANKS);
            int allowanceRanks = data.getInt(PerfRankMgmtConstant.NCKD_ALLOWANCERANKS);
            int fails = data.getInt(PerfRankMgmtConstant.NCKD_FAILS);
            int basics = data.getInt(PerfRankMgmtConstant.NCKD_BASICS);
            int excellents = data.getInt(PerfRankMgmtConstant.NCKD_EXCELLENTS);

            if (topRanks != context.totalRankCount) {
                this.addFatalErrorMessage(rowDataEntity, "总排名人数与实际录入数据不一致；\n");
            }
            if (allowanceRanks != context.allowanceRankCount) {
                this.addFatalErrorMessage(rowDataEntity, "R排名人数与实际录入数据不一致；\n");
            }
            if (fails != context.failCount) {
                this.addFatalErrorMessage(rowDataEntity, "不合格人数与实际录入数据不一致；\n");
            }
            if (basics != context.basicCount) {
                this.addFatalErrorMessage(rowDataEntity, "基本人数与实际录入数据不一致；\n");
            }
            if (excellents != context.excellentCount) {
                this.addFatalErrorMessage(rowDataEntity, "优秀人数与实际录入数据不一致；\n");
            }
        }
    }

    /**
     * 验证排名范围和重复情况
     * @param entries 分录集合
     * @param totalRankCount 总排名数
     * @param rowDataEntity 行数据实体
     * @return: void
     * @author W.Y.C
     * @date: 2025/10/21 22:42
     */
    private void validateRankRanges(DynamicObjectCollection entries, int totalRankCount, ExtendedDataEntity rowDataEntity) {
        ValidationContext context = new ValidationContext();

        // 统计每个排名出现的次数
        for (int i = 0; i < entries.size(); i++) {
            DynamicObject entry = entries.get(i);
            DynamicObject person = entry.getDynamicObject(PerfRankMgmtConstant.NCKD_PERSON);

            if (person != null) {
                String personName = person.getString(FormConstant.NAME_KEY);
                boolean isRanking = entry.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING);
                boolean postAllowance = entry.getBoolean(PerfRankMgmtConstant.NCKD_POSTALLOWANCE);

                if (isRanking) {
                    validateAndRecordRank(entry, PerfRankMgmtConstant.NCKD_TOPRANK, "参与排名","排名", personName, rowDataEntity, context.rankCountMap);

                    if (postAllowance) {
//                        validateAndRecordRank(entry, PerfRankMgmtConstant.NCKD_ALLOWANCERANK, "享受职位津贴","R排名", personName, rowDataEntity, context.rankRCountMap);
                    }
                }


            }
        }

        // 找出重复的排名
        findDuplicateRanks(context.rankCountMap, context.duplicateRanks);
        findDuplicateRanks(context.rankRCountMap, context.duplicateRRanks);

        // 检查排名范围和重复率
       for (int i = 0; i < entries.size(); i++) {
            DynamicObject entry = entries.get(i);
            boolean isRanking = entry.getBoolean(PerfRankMgmtConstant.NCKD_ISRANKING);
            boolean postAllowance = entry.getBoolean(PerfRankMgmtConstant.NCKD_POSTALLOWANCE);

            if (isRanking) {
                // 检查排名字段是否在有效范围内
                int topRank = entry.getInt(PerfRankMgmtConstant.NCKD_TOPRANK);
                if (topRank < 1 || topRank > totalRankCount) {
                    this.addFatalErrorMessage(rowDataEntity,
                            StrFormatter.format("第{}行，排名{}超出有效范围[1-{}]\n", i + 1, topRank, totalRankCount));
                }
                /*if (postAllowance) {
                    // 检查R排名字段是否在有效范围内
                    int allowanceRank = entry.getInt(PerfRankMgmtConstant.NCKD_ALLOWANCERANK);
                    if (allowanceRank < 1 || allowanceRank > totalRankCount) {
                        this.addFatalErrorMessage(rowDataEntity,
                                StrFormatter.format("第{}行，R排名{}超出有效范围[1-{}]\n", i + 1, allowanceRank, totalRankCount));
                    }
                }*/
            }
        }

        // 验证排名重复率
        validateRankDuplicateRate(context, totalRankCount, rowDataEntity);

        // 特殊排名组合校验
        validateSpecialRankCombination(context, rowDataEntity);
    }

    /**
     * 验证并记录排名值
     * @param entry 分录对象
     * @param rankField 排名字段名
     * @param rankType 排名类型描述
     * @param personName 人员姓名
     * @param rowDataEntity 行数据实体
     * @param rankCountMap 排名计数映射
     */
    private void validateAndRecordRank(DynamicObject entry, String rankField,String type, String rankType,
                                       String personName, ExtendedDataEntity rowDataEntity,
                                       Map<Integer, Integer> rankCountMap) {
        int rankValue = entry.getInt(rankField);
        if (rankValue < 1) {
            this.addFatalErrorMessage(rowDataEntity, StrFormatter.format("人员【{}】已勾选{}，{}数不能小于1或为空",
                    personName, type, rankType));
        } else {
            rankCountMap.put(rankValue, rankCountMap.getOrDefault(rankValue, 0) + 1);
        }
    }

    /**
     * 查找重复的排名
     * @param rankCountMap 排名计数映射
     * @param duplicateRanks 重复排名集合
     */
    private void findDuplicateRanks(Map<Integer, Integer> rankCountMap, Set<Integer> duplicateRanks) {
        for (Map.Entry<Integer, Integer> entry : rankCountMap.entrySet()) {
            if (entry.getValue() > 1) {
                duplicateRanks.add(entry.getKey());
            }
        }
    }

    /**
     * 特殊排名组合校验
     * 当相同排名重复出现时，其连续序列结束位置不能被其他排名占用
     * @param context 上下文
     * @param rowDataEntity 行数据实体
     * @return: void
     * @author W.Y.C
     * @date: 2025/10/21 22:43
     */
    private void validateSpecialRankCombination(ValidationContext context, ExtendedDataEntity rowDataEntity) {
        // 校验普通排名的特殊组合
        List<String> invalidCombinations = new ArrayList<>();

        // 校验普通排名
        validateSpecialRankCombinationForType(context.rankCountMap, context.duplicateRanks, "排名", invalidCombinations);

        // 校验R排名
        validateSpecialRankCombinationForType(context.rankRCountMap, context.duplicateRRanks, "R排名", invalidCombinations);

        // 如果有不合规的组合，添加详细的错误信息
        if (!invalidCombinations.isEmpty()) {
            StringBuilder errorMsg = new StringBuilder("排名设置不符合规范！\n");
            errorMsg.append("【校验规则】\n");
            errorMsg.append("当相同排名重复出现时，其连续序列结束位置不能被其他排名占用。\n");
            errorMsg.append("【问题详情】\n");
            for (int i = 0; i < invalidCombinations.size(); i++) {
                errorMsg.append(StrFormatter.format("{}. {}\n", i + 1, invalidCombinations.get(i)));
            }
            errorMsg.append("【示例说明】\n");
            errorMsg.append("❌ 不合规示例：[1,2,2,2,4] - 排名2重复3次，结束位置应为2+3-1=4，但4已在列表中\n");
            errorMsg.append("✅ 合规示例：[1,1,1,4] - 排名1重复3次，结束位置应为1+3-1=3，3不在列表中\n");
            errorMsg.append("【解决建议】\n");
            errorMsg.append("请调整重复排名的数值或移除冲突的排名，确保连续序列结束位置未被占用；\n\n");
            this.addFatalErrorMessage(rowDataEntity, errorMsg.toString());
        }
    }

    /**
     * 针对特定类型排名校验特殊组合规则
     * @param rankCountMap 排名计数映射
     * @param duplicateRanks 重复排名集合
     * @param rankType 排名类型（如"排名"、"R排名"）
     * @param invalidCombinations 不合规组合列表
     */
    private void validateSpecialRankCombinationForType(Map<Integer, Integer> rankCountMap,
                                                       Set<Integer> duplicateRanks,
                                                       String rankType,
                                                       List<String> invalidCombinations) {
        // 遍历所有重复的排名
        for (Integer rank : duplicateRanks) {
            int count = rankCountMap.get(rank);
            // 计算连续序列结束值
            int mark = rank + count - 1;

            // 检查结束值是否在列表中存在
            if (rankCountMap.containsKey(mark) && mark != rank) {
                invalidCombinations.add(StrFormatter.format(
                        "{}{}重复{}次，结束位置{}被占用",
                        rankType, rank, count, mark));
            }
        }
    }

    /**
     * 验证排名重复率是否超过阈值
     * @param context 上下文
     * @param totalRankCount 总排名数
     * @param rowDataEntity 行数据实体
     * @return: void
     * @author W.Y.C
     * @date: 2025/10/21 22:44
     */
    private void validateRankDuplicateRate(ValidationContext context, int totalRankCount, ExtendedDataEntity rowDataEntity) {
        // 验证普通排名重复率
        validateRankDuplicateRateForType(context.rankCountMap, context.duplicateRanks, totalRankCount,
                "排名", rowDataEntity);

        // 验证R排名重复率
        validateRankDuplicateRateForType(context.rankRCountMap, context.duplicateRRanks, totalRankCount,
                "R排名", rowDataEntity);
    }

    /**
     * 针对特定类型排名验证重复率
     * @param rankCountMap 排名计数映射
     * @param duplicateRanks 重复排名集合
     * @param totalRankCount 总排名数
     * @param rankType 排名类型
     * @param rowDataEntity 行数据实体
     */
    private void validateRankDuplicateRateForType(Map<Integer, Integer> rankCountMap,
                                                  Set<Integer> duplicateRanks,
                                                  int totalRankCount,
                                                  String rankType,
                                                  ExtendedDataEntity rowDataEntity) {
        if (totalRankCount > 0) {
            double duplicateRate = (double) duplicateRanks.size() / totalRankCount;
            if (duplicateRate > 0.3) {
                // 构建重复排名详情信息
                StringBuilder detailMessage = new StringBuilder();
                detailMessage.append(rankType).append("重复率超过30%，当前重复率: ");
                detailMessage.append(String.format("%.1f", duplicateRate * 100)).append("%，");
                detailMessage.append("具体重复的排名有: ");

                List<Integer> sortedDuplicateRanks = new ArrayList<>(duplicateRanks);
                Collections.sort(sortedDuplicateRanks);

                for (int i = 0; i < sortedDuplicateRanks.size(); i++) {
                    int rank = sortedDuplicateRanks.get(i);
                    int count = rankCountMap.get(rank);
                    detailMessage.append(StrFormatter.format("{}【{}】出现{}次；", rankType, rank, count));
                }
                detailMessage.append("\n");
                this.addFatalErrorMessage(rowDataEntity, detailMessage.toString());
            }
        }
    }

    private void validateUserUniqueAcrossUnits() {

    }

    /**
     * 验证上下文对象，用于存储验证过程中的统计数据
     * @author W.Y.C
     * @date 2025/10/21 22:45
     * @version 1.0
     */
    private static class ValidationContext {
        int totalRankCount = 0;
        int allowanceRankCount = 0;
        int failCount = 0;
        int basicCount = 0;
        int excellentCount = 0;
        int qualifiedCount = 0;
        Set<Long> personIds = new HashSet<>();
        Set<Integer> rankSet = new HashSet<>();  // 记录已出现的排名
        Set<Integer> duplicateRanks = new HashSet<>();  // 记录普通排名中重复的排名
        Set<Integer> duplicateRRanks = new HashSet<>();  // 记录R排名中重复的排名
        Map<Integer, Integer> rankCountMap = new HashMap<>();  // 记录每个普通排名出现的次数
        Map<Integer, Integer> rankRCountMap = new HashMap<>();  // 记录每个R排名出现的次数
    }

}