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

import kd.bos.common.enums.EnableEnum;
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.dataentity.utils.ObjectUtils;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.constant.StatusEnum;
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.args.BeginOperationTransactionArgs;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.constant.FormConstant;
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.entity.helper.EntityHelper;
import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
import nckd.jxccl.hr.psms.common.PositionStructureConstant;

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

/**
* 高级人才新建聘任
* 实体标识：nckd_newseniorappoint
* @author W.Y.C
* @date 2025/12/25 19:28
* @version 1.0
*/
public class NewSeniorAppointOpPlugin extends AbstractOperationServicePlugIn implements Plugin {

    @Override
    public void onAddValidators(AddValidatorsEventArgs e) {
        e.addValidator(new AbstractValidator() {

            @Override
            public void validate() {
                //员工【吴洁】已存在高级人才聘任
                //聘任开始日期超出当前日期!请重新操作!
                List<Long> personIds = new ArrayList<>();
                for (ExtendedDataEntity dataEntity : getDataEntities()) {
                    DynamicObject data = dataEntity.getDataEntity();
                    DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
                    if (person == null) {
                        this.addFatalErrorMessage(dataEntity,"请填写员工");
                    }else{
                        personIds.add(data.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY)));
                    }
                    Date beginDate = data.getDate(PositionStructureConstant.NCKD_BEGINDATE);
                    if(beginDate == null){
                        this.addFatalErrorMessage(dataEntity,"请填写聘任开始日期");
                    }
                    //判断开始日期是否超出当前日期
                    if (beginDate != null && beginDate.after(new Date())) {
                        this.addFatalErrorMessage(dataEntity,"聘任开始日期超出当前日期");
                    }

                }

                QFilter keyFilter = new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
                        .and(PositionStructureConstant.NCKD_TYPESTATE,QCP.equals, TypeStateEnum.HIGH_PROFESSIONAL_EMPLOYMENT.getCode())
                        .and(PositionStructureConstant.NCKD_EMPLOYMENTSTATUS,QCP.equals, EnableEnum.YES.getCode());
                QueryFieldBuilder keyFieldBuilder = QueryFieldBuilder.create()
                        .addIdNumberName(PositionStructureConstant.NCKD_PERSON)
                        .addIdNumberName(PositionStructureConstant.NCKD_JOBSEQHR)
                        .addIdNumberNameWithExtras(new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},FormConstant.JOBLEVELSEQ)
                        .add(PositionStructureConstant.NCKD_BEGINDATE)
                        .orderDesc(PositionStructureConstant.NCKD_BEGINDATE);
                DynamicObjectCollection keyList = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, keyFieldBuilder.buildSelect(), new QFilter[]{keyFilter}, keyFieldBuilder.buildOrder());
                // 按人员分组，取最新一条记录
                Map<Long, DynamicObject> keyListLatestMap = keyList.stream()
                        .collect(Collectors.groupingBy(
                                obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY)),
                                Collectors.toList()
                        ))
                        .entrySet()
                        .stream()
                        .collect(Collectors.toMap(
                                Map.Entry::getKey,
                                entry -> entry.getValue().get(0) // 由于已按日期降序排列，取第一条即为最新
                        ));

                Map<Long, DynamicObject> empPosOrgRelByEmployeesMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
                for (ExtendedDataEntity dataEntity : getDataEntities()) {
                    DynamicObject data = dataEntity.getDataEntity();
                    DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
                    if (person != null)  {
                        long personId = data.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
                        DynamicObject latest = keyListLatestMap.get(personId);
                        if (latest != null) {
                            this.addFatalErrorMessage(dataEntity, "员工【" + data.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY)) + "】已存在高级人才聘任");
                        }
                        DynamicObject empPosOrgRel = empPosOrgRelByEmployeesMap.get(personId);
                        if (empPosOrgRel == null) {
                            this.addFatalErrorMessage(dataEntity, "员工【" + data.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY)) + "】不存在任职信息");
                        } else {
                            DynamicObject position = empPosOrgRel.getDynamicObject(FormConstant.POSITION_KEY);
                            if (position == null) {
                                this.addFatalErrorMessage(dataEntity, "员工【" + data.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY)) + "】不存在职位信息");
                            } else {
                                DynamicObject jobSeq = position.getDynamicObject(FormConstant.NCKD_JOBSEQ);
                                if (jobSeq == null) {
                                    this.addFatalErrorMessage(dataEntity, "员工【" + data.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY)) + "】不存在职位序列");
                                }

                            }
                        }
                    }
                }
            }
        });
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {

        List<Long> personIds = new ArrayList<>();
        for (DynamicObject dataEntity : e.getDataEntities()) {
            long personId = dataEntity.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
            personIds.add(personId);
        }
        Map<Long, DynamicObject> empPosOrgRelByEmployeesMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
        List<DynamicObject> saveDynamicObjectList = new ArrayList<>();
        for (DynamicObject dataEntity : e.getDataEntities()) {
            Date beginDate = dataEntity.getDate(PositionStructureConstant.NCKD_BEGINDATE);
            long personId = dataEntity.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
            DynamicObject empPosOrgRel = empPosOrgRelByEmployeesMap.get(personId);
            DynamicObject newPersonPosFile = EntityHelper.newEntity(PositionStructureConstant.PERSONPOSFILE_ENTITYID);
            newPersonPosFile.set(PositionStructureConstant.NCKD_PERSON, dataEntity.getDynamicObject(FormConstant.NCKD_PERSON));
            newPersonPosFile.set(PositionStructureConstant.NCKD_FIRSTRANK, EnableEnum.YES.getCode());
            newPersonPosFile.set(PositionStructureConstant.NCKD_BEGINDATE, beginDate);
            DynamicObject position = empPosOrgRel.getDynamicObject(FormConstant.POSITION_KEY);
            DynamicObject jobSeq = position.getDynamicObject(FormConstant.NCKD_JOBSEQ);
            newPersonPosFile.set(PositionStructureConstant.NCKD_JOBSEQHR, jobSeq);
            newPersonPosFile.set(PositionStructureConstant.NCKD_POSITIONHR, position);
            newPersonPosFile.set(PositionStructureConstant.NCKD_DEP, empPosOrgRel.getDynamicObject(FormConstant.ADMINORG));
            newPersonPosFile.set(PositionStructureConstant.NCKD_JOBLEVELHR, dataEntity.getDynamicObject(PositionStructureConstant.NCKD_JOBLEVELHR));
            newPersonPosFile.set(PositionStructureConstant.NCKD_TYPESTATE, TypeStateEnum.HIGH_PROFESSIONAL_EMPLOYMENT.getCode());
            newPersonPosFile.set(PositionStructureConstant.NCKD_EXECUTEYEAR, DateUtil.getYear(beginDate));
            newPersonPosFile.set(PositionStructureConstant.NCKD_EMPLOYMENTSTATUS, EnableEnum.YES.getCode());
            newPersonPosFile.set(PositionStructureConstant.NCKD_DISABLE, EnableEnum.NO.getCode());
            newPersonPosFile.set(PositionStructureConstant.STATUS, StatusEnum.C.toString());
            newPersonPosFile.set(PositionStructureConstant.ENABLE, EnableEnum.YES.getCode());
            newPersonPosFile.set(PositionStructureConstant.CREATOR_KEY, RequestContext.get().getCurrUserId());
            saveDynamicObjectList.add(newPersonPosFile);
        }
        OperationResult operationResult = SaveServiceHelper.saveOperate(PositionStructureConstant.PERSONPOSFILE_ENTITYID, saveDynamicObjectList.toArray(new DynamicObject[0]), OperateOption.create());
        if (!operationResult.isSuccess()) {
            StringJoiner errorMsg = new StringJoiner("\n");
            for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
                errorMsg.add(error.getMessage());
            }
            if (!ObjectUtils.isEmpty(operationResult.getMessage())) {
                errorMsg.add(operationResult.getMessage());
            }
            throw new ValidationException("聘任高级人才失败，原因：" + errorMsg.toString());
        }
    }
}