package nckd.jxccl.opmc.pm.helper;

import kd.bos.common.enums.EnableEnum;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.MainEntityType;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
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.orm.helper.QFilterCommonHelper;
import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 考核周期帮助类
 *
 * @author W.Y.C
 * @date 2025/11/4 17:06
 * @version 1.0
 */
public class PerfManagerHelper {


    /**
     * 根据人员和日期查询全排名结果
     * @param date 日期
     * @param personIds 人员id
     * @return: java.util.Map<java.lang.Long, nckd.jxccl.base.common.enums.AppraisalResultEnum>
     * @author W.Y.C
     * @date: 2025/11/15 22:40
     */
    public static Map<Long, AppraisalResultEnum> getPerfRankResult(Date date, Collection<Long> personIds) {

        QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_THEYEAR, QCP.equals, DateUtil.getYear(date))
                .and(String.join(".", PerfManagerFormConstant.NCKD_PERFRANKMGMTENTRY, FormConstant.NCKD_PERSON), QCP.in, personIds)
                .and(String.join(".", PerfManagerFormConstant.NCKD_PERFRANKMGMTENTRY, PerfManagerFormConstant.NCKD_ISRANKING), QCP.equals, EnableEnum.YES.getCode());
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .addIdNumberName(PerfManagerFormConstant.NCKD_PERFRANKMGMTENTRY, PerfManagerFormConstant.NCKD_APPRAISALRESULT)
                .addIdNumberName(PerfManagerFormConstant.NCKD_PERFRANKMGMTENTRY, PerfManagerFormConstant.NCKD_PERSON);
        DynamicObjectCollection query = QueryServiceHelper.query(PerfManagerFormConstant.NCKD_PERFRANKMGMT_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
        Map<Long, AppraisalResultEnum> resultMap = new HashMap<>();
        for (DynamicObject obj : query) {
            long personId = obj.getLong(String.join(".", PerfManagerFormConstant.NCKD_PERFRANKMGMTENTRY, PerfManagerFormConstant.NCKD_PERSON, FormConstant.ID_KEY));
            String resultNumber = obj.getString(String.join(".", PerfManagerFormConstant.NCKD_PERFRANKMGMTENTRY, PerfManagerFormConstant.NCKD_APPRAISALRESULT, FormConstant.NUMBER_KEY));
            AppraisalResultEnum resultEnum = AppraisalResultEnum.getByCode(resultNumber);
            if (resultEnum != null) {
                resultMap.put(personId, resultEnum);
            }

        }

        return resultMap;
    }


    /**
     * 根据日期查询范围内的考核周期
     * 查询逻辑说明：
     * 1. 开始时间条件：考核周期的开始年份(NCKD_BEGINYEAR)必须小于等于指定日期
     * 2. 结束时间条件：优先使用实际结束年份(NCKD_ACTENDYEAR)，如果为空则使用计划结束年份(NCKD_ENDYEAR)
     * 3. 结束时间必须大于等于指定日期
     * 4. 即查找满足 "NCKD_BEGINYEAR <= date <= (NCKD_ACTENDYEAR为空时取NCKD_ENDYEAR)" 条件的考核周期
     *
     * @param date      指定查询日期
     * @param personIds 人员ID集合
     * @return 符合条件的考核周期数组
     * @author W.Y.C
     * @date 2025/11/4 17:06
     */
    public static DynamicObject[] getByDate(Date date, Collection<Long> personIds) {
        QueryFieldBuilder queryFieldBuilder = createDefaultQueryFieldBuilder();

        // 构造查询条件：日期在[NCKD_BEGINYEAR, NCKD_ENDYEAR]范围内
        // 考虑到NCKD_ACTENDYEAR可能为空，优先使用NCKD_ACTENDYEAR作为结束时间
        QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_BEGINYEAR, QCP.less_equals, date)
                .and(new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.in, personIds));

        // 添加结束时间判断逻辑
        QFilter endDateFilter = new QFilter(PerfManagerFormConstant.NCKD_ACTENDYEAR, QCP.large_equals, date)
                .or(new QFilter(PerfManagerFormConstant.NCKD_ACTENDYEAR, QCP.is_null, null)
                        .and(new QFilter(PerfManagerFormConstant.NCKD_ENDYEAR, QCP.large_equals, date)));

        filter.and(endDateFilter);

        return BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                queryFieldBuilder.buildSelect(), new QFilter[]{filter});
    }

    /**
     * 获取当前人员所有考核周期
     *
     * @param personIds   人员ID集合
     * @param otherFilter 其他过滤条件
     * @return 符合条件的考核周期数组
     * @author W.Y.C
     * @date 2025/11/13 22:16
     */
    public static DynamicObject[] getByPersonId(Collection<Long> personIds, QFilter otherFilter) {
        QueryFieldBuilder queryFieldBuilder = createDefaultQueryFieldBuilder()
                .orderDesc(PerfManagerFormConstant.NCKD_BEGINYEAR);

        QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.in, personIds);
        if (otherFilter != null) {
            filter.and(otherFilter);
        }
        return BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                queryFieldBuilder.buildSelect(), new QFilter[]{filter});
    }

    /**
     * 查询开始时间之前的考核周期
     *
     * @param beginYear   开始年份
     * @param personIds   人员ID集合
     * @param otherFilter 其他过滤条件
     * @return 符合条件的考核周期数组
     * @author W.Y.C
     * @date 2025/11/13 22:16
     */
    public static DynamicObject[] getBeforeBeginYear(Date beginYear, Collection<Long> personIds, QFilter otherFilter) {
        QueryFieldBuilder queryFieldBuilder = createDefaultQueryFieldBuilder();

        QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_BEGINYEAR, QCP.less_equals, beginYear)
                .and(new QFilter(PerfManagerFormConstant.NCKD_THESTATUS, QCP.equals, EnableEnum.YES.getCode()))
                .and(new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.in, personIds));
        if (otherFilter != null) {
            filter.and(otherFilter);
        }

        return BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                queryFieldBuilder.buildSelect(), new QFilter[]{filter});
    }
    
    /**
     * 批量查询不同人员在各自指定日期前的考核周期
     *
     * @param personDateMap 人员ID与日期的映射关系
     * @param otherFilter   其他过滤条件
     * @return 符合条件的考核周期数组
     */
    public static DynamicObject[] getBeforeBeginYear(Map<Long, Date> personDateMap, QFilter otherFilter) {
        if (personDateMap == null || personDateMap.isEmpty()) {
            return new DynamicObject[0];
        }

        QueryFieldBuilder queryFieldBuilder = createDefaultQueryFieldBuilder();

        // 构建OR条件查询不同人员的不同日期
        QFilter orFilter = null;
        for (Map.Entry<Long, Date> entry : personDateMap.entrySet()) {
            Long personId = entry.getKey();
            Date beginYear = entry.getValue();
            
            // 为每个人员构建独立的查询条件
            QFilter personFilter = new QFilter(PerfManagerFormConstant.NCKD_BEGINYEAR, QCP.less_equals, beginYear)
                    .and(new QFilter(PerfManagerFormConstant.NCKD_THESTATUS, QCP.equals, EnableEnum.YES.getCode()))
                    .and(new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.equals, personId));
            
            // 使用OR连接所有人员的条件
            if (orFilter == null) {
                orFilter = personFilter;
            } else {
                orFilter = orFilter.or(personFilter);
            }
        }

        QFilter finalFilter = orFilter;
        if (otherFilter != null) {
            finalFilter.and(otherFilter);
        }

        return BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                queryFieldBuilder.buildSelect(), new QFilter[]{finalFilter});
    }

    /**
     * 根据人员获取当前最新的考核周期
     *
     * @param personIds 人员ID
     * @return 符合条件的考核周期数组
     * @author W.Y.C
     * @date 2025/11/04 17:31
     */
    public static DynamicObject[] getNewestPerfManagerByPerson(Collection<Long> personIds) {
        return getNewestPerfManagerByPerson(personIds, null);
    }

    /**
     * 根据ID获取考核周期
     *
     * @param ids ID集合
     * @return 考核周期数组
     */
    public static DynamicObject[] getById(Collection<Long> ids) {
        QFilter filter = QFilterCommonHelper.getIdInFilter(ids);
        MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(PerfManagerFormConstant.PERFMANAGER_ENTITYID);

        return BusinessDataServiceHelper.load(ids.toArray(new Long[0]), dataEntityType);
    }

    /**
     * 根据人员获取当前最新的考核周期（"是否当前最新记录 = true" 并且 "周期状态 = 1"）
     *
     * @param personIds   人员ID
     * @param otherFilter 其他过滤条件
     * @return 符合条件的考核周期数组
     * @author W.Y.C
     * @date 2025/11/04 17:30
     */
    public static DynamicObject[] getNewestPerfManagerByPerson(Collection<Long> personIds, QFilter otherFilter) {
        QueryFieldBuilder queryFieldBuilder = createDefaultQueryFieldBuilder();

        QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_ISCURRENTNEWEST, QCP.equals, EnableEnum.YES.getCode())
                .and(new QFilter(PerfManagerFormConstant.NCKD_THESTATUS, QCP.equals, EnableEnum.YES.getCode()))
                .and(new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.in, personIds));
        if (otherFilter != null) {
            filter.and(otherFilter);
        }

        return BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                queryFieldBuilder.buildSelect(), new QFilter[]{filter});
    }

    /**
     * 根据人员获取当前最新的考核周期（根据"周期开始时间"）
     *
     * @param personIds   人员ID
     * @param otherFilter 其他过滤条件
     * @return 符合条件的考核周期列表
     * @author W.Y.C
     * @date 2025/11/04 17:30
     */
    public static List<DynamicObject> getNewestPerfManagerByPersonAndBeginYear(Collection<Long> personIds, QFilter otherFilter) {
        QueryFieldBuilder queryFieldBuilder = createDefaultQueryFieldBuilder()
                .add(PerfManagerFormConstant.CREATE_TIME_KEY)
                .orderDesc(PerfManagerFormConstant.NCKD_BEGINYEAR);

        QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.in, personIds);
        if (otherFilter != null) {
            filter.and(otherFilter);
        }

        DynamicObject[] load = BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                queryFieldBuilder.buildSelect(), new QFilter[]{filter}, queryFieldBuilder.buildOrder());

        // 只取每个人员最新记录（先按NCKD_BEGINYEAR，再按CREATE_TIME_KEY）
        Map<Long, DynamicObject> latestRecordMap = new HashMap<>();
        for (DynamicObject dynamicObject : load) {
            DynamicObject person = dynamicObject.getDynamicObject(FormConstant.NCKD_PERSON);
            Date beginDate = dynamicObject.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
            Date createTime = dynamicObject.getDate(PerfManagerFormConstant.CREATE_TIME_KEY);
            long personId = person.getLong(FormConstant.ID_KEY);

            // 如果map中没有该personId的记录，或者当前记录的beginDate更晚，
            // 或者beginDate相同但createTime更晚，则更新记录
            if (!latestRecordMap.containsKey(personId)) {
                latestRecordMap.put(personId, dynamicObject);
            } else {
                Date existingBeginDate = latestRecordMap.get(personId).getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                if (beginDate.after(existingBeginDate)) {
                    latestRecordMap.put(personId, dynamicObject);
                } else if (beginDate.equals(existingBeginDate)) {
                    Date existingCreateTime = latestRecordMap.get(personId).getDate(PerfManagerFormConstant.CREATE_TIME_KEY);
                    if (createTime != null && (existingCreateTime == null || createTime.after(existingCreateTime))) {
                        latestRecordMap.put(personId, dynamicObject);
                    }
                }
            }
        }
        return new ArrayList<>(latestRecordMap.values());
    }

    /**
     * 根据人员将所有IsCurrentNewest更新为非最新的
     *
     * @param personId 人员ID（可传多个）
     * @author W.Y.C
     * @date 2025/09/28 21:18
     */
    public static void markAsNotCurrentNewest(Long... personId) {
        QFilter filter = new QFilter(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY), QCP.in, personId);
        QueryFieldBuilder queryField = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(FormConstant.NCKD_ISCURRENTNEWEST);
        DynamicObject[] personPosFileColl = BusinessDataServiceHelper.load(PerfManagerFormConstant.PERFMANAGER_ENTITYID,
                queryField.buildSelect(), new QFilter[]{filter});
        for (DynamicObject personPosFile : personPosFileColl) {
            personPosFile.set(FormConstant.NCKD_ISCURRENTNEWEST, Boolean.FALSE);
        }
        SaveServiceHelper.update(personPosFileColl);
    }

    /***
     * 将人员最新考核周期标记为最新的并修改状态为正常
     * @param personIds 人员ID（可传多个）
     * @param otherFilter 其他条件
     * @return: void
     * @author W.Y.C
     * @date: 2025/11/19 18:07
     */
    public static void markAsCurrentNewestAndUpdateStatus(Collection personIds, QFilter otherFilter) {
        List<DynamicObject> perfManagerColl = getNewestPerfManagerByPersonAndBeginYear(personIds, otherFilter);
        DynamicObject[] updatePerfManagerColl = new DynamicObject[perfManagerColl.size()];
        for (int i = 0; i < perfManagerColl.size(); i++) {
            DynamicObject dynamicObject = perfManagerColl.get(i);
            dynamicObject.set(FormConstant.NCKD_ISCURRENTNEWEST, Boolean.TRUE);

            String theStatus = dynamicObject.getString(PerfManagerFormConstant.NCKD_THESTATUS);
            if(theStatus.equalsIgnoreCase("3")){
                //结束状态标记为正常
                dynamicObject.set(PerfManagerFormConstant.NCKD_THESTATUS, EnableEnum.YES.getCode());
                dynamicObject.set(PerfManagerFormConstant.NCKD_WHYEND,null);
                dynamicObject.set(PerfManagerFormConstant.NCKD_ACTENDYEAR,null);
            }
            updatePerfManagerColl[i] = dynamicObject;
        }
        SaveServiceHelper.update(updatePerfManagerColl);
    }

    /**
     * 将人员最新考核周期标记为最新的
     *
     * @param personIds   人员ID（可传多个）
     * @param otherFilter 其他条件
     * @author W.Y.C
     * @date 2025/09/28 21:18
     */
    public static void markAsCurrentNewest(Collection personIds, QFilter otherFilter) {
        List<DynamicObject> perfManagerColl = getNewestPerfManagerByPersonAndBeginYear(personIds, otherFilter);
        DynamicObject[] updatePerfManagerColl = new DynamicObject[perfManagerColl.size()];
        for (int i = 0; i < perfManagerColl.size(); i++) {
            DynamicObject dynamicObject = perfManagerColl.get(i);
            dynamicObject.set(FormConstant.NCKD_ISCURRENTNEWEST, Boolean.TRUE);
            updatePerfManagerColl[i] = dynamicObject;
        }
        SaveServiceHelper.update(updatePerfManagerColl);
    }

    /**
     * 创建默认的查询字段构建器
     *
     * @return QueryFieldBuilder实例
     */
    private static QueryFieldBuilder createDefaultQueryFieldBuilder() {
        return QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .addIdNumberName(FormConstant.NCKD_EMPPOSORGREL)
                .addIdNumberName(FormConstant.NCKD_PERSON)
                .addIdNumberName(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT)
                .addIdNumberName(PerfManagerFormConstant.NCKD_SECONDYEARRESULT)
                .addIdNumberName(PerfManagerFormConstant.NCKD_THIRDYEARRESULT)
                .add(PerfManagerFormConstant.NCKD_BEGINYEAR)
                .add(PerfManagerFormConstant.NCKD_ENDYEAR)
                .add(PerfManagerFormConstant.NCKD_ACTENDYEAR)
                .add(PerfManagerFormConstant.NCKD_WHYEND)
                .add(PerfManagerFormConstant.NCKD_THESTATUS)
                .add(PerfManagerFormConstant.NCKD_ISCURRENTNEWEST)
                .add(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY)
                .addIdNumberName(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALRESULT)
                .addGroup(new String[]{PerfManagerFormConstant.NCKD_PERFMANAGERENTRY},
                        PerfManagerFormConstant.NCKD_APPRAISALRESULT,
                        PerfManagerFormConstant.NCKD_APPRAISALYEAR,
                        PerfManagerFormConstant.NCKD_ISALLRANKSOURCE);
    }
}
