package yem.wm.bd.createbasedata.operation;

import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.serialization.SerializationUtils;
import kd.bos.entity.EntityType;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.botp.CRFormula;
import kd.bos.entity.formula.BOSExpressionContext;
import kd.bos.entity.formula.CalcExprParser;
import kd.bos.entity.formula.RowDataModel;
import kd.bos.entity.function.FunctionManage;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import yem.base.common.utils.DynamicObjectUtil;
import yem.base.common.utils.YEM;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description 审核生成保险资料
 * 1、第一次点击审核生成保险资料
 * 2、第二次点击审核以及合同变更更新保险资料
 * @Author: zhangh
 * @CreateTime: 2025-02-14  18:20
 */
public class CreateInsuranceAuditOpPlugin extends AbstractOperationServicePlugIn {
    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e) {
        DynamicObject[] dataEntities = e.getDataEntities();
        for (DynamicObject dataEntity : dataEntities) {
            String name = dataEntity.getDataEntityType().getName();
            dataEntity = BusinessDataServiceHelper.loadSingleFromCache(dataEntity.getLong("id"), name);//变更方案确认之后，添加泵更更新的逻辑
            createDataBase(dataEntity, name);//生成以及跟新《保险资料》
        }
    }

    /**
     * @param dataEntity 合同实体
     * @param name       合同标识
     * @return void
     * @Description: 生成以及更新《保险资料》
     * @function 审核时生成《保险资料》以及更新《保险资料》
     * @purposes 用途
     */
    public void createDataBase(DynamicObject dataEntity, String name) {

        List<QFilter> qFilters = new ArrayList<>();

        qFilters.add(new QFilter("yem_billkey", QCP.equals, name));//《保险资料》中【单据标识】条件
        qFilters.add(new QFilter("yem_billid", QCP.equals, dataEntity.getLong("id")));

        String selectfields = DynamicObjectUtil.getSelectfields("yem_bd_insuranceinfor", false);
        DynamicObject baseData = BusinessDataServiceHelper.loadSingle("yem_bd_insuranceinfor", selectfields, qFilters.toArray(new QFilter[]{}));//根据条件查询《保险资料》

        if (baseData == null) {//如果查询到的《保险资料》为空，则创建《保险资料》实体
            baseData = BusinessDataServiceHelper.newDynamicObject("yem_bd_insuranceinfor");
        }

        qFilters.clear();
        qFilters.add(new QFilter("yem_sourceentity.number", QCP.equals, name));
        qFilters.add(new QFilter("yem_targetentity.number", QCP.equals, "yem_bd_insuranceinfor"));
        String selectfield = DynamicObjectUtil.getSelectfields("yem_bd_fieldmap", false);
        selectfield = DynamicObjectUtil.getEntrySelectfields(selectfield, "yem_bd_fieldmap", "yem_fieldcontrast_e", false);
        DynamicObject fieldmap = BusinessDataServiceHelper.loadSingle("yem_bd_fieldmap", selectfield, qFilters.toArray(new QFilter[]{}));//查询《字段映射配置》表
        if (fieldmap != null) {
            DynamicObjectCollection fieldcontrastEntry = fieldmap.getDynamicObjectCollection("yem_fieldcontrast_e");//获取《字段映射》配置中的{字段对照}
            MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(name);//获取元数据模型，主要用于读取字段类型和字段模型相关。
            for (DynamicObject entry : fieldcontrastEntry) {
                String sourcekey = entry.getString("yem_sourcekey");//获取《字段映射配置》中{字段对照}【源单标识】字段
                String math = entry.getString("yem_math");//获取《字段映射配置》中{字段对照}【计算公式】字段
                Object value = null;
                if (YEM.isNotEmpty(sourcekey)) {
                    for (EntityType type : dataEntityType.getAllEntities().values()) {
                        if (!(type instanceof MainEntityType)) continue;//判断是否属于单据头，如果是单据体则跳出循环
                        if (!type.getFields().containsKey(sourcekey)) continue;;//判断源单字段是否是单据头字段，如果不是单据头字段，则跳出本次循环
                        value = dataEntity.get(sourcekey);
                    }

                } else if (YEM.isNotEmpty(math)) {
                    CRFormula formula = SerializationUtils.fromJsonString(math, CRFormula.class);//对【计算公式】进行序列话
                    String expression = formula.getExpression();//获取计算公式的表达式
                    //RowDataModel第一个入参要传入当前的实体名，如解析单据体的数据，则传入单据体标识
                    RowDataModel rowDataModel = new RowDataModel(name, dataEntityType);
                    rowDataModel.setRowContext(dataEntity);
                    BOSExpressionContext bosExpressionContext = new BOSExpressionContext(rowDataModel);//创建表达式运行上下文对象
                    value = CalcExprParser.getExpressionValue(expression, bosExpressionContext, FunctionManage.get());//根据表达式取值
                }
                //目标字段
                String targetfieidexp = entry.getString("yem_targetkey");
                MainEntityType dataTarEntityType = MetadataServiceHelper.getDataEntityType("yem_bd_insuranceinfor");//获取元数据模型，主要用于读取字段类型和字段模型相关。
                for (EntityType entityType : dataTarEntityType.getAllEntities().values()) {
                    if (!(entityType instanceof MainEntityType)) continue;//判断是否属于单据头，如果是单据体则跳出循环
                    if (!entityType.getFields().containsKey(targetfieidexp)) continue;//判断源单字段是否是单据头字段，如果不是单据头字段，则跳出本次循环
                    baseData.set(targetfieidexp, value);
                }
            }
            OperationServiceHelper.executeOperate("save", "yem_bd_insuranceinfor", new DynamicObject[]{baseData}, OperateOption.create());
        }
    }
}
