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

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.metadata.dynamicobject.DynamicObjectType;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.interaction.InteractionConfirmResult;
import kd.bos.entity.operate.interaction.InteractionContext;
import kd.bos.entity.operate.interaction.KDInteractionException;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperateErrorInfo;
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.BeforeOperationArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.entity.validate.BillStatus;
import kd.bos.entity.validate.ErrorLevel;
import kd.bos.form.MessageBoxResult;
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.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.exception.ValidationException;
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.common.PositionStructureConstant;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.StringJoiner;

/**
* 年度调整锁定解锁
* @author W.Y.C
* @date 2025/10/16 9:36
* @version 1.0
*/
public class AnnualLockOrUnLockedOpPlugin extends AbstractOperationServicePlugIn implements Plugin {

    private final static String INTERACTION_SPONORE = AnnualLockOrUnLockedOpPlugin.class.getName();
    private final static String INTERACTION_SPONORE1 = AnnualLockOrUnLockedOpPlugin.class.getName() + "#1";

    private List<Long> ids;

    StringJoiner pendingMsgJoiner = new StringJoiner(StrFormatter.LINE_SEPARATOR);

    private List<String> pendingPerson = new ArrayList<>();

    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){
        ids = new ArrayList<>();
        e.addValidator(new AbstractValidator() {
            @Override
            public void validate() {
                String operateKey = this.getOperateKey();
                //islocked：锁定
                //unlocked：解锁
                for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
                    DynamicObject data = rowDataEntity.getDataEntity();
                    long id = data.getLong(FormConstant.ID_KEY);
                    String adjustStatus = data.getString(PositionStructureConstant.NCKD_ADJUSSTATUS);
                    boolean lockStatus = data.getBoolean(PositionStructureConstant.NCKD_LOCKSTATUS);
                    DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
                    String personName = person.getString(FormConstant.NAME_KEY);
                    if(PositionStructureConstant.ISLOCKED_OP.equals(operateKey)) {
                        if(!lockStatus) {
                            if (!EnableEnum.YES.getCode().equals(adjustStatus)) {
                                //锁定的数据不是“未生效”状态
                                pendingPerson.add(personName);
                            }
                            ids.add(id);
                        }else{
                            message.add(StrFormatter.format("【{}】的年度调整已是“锁定”状态，忽略此条处理。", person.getString("name")));
                        }
                    } else if(PositionStructureConstant.UNLOCKED_OP.equals(operateKey)) {
                        if(!lockStatus) {
                            message.add(StrFormatter.format("【{}】的年度调整已是“解锁”状态，忽略此条处理。", person.getString("name")));
                        }else{
                            ids.add(id);
                        }
                    }
                }
            }
        });
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        String operateKey = e.getOperationKey();

        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                .add(FormConstant.ID_KEY)
                .add(PositionStructureConstant.NCKD_DEP)
                .add(PositionStructureConstant.NCKD_LOCKSTATUS)
                .add(PositionStructureConstant.KEY_NCKD_LOCKUSER)
                .add(PositionStructureConstant.NCKD_LOCKDATETIME);
        DynamicObject[] load = BusinessDataServiceHelper.load(PositionStructureConstant.PERSONPOSFILE_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{QFilterCommonHelper.getIdInFilter(ids)});
        boolean isProcessFlag = true;
        if(PositionStructureConstant.ISLOCKED_OP.equals(operateKey)) {
            for (DynamicObject dynamicObject : load) {
                long id = dynamicObject.getLong(FormConstant.ID_KEY);
                dynamicObject.set(PositionStructureConstant.NCKD_LOCKSTATUS, EnableEnum.YES.getCode());
                dynamicObject.set(PositionStructureConstant.KEY_NCKD_LOCKUSER, RequestContext.get().getCurrUserId());
                dynamicObject.set(PositionStructureConstant.NCKD_LOCKDATETIME, new Date());
            }
            SaveServiceHelper.update(load);
        }else {
            if(load != null && load.length >0) {
                //操作原因
                String reason = this.getOption().getVariableValue("reason", "");
                //发起解锁单据流程
                DynamicObject billObj = BusinessDataServiceHelper.newDynamicObject(PositionStructureConstant.POSFILEUNLOCK_ENTITYID);
                billObj.set(FormConstant.CREATOR_KEY, UserServiceHelper.getCurrentUserId());
                billObj.set(FormConstant.CREATE_TIME_KEY, System.currentTimeMillis());
                billObj.set(FormConstant.BILL_STATUS_KEY, BillStatus.A.toString());
                DynamicObject org = BusinessDataServiceHelper.newDynamicObject(FormConstant.ADMINORG_ENTITYID);
                org.set(FormConstant.ID_KEY, UserServiceHelper.getUserMainOrgId(UserServiceHelper.getCurrentUserId()));
                billObj.set(FormConstant.ORG_KEY, org);
                billObj.set(PositionStructureConstant.NCKD_REASON, reason);

                DynamicObjectCollection entryColl = billObj.getDynamicObjectCollection(PositionStructureConstant.NCKD_POSFILEUNLOCKENTRY);
                DynamicObjectType entryType = entryColl.getDynamicObjectType();
                for (DynamicObject dynamicObject : load) {
                    DynamicObject entryObj = new DynamicObject(entryType);
                    entryObj.set(PositionStructureConstant.NCKD_PERSONPOSFILE, dynamicObject);
                    entryObj.set(PositionStructureConstant.NCKD_ORG, dynamicObject.getDynamicObject(FormConstant.NCKD_DEP).getDynamicObject(FormConstant.BELONGCOMPANY_KEY));
                    entryColl.add(entryObj);
                }
                //提交单据
                OperateOption option = OperateOption.create();
                OperationResult result = OperationServiceHelper.executeOperate(
                        "submit",
                        PositionStructureConstant.POSFILEUNLOCK_ENTITYID,
                        new DynamicObject[]{billObj},
                        option
                );
                if (!result.isSuccess()) {
                    StringJoiner joiner = new StringJoiner(StrFormatter.LINE_SEPARATOR);
                    for (IOperateInfo iOperateInfo : result.getAllErrorOrValidateInfo()) {
                        joiner.add(iOperateInfo.getMessage());
                    }
                    throw new ValidationException(StrFormatter.format("提交解锁申请单失败，原因：{}", joiner.toString()));

                } else {
                    if (this.getOperationResult().getCustomData() == null) {
                        this.getOperationResult().setCustomData(new HashMap<>());
                    }
                    this.getOperationResult().getCustomData().put("bill", "true");
                }
            }
        }


        if(message.length() > 0) {
            if (this.getOperationResult().getCustomData() == null) {
                this.getOperationResult().setCustomData(new HashMap<>());
            }
            this.getOperationResult().getCustomData().put("message", message.toString());
        }
    }

    @Override
    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
        String operationKey = e.getOperationKey();
        if(PositionStructureConstant.ISLOCKED_OP.equals(operationKey)) {
            if (!pendingPerson.isEmpty()) {
                e.cancel = !this.showInteractionMessage();
            }
        }else if(PositionStructureConstant.UNLOCKED_OP.equals(operationKey)){
            //从流程启动条件判断非集团本部的不需要审批
            //校验选中的档案是否已经有申请单据
            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                    .addGroup(new String[]{PositionStructureConstant.NCKD_POSFILEUNLOCKENTRY, PositionStructureConstant.NCKD_PERSONPOSFILE,FormConstant.NCKD_PERSON},
                            FormConstant.NAME_KEY);
            QFilter filter = new QFilter(FormConstant.BILL_STATUS_KEY, QCP.not_equals, BillStatus.C.toString())
                    .and(new QFilter(String.join(".", PositionStructureConstant.NCKD_POSFILEUNLOCKENTRY, PositionStructureConstant.NCKD_PERSONPOSFILE, FormConstant.ID_KEY), QCP.in, ids));
            DynamicObjectCollection query = QueryServiceHelper.query(PositionStructureConstant.POSFILEUNLOCK_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
            if(!query.isEmpty()){
                List<String> personNames = new ArrayList<>(query.size());
                for (DynamicObject dynamicObject : query) {
                    String personName = dynamicObject.getString(String.join(".", PositionStructureConstant.NCKD_POSFILEUNLOCKENTRY, PositionStructureConstant.NCKD_PERSONPOSFILE, FormConstant.NCKD_PERSON, FormConstant.NAME_KEY));
                    personNames.add(personName);
                }
                throw new ValidationException(StrFormatter.format("人员【{}】的职位档案已存在待解锁的申请，请勿重复申请。", String.join(",", personNames)));
            }else{
                e.cancel = !this.unlockNeedApprovalInteractionMessage();
            }
        }

    }


    private boolean showInteractionMessage() {
        //交互式操作提示
        // 检查是否为回调：避免死循环
        String confirmResultString = this.getOption().getVariableValue(OperateOptionConst.INTERACTIONCONFIRMRESULT, "");
        InteractionConfirmResult confirmResult = InteractionConfirmResult.fromJsonString(confirmResultString);
        if (confirmResult.getResults().containsKey(INTERACTION_SPONORE)) {
            // 已是回调，直接返回结果
            MessageBoxResult result = MessageBoxResult.valueOf(confirmResult.getResults().get(INTERACTION_SPONORE));
            return result == MessageBoxResult.Yes;
        }

        // 首次执行：抛出交互异常
        InteractionContext interactionContext = new InteractionContext();
        interactionContext.setSimpleMessage("存在“未生效的”档案");
        OperateErrorInfo errorInfo = new OperateErrorInfo();
        errorInfo.setMessage(StrFormatter.format("人员【{}】的档案还“未生效”，锁定后无法后续操作", String.join("，", pendingPerson)));
        errorInfo.setLevel(ErrorLevel.Warning);
        interactionContext.addOperateInfo(errorInfo);
        throw new KDInteractionException(INTERACTION_SPONORE, interactionContext);
    }

    private boolean unlockNeedApprovalInteractionMessage() {
        //交互式操作提示
        // 检查是否为回调：避免死循环
        String confirmResultString = this.getOption().getVariableValue(OperateOptionConst.INTERACTIONCONFIRMRESULT, "");
        InteractionConfirmResult confirmResult = InteractionConfirmResult.fromJsonString(confirmResultString);
        if (confirmResult.getResults().containsKey(INTERACTION_SPONORE1)) {
            // 已是回调，直接返回结果
            MessageBoxResult result = MessageBoxResult.valueOf(confirmResult.getResults().get(INTERACTION_SPONORE1));
            return result == MessageBoxResult.Yes;
        }

        // 首次执行：抛出交互异常
        InteractionContext interactionContext = new InteractionContext();
        interactionContext.setSimpleMessage("存在“未生效的”档案");
        OperateErrorInfo errorInfo = new OperateErrorInfo();
        errorInfo.setMessage("非总部解锁需要经过总部审批，审批通过之后自动解锁；点击“是”系统自动发起解锁审批流程");
        errorInfo.setLevel(ErrorLevel.Warning);
        interactionContext.addOperateInfo(errorInfo);
        throw new KDInteractionException(INTERACTION_SPONORE1, interactionContext);
    }

}