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

import kd.bos.common.enums.EnableEnum;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.ExtendedDataEntity;
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.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
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.utils.QueryFieldBuilder;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
import nckd.jxccl.hr.psms.business.ManagerAllowanceService;
import nckd.jxccl.hr.psms.common.PositionStructureConstant;
import nckd.jxccl.hr.psms.helper.PositionFileHelper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;

/**
* 年度调整【置回未生效】OP
* @author W.Y.C
* @date 2025/10/14 20:47
* @version 1.0
*/
public class AnnualSetinActiveOpPlugin extends AbstractOperationServicePlugIn implements Plugin {

    /** 需要生效的数据（key：id，value：生效日期）*/
    private Map<Long,Integer> idMaps = new HashMap<>();
    private StringJoiner message = new StringJoiner(StrFormatter.LINE_SEPARATOR);
    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        e.getFieldKeys().add(FormConstant.NCKD_PERSON);
        e.getFieldKeys().add(PositionStructureConstant.NCKD_LASTPERSONPOSFILE);
        e.getFieldKeys().add(PositionStructureConstant.NCKD_TYPESTATE);
        e.getFieldKeys().add(PositionStructureConstant.NCKD_ADJUSSTATUS);
        e.getFieldKeys().add(PositionStructureConstant.NCKD_LOCKSTATUS);
    }

    @Override
    public void onAddValidators(AddValidatorsEventArgs e){
        e.addValidator(new AbstractValidator() {
            @Override
            public void validate() {
                for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                    DynamicObject data = rowDataEntity.getDataEntity();
                    long id = data.getLong(FormConstant.ID_KEY);
                    String typeState = data.getString(PositionStructureConstant.NCKD_TYPESTATE);
                    String adjustStatus = data.getString(PositionStructureConstant.NCKD_ADJUSSTATUS);
                    DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
                    TypeStateEnum typeStateEnum = TypeStateEnum.getByCode(typeState);
                    List<Long> personIds = new ArrayList<Long>();

                    //校验是否是“年度调整”
                    if(TypeStateEnum.ANNUAL_ADJUSTMENT.getCode().equalsIgnoreCase(typeState)){
                        if (EnableEnum.YES.getCode().equals(adjustStatus)) {
                            //只有已生效的才需要置回未生效
                            personIds.add(person.getLong(FormConstant.ID_KEY));
                            idMaps.put(id,rowDataEntity.getDataEntityIndex());
                        }else{
                            message.add(StrFormatter.format("【{}】的年度调整已是“未生效”状态，忽略此条处理。", person.getString("name")));
                        }
                    }else{
                        //其他类型不能置回未生效
                        addFatalErrorMessage(rowDataEntity, StrFormatter.format("【{}】不能置回未生效，只有年度调整才能操作", typeStateEnum.getName()));
                    }
                }
                if(!idMaps.isEmpty()){
                    //校验是否已被使用
                    QFilter qFilter = new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
                            .and(new QFilter(String.join(".", PositionStructureConstant.NCKD_LASTPERSONPOSFILE, FormConstant.ID_KEY), QCP.in, idMaps.keySet()));
                    QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                            .add(PositionStructureConstant.ID_KEY)
                            .addGroup(new String[]{FormConstant.NCKD_PERSON}, FormConstant.NAME_KEY)
                            .add(PositionStructureConstant.NCKD_EXECUTEYEAR)
                            .add(PositionStructureConstant.NCKD_TYPESTATE);
                    DynamicObjectCollection query = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
                    if(!query.isEmpty()){
                        for (DynamicObject dynamicObject : query) {
                            long id = dynamicObject.getLong(FormConstant.ID_KEY);
                            String executeYear = dynamicObject.getString(PositionStructureConstant.NCKD_EXECUTEYEAR);
                            String typeState = dynamicObject.getString(PositionStructureConstant.NCKD_TYPESTATE);
                            TypeStateEnum typeStateEnum = TypeStateEnum.getByCode(typeState);
                            String personName = dynamicObject.getString(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NAME_KEY));
                            addFatalErrorMessage(getDataEntities()[idMaps.get(id)], StrFormatter.format("【{}】的档案已被【{}】年度的“{}”档案使用，不能置回未生效。",personName, executeYear,typeStateEnum.getName()));
                        }
                    }
                }

                //所有情况校验完再校验是否被锁定，比较友好。不然先校验锁等用户解锁之后又发现其他情况而不能继续处理
                if(this.getValidateResult().isSuccess()) {
                    for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                        DynamicObject data = rowDataEntity.getDataEntity();
                        String typeState = data.getString(PositionStructureConstant.NCKD_TYPESTATE);
                        TypeStateEnum typeStateEnum = TypeStateEnum.getByCode(typeState);
                        DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
                        //校验是否已被“锁定”
                        boolean lockStatus = data.getBoolean(PositionStructureConstant.NCKD_LOCKSTATUS);
                        if (lockStatus) {
                            addFatalErrorMessage(rowDataEntity, StrFormatter.format("【{}】的{}已“锁定”，不能生效。请先“解锁”。", person.getString(FormConstant.NAME_KEY), typeStateEnum.getName()));
                        }
                    }
                }
            }
        });
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PositionStructureConstant.NCKD_PERSON)
                .add(PositionStructureConstant.NCKD_BEGINDATE)
                .add(PositionStructureConstant.NCKD_ADJUSSTATUS)
                .add(PositionStructureConstant.NCKD_DEP)
                .add(PositionStructureConstant.NCKD_JOBLEVELHR)
                .add(PositionStructureConstant.NCKD_JOBSEQHR)
                .add(PositionStructureConstant.NCKD_PROTITLELEVEL)
                .addGroup(new String[]{FormConstant.NCKD_PERSON},FormConstant.ID_KEY);
        //本次需要生效的id
        Set<Long> ids = idMaps.keySet();
        DynamicObject[] load = BusinessDataServiceHelper.load(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{QFilterCommonHelper.getIdInFilter(ids)});
        List<Long> personIds = new ArrayList<>();
        for (DynamicObject dynamicObject : load) {
            long id = dynamicObject.getLong(FormConstant.ID_KEY);
            dynamicObject.set(PositionStructureConstant.NCKD_BEGINDATE, null);
            dynamicObject.set(PositionStructureConstant.NCKD_ADJUSSTATUS, EnableEnum.NO.getCode());
            personIds.add(dynamicObject.getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY));
        }
        SaveServiceHelper.update(load);
        if(message.length() > 0){
            if (this.getOperationResult().getCustomData() == null) {
                this.getOperationResult().setCustomData(new HashMap<>());
            }
            this.getOperationResult().getCustomData().put("message", message.toString());
        }

        //将人员所有职位档案标记为非最新
        PositionFileHelper.markAsNotCurrentNewest(personIds.toArray(new Long[0]));
        //将当前人员最新档案（初定 或者 （年度调整 并且 已生效） 或者 (动态调整) 生效时间为最新的那一条）标记为最新的
        PositionFileHelper.markAsCurrentNewest(null,personIds.toArray(new Long[0]));
        //职位津贴
        ManagerAllowanceService.expireMgrPostAllow(Arrays.asList(load));
    }
}