package nckd.jxccl.hr.psms.plugin.operate.other;

import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.ObjectUtils;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.MainEntityType;
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.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.entity.validate.AbstractValidator;
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.OperationServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.enums.psms.JobSeqEnum;
import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
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.hr.psms.common.PositionStructureConstant;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
* 事务变动生效后调动事件订阅操作插件-管理人员任命
* 实体标识：nckd_mgrappointmgmt
* @author W.Y.C
* @date 2025/12/5 10:44
* @version 1.0
*/
public class MgrAppointMgmtTransferAfterEffectOp extends AbstractOperationServicePlugIn implements Plugin {


    private static final Log log = LogFactory.getLog(MgrAppointMgmtTransferAfterEffectOp.class);

    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        e.getFieldKeys().addAll(this.billEntityType.getAllFields().keySet());
    }

    @Override
    public void onAddValidators(AddValidatorsEventArgs e) {
        e.addValidator(new AbstractValidator() {
            @Override
            public void validate() {
                for (ExtendedDataEntity row : this.getDataEntities()) {
                    DynamicObject dataEntity = row.getDataEntity();
                    //人员
                    DynamicObject employee = dataEntity.getDynamicObject(FormConstant.BB_EM_TID);
                    if(employee == null){
                        this.addFatalErrorMessage(row, "人员不能为空");
                    }
                    //调出岗位
                   /* DynamicObject beforePosition = dataEntity.getDynamicObject(FormConstant.BB_PO_POSITION);
                    if(beforePosition == null){
                        this.addFatalErrorMessage(row, "调出岗位不能为空");
                    }else{
                        //调出前职位序列
                        DynamicObject beforeJobSeq = beforePosition.getDynamicObject(FormConstant.NCKD_JOBSEQ);
                        if(beforeJobSeq == null){
                            this.addFatalErrorMessage(row, "调出前职位序列不能为空");
                        }
                    }*/
                    //调入岗位
                    DynamicObject afterPosition = dataEntity.getDynamicObject(FormConstant.APOSITION);
                    if(afterPosition == null){
                        this.addFatalErrorMessage(row, "调入岗位不能为空");
                    }else{
                        //调入岗位
                       /* DynamicObject afterJobSeq = afterPosition.getDynamicObject(FormConstant.NCKD_JOBSEQ);
                        if(afterJobSeq == null){
                            this.addFatalErrorMessage(row, "调入岗位职位序列不能为空");
                        }*/
                    }

                }
            }
        });
    }



    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        List<Long> personIdList = new ArrayList<>();
        for (DynamicObject dataEntity : e.getDataEntities()) {
            DynamicObject employee = dataEntity.getDynamicObject(FormConstant.BB_EM_TID);
            if(employee != null){
                personIdList.add(employee.getLong(FormConstant.ID_KEY));
            }
        }
        //查询管理人员任命
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY);
        QFilter qFilter = new QFilter(PositionStructureConstant.NCKD_PERSON, QCP.in, personIdList);
        qFilter.and(PositionStructureConstant.NCKD_TYPESTATE, QCP.equals, TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode());
        DynamicObjectCollection query = QueryServiceHelper.query(PositionStructureConstant.NCKD_PERSONPOSFILE, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
        List<Long> ids = query.stream()
                .map(obj -> obj.getLong(FormConstant.ID_KEY))
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
        MainEntityType entityType = EntityMetadataCache.getDataEntityType(PositionStructureConstant.NCKD_PERSONPOSFILE);
        DynamicObject[] load = BusinessDataServiceHelper.load(ids.toArray(new Long[0]), entityType);
        // 按人员分组，Map<人员ID, List<职位档案>>
        Map<Long, List<DynamicObject>> personPosFileMap = Arrays.stream(load)
                .collect(Collectors.groupingBy(
                        obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY))
                ));

        List<DynamicObject> newMgrAppointMgmt = new ArrayList<>();
        List<DynamicObject> endMgrAppointMgmt = new ArrayList<>();
        List<Long> afectPersonIdList = new ArrayList<>();
        for (DynamicObject dataEntity : e.getDataEntities()) {
            DynamicObject afterPosition = dataEntity.getDynamicObject(FormConstant.APOSITION);
            afectPersonIdList.add(afterPosition.getLong(FormConstant.ID_KEY));
        }
        Map<Long, DynamicObject> positionMap = new HashMap<>();
        if(!afectPersonIdList.isEmpty()){
            MainEntityType positionHrEntityType = EntityMetadataCache.getDataEntityType(FormConstant.HBPM_POSITIONHR);
            DynamicObject[] positionArray = BusinessDataServiceHelper.load(afectPersonIdList.toArray(new Long[0]), positionHrEntityType);
            positionMap = java.util.Arrays.stream(positionArray)
                    .collect(Collectors.toMap(
                            obj -> obj.getLong(FormConstant.ID_KEY),
                            obj -> obj,
                            (existing, replacement) -> existing // 如果有重复key，保留现有的值
                    ));
        }
        for (DynamicObject dataEntity : e.getDataEntities()) {
            //人员
            DynamicObject employee = dataEntity.getDynamicObject(FormConstant.BB_EM_TID);
            long empId = dataEntity.getLong(String.join(".", FormConstant.BB_EM_TID, FormConstant.ID_KEY));
           /* //调出岗位
            DynamicObject beforePosition = dataEntity.getDynamicObject(FormConstant.BB_PO_POSITION);
            //调出前职位序列
            DynamicObject beforeJobSeq = beforePosition.getDynamicObject(FormConstant.NCKD_JOBSEQ);*/
            //调入岗位
            DynamicObject afterPosition = dataEntity.getDynamicObject(FormConstant.APOSITION);
            DynamicObject dbAfterPosition = positionMap.get(afterPosition.getLong(FormConstant.ID_KEY));
            //调入岗位
            DynamicObject afterJobSeq = dbAfterPosition.getDynamicObject(FormConstant.NCKD_JOBSEQ);
            String afterJobSeqNumber = afterJobSeq != null ? afterJobSeq.getString(FormConstant.NUMBER_KEY) : null;
            //调动生效日期
            Date effectiveDate = dataEntity.getDate(FormConstant.B_EFFECTIVEDATE);

            List<DynamicObject> personPosFile = personPosFileMap.get(empId);

            if(JobSeqEnum.MANAGE.getCode().equalsIgnoreCase(afterJobSeqNumber)){
                //调入后岗位是管理序列
                //判断有没有在任命的记录，没有则新增。如果有判断状态是不是等于0（已终止），如果是则新增
                boolean needCreateNew = false;
                Date latestEndDate = null;
                if(personPosFile == null || personPosFile.isEmpty()){
                    // 没有任命记录
                    needCreateNew = true;
                }else{
                    // 检查所有记录的状态是否都为已终止(0)
                    boolean allTerminated = true;

                    for(DynamicObject record : personPosFile){
                        String appointStatus = record.getString(PositionStructureConstant.NCKD_APPOINTSTATUS);
                        if(!"0".equals(appointStatus)){
                            allTerminated = false;
                            break;
                        }
                        // 获取记录的终止时间，找到最近的一次
                        Date endDate = record.getDate(PositionStructureConstant.NCKD_ENDDATE);
                        if (endDate != null) {
                            if (latestEndDate == null || endDate.after(latestEndDate)) {
                                latestEndDate = endDate;
                            }
                        }
                    }
                    // 所有记录都是已终止状态
                    if(allTerminated){
                        needCreateNew = true;
                    }
                    // 如果需要使用latestEndDate，可以在这里添加相关逻辑
                    // 例如：可以在新增记录时将此日期作为参考
                }
                if(needCreateNew){
                    DynamicObject newEntity = EntityHelper.newEntity(PositionStructureConstant.NCKD_PERSONPOSFILE);
                    newEntity.set(FormConstant.NCKD_PERSON, employee);
                    Date beginDate;
                    if (latestEndDate != null && latestEndDate.after(effectiveDate)) {
                        // 如果最后结束日期在生效日期之后，则使用最后结束日期加一天
                        beginDate = DateUtil.toDate(DateUtil.addDays(DateUtil.toLocalDateTime(latestEndDate), 1));
                        newEntity.set(FormConstant.DESCRIPTION_KEY, StrFormatter.format("调动单生成任命。（由于最后一次任命结束时间：【{}】，调动生效日期：【{}】，系统自动将本次任命开始日期设置为【{}】）",
                                DateUtil.format(latestEndDate, "yyyy-MM-dd"),
                                DateUtil.format(effectiveDate, "yyyy-MM-dd"),
                                DateUtil.format(beginDate, "yyyy-MM-dd")));
                    } else {
                        // 否则使用生效日期
                        beginDate = effectiveDate;
                        newEntity.set(FormConstant.DESCRIPTION_KEY,"调动单生成任命");
                    }
                    newEntity.set(PositionStructureConstant.NCKD_BEGINDATE, beginDate);
                    newMgrAppointMgmt.add(newEntity);

                }
            }else{
                //调入后岗位不是管理序列
                //判断有没有在任命的记录，有则终止任命
                if(personPosFile != null && !personPosFile.isEmpty()){
                    for(DynamicObject record : personPosFile){
                        String appointStatus = record.getString(PositionStructureConstant.NCKD_APPOINTSTATUS);
                        if(!"1".equals(appointStatus)){
                            // 终止任命
                            record.set(PositionStructureConstant.NCKD_APPOINTSTATUS, "0");
                            record.set(PositionStructureConstant.NCKD_ENDDATE, effectiveDate);
                            record.set(PositionStructureConstant.NCKD_DESCRIPTION, "调动单终止任命");
                            endMgrAppointMgmt.add(record);
                        }
                    }
                }
            }
        }
        if(!newMgrAppointMgmt.isEmpty()) {
            OperateOption operateOption = OperateOption.create();
            operateOption.setVariableValue(PositionStructureConstant.NCKD_TYPESTATE, TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode());
            OperationResult operationResult = OperationServiceHelper.executeOperate(
                    "savenewappointment",
                    PositionStructureConstant.PERSONPOSFILE_ENTITYID,
                    newMgrAppointMgmt.toArray(new DynamicObject[0]),
                    OperateOption.create()
            );

            if (operationResult != null && !operationResult.isSuccess()) {
                StringJoiner errorMsg = new StringJoiner("；");
                for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
                    errorMsg.add(error.getMessage());
                }
                if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
                    errorMsg.add(operationResult.getMessage());
                }
                throw new ValidationException("同步管理人员任命异常，原因：" + errorMsg.toString());
            }
        }
        if(!endMgrAppointMgmt.isEmpty()){
            OperateOption operateOption = OperateOption.create();
            operateOption.setVariableValue(PositionStructureConstant.NCKD_TYPESTATE, TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode());
            OperationResult operationResult = OperationServiceHelper.executeOperate(
                    "endappointment",
                    PositionStructureConstant.PERSONPOSFILE_ENTITYID,
                    endMgrAppointMgmt.toArray(new DynamicObject[0]),
                    OperateOption.create()
            );

            if (operationResult != null && !operationResult.isSuccess()) {
                StringJoiner errorMsg = new StringJoiner("；");
                for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
                    errorMsg.add(error.getMessage());
                }
                if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
                    errorMsg.add(operationResult.getMessage());
                }
                throw new ValidationException("同步管理人员任命异常，原因：" + errorMsg.toString());
            }
        }
    }
}