package nckd.jxccl.swc.mas.plugin.operate.structappr.change;

import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.dataentity.utils.ObjectUtils;
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.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
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.StrFormatter;

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

/**
 * 薪酬标准变更操作插件抽象基类
 *
 * @author W.Y.C
 * @date 2025/12/03
 */
public abstract class AbstractSalaryStdChgOpPlugin extends AbstractOperationServicePlugIn implements Plugin {

    /**
     * 获取实体ID
     * @return 实体ID
     */
    protected abstract String getEntityId();

    /**
     * 获取实体ID
     * @return 实体ID
     */
    protected abstract String getEntityName();

    /**
     * 处理更新前的额外逻辑
     * @param dataEntity 数据实体
     * @param updateEntity 更新实体
     */
    protected abstract void processBeforeUpdate(DynamicObject dataEntity, DynamicObject updateEntity);

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

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        List<Long> entityIdList = new ArrayList<>();
        for (DynamicObject dataEntity : e.getDataEntities()) {
            long entityId = dataEntity.getLong(String.join(".", getEntityId(), FormConstant.ID_KEY));
            entityIdList.add(entityId);
        }
        
        MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(getEntityId());
        DynamicObject[] load = BusinessDataServiceHelper.load(entityIdList.toArray(new Long[0]), dataEntityType);
        
        // 按ID分组
        Map<Long, DynamicObject> groupedById = Arrays.stream(load)
                .collect(Collectors.toMap(
                        obj -> obj.getLong(FormConstant.ID_KEY),
                        obj -> obj
                ));
                
        for (DynamicObject dataEntity : e.getDataEntities()) {
            long entityId = dataEntity.getLong(String.join(".", getEntityId(), FormConstant.ID_KEY));
            DynamicObjectCollection entryColl = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);

            DynamicObject updateEntity = groupedById.get(entityId);
            DynamicObjectCollection updateEntryColl = updateEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);

            for (DynamicObject entry : entryColl) {
                long originId = entry.getLong("nckd_originid");
                for (DynamicObject updateEntry : updateEntryColl) {
                    long id = updateEntry.getLong(FormConstant.ID_KEY);
                    if (originId == id) {
                        DataEntityPropertyCollection properties = entry.getDynamicObjectType().getProperties();
                        for (IDataEntityProperty property : properties) {
                            String name = property.getName();
                            if (name.contains("nckd_") && !name.contains("nckd_originid")) {
                                updateEntry.set(name, entry.get(name));
                            }
                        }
                        break;
                    }
                }
            }
            
            // 处理更新前的额外逻辑
            processBeforeUpdate(dataEntity, updateEntity);
        }

        // 执行取消提交操作
       /* OperationResult unsubmitResult = OperationServiceHelper.executeOperate("unsubmit", getEntityId(), load,OperateOption.create());
        if (unsubmitResult.isSuccess()) {*/
            OperateOption option = OperateOption.create();
            //修改和删除不校验是否是暂存状态（只能修改暂存的数据。只能删除暂存的数据。）
            option.setVariableValue("forceNoAudit","true");
            // 执行保存操作
            OperationResult saveResult = SaveServiceHelper.saveOperate(getEntityId(), load, option);
            if (saveResult != null && !saveResult.isSuccess()) {
                StringJoiner errorMsg = new StringJoiner("；");
                for (IOperateInfo error : saveResult.getAllErrorOrValidateInfo()) {
                    errorMsg.add(error.getMessage());
                }
                if (!ObjectUtils.isEmpty(saveResult.getMessage())) {
                    errorMsg.add(saveResult.getMessage());
                }
                throw new ValidationException(StrFormatter.format("回写【{}】失败，原因：{}",getEntityName(),errorMsg.toString()));
            }

        /*} else {
            throw new ValidationException(StrFormatter.format("回写【{}】失败，原因：{}",getEntityName(),unsubmitResult.getMessage()));
        }*/
    }
}