package yem.base.common.module.version.dynamic;

import com.alibaba.fastjson.JSONObject;
import kd.bos.bill.OperationStatus;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.serialization.SerializationUtils;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IFormView;
import kd.bos.form.IPageCache;
import kd.bos.form.ShowType;
import kd.bos.form.control.Control;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.control.events.RowClickEvent;
import kd.bos.form.control.events.RowClickEventListener;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;

import java.util.EventObject;

/**
 * 变更履历-表单插件
 * yem_wm_versionresume
 * @description:
 * @author longh
 * @date 2022年1月18日 下午4:32:33
 */
public class VersionResumeEdit extends AbstractFormPlugin implements RowClickEventListener {
	private static final String KEY_INFORM = "yem_base_vresumebill";//【变更履历_单据详情】单据标识

	@Override
	public void afterCreateNewData(EventObject evt) {
		super.afterCreateNewData(evt);
		this.initData();
	}

/**
 * 初始化数据方法，用于加载并设置相关业务数据到模型和页面缓存中。
 * 该方法从视图中获取展示参数，根据参数加载源单据和变更单据信息，并将这些信息填充到数据模型中。
 * 同时，将变更单据的详细信息序列化为JSON字符串，存储在页面缓存中，以供后续使用。
 */
private void initData() {
    // 获取当前模型、视图和页面缓存实例
    IDataModel model = this.getModel();
    IFormView view = this.getView();
    IPageCache pageCache = this.getPageCache();

    // 创建一个空的自定义参数对象
    JSONObject customParams = new JSONObject();

    // 从视图中获取表单展示参数
    FormShowParameter showParameter = view.getFormShowParameter();

    // 从展示参数中获取“data”部分的自定义参数
    JSONObject data = showParameter.getCustomParam("data");
    // 如果“data”部分不存在，则直接返回，不进行后续处理
    if(data == null) {
        return;
    }

    // 从data对象中提取所需字段值
//    Long tplPkId = data.getLong("tplPkId");
    String yem_requirebill = data.getString("yem_requirebill");
    String yem_changebill = data.getString("yem_changebill");
    Long pkId = data.getLong("pkId");

    // 根据pkId和yem_requirebill加载源单据，并将单据编号设置到模型中
    DynamicObject srcBill = BusinessDataServiceHelper.loadSingle(pkId, yem_requirebill);
    model.setValue("yem_srcbillno", srcBill.getString("billno"));

    // 清除模型中“yem_entryentity”条目的数据
    model.deleteEntryData("yem_entryentity");

    // 根据yem_changebill和过滤条件加载变更单据列表，并遍历列表
    DynamicObject[] bills = BusinessDataServiceHelper.load(yem_changebill, "id,billno,yem_version,yem_changeman,yem_changedate,yem_effectdate",
            new QFilter[] {new QFilter("yem_masterid", QCP.equals, pkId)}, "yem_version desc");
    for (DynamicObject bill : bills) {
        // 在模型中创建一个新的条目行
        int index = model.createNewEntryRow("yem_entryentity");
        // 从变更单据中提取版本号等字段值，并设置到模型的对应条目行中
        int yem_version = bill.getInt("yem_version");
        Object pkValue = bill.getPkValue();
        model.setValue("yem_version", yem_version, index);
        model.setValue("yem_billno", bill.get("billno"), index);
        model.setValue("yem_changeman", bill.get("yem_changeman"), index);
        model.setValue("yem_changedate", bill.get("yem_changedate"), index);
        model.setValue("yem_effectdate", bill.get("yem_effectdate"), index);
        model.setValue("yem_pkid", pkValue, index);

        // 如果当前条目是第一个，则将pkValue设置到自定义参数对象中
        if(index == 0) {
            customParams.put("pkid", pkValue);
        }
    }
    // 设置变更单据的总数（即条目的数量减1）到模型中
    model.setValue("yem_changenumber", bills.length - 1);

    // 创建一个数组，用于存储变更单据的id值
    Object[] pkArray = new Object[bills.length];
    for (int i = 0; i < bills.length; i++) {
        pkArray[i] = bills[i].get("id");
    }

    // 根据yem_changebill的值获取对应的实体类型，并根据pkArray加载变更单据的详细信息
    MainEntityType type = EntityMetadataCache.getDataEntityType(yem_changebill);
    DynamicObject[] billDetails = BusinessDataServiceHelper.load(pkArray, type);
    // 将变更单据的详细信息序列化为JSON字符串，并存储到页面缓存中
    String billsJson = SerializationUtils.toJsonString(billDetails);
    pageCache.put("billsJson", billsJson);

    // 将JSON字符串和变更单据编号添加到自定义参数对象中
    customParams.put("billsJson", billsJson);
    customParams.put("yem_changebill", yem_changebill);

    // 使用视图和自定义参数对象显示表单
    this.showForm(view, customParams);
}


	/**
	 * 显示表单的辅助方法。
	 * 该方法用于在给定的视图中显示一个表单，表单的数据和行为根据传入的参数定制。
	 *
	 * @param view 表单将要显示在其中的视图接口。通过这个接口，方法能够指示视图如何显示表单。
	 * @param customParams 表单的自定义参数。这些参数可以用来初始化表单的状态或填充表单的数据。
	 */
	private void showForm(IFormView view, JSONObject customParams) {
	    // 创建表单显示参数对象，用于配置表单的显示方式和状态。
	    FormShowParameter showForm = new FormShowParameter();

	    // 设置表单的自定义参数，这些参数可以是任何与表单展示相关的数据。
	    showForm.setCustomParam("data", customParams);

	    // 设置表单的状态为编辑状态，这意味着表单将允许用户修改数据。
	    showForm.setStatus(OperationStatus.EDIT);

	    // 配置表单的打开方式，这里设置为在容器内打开。
	    showForm.getOpenStyle().setShowType(ShowType.InContainer);

	    // 设置表单的目标键，这个键可以用于关联表单和特定的容器或操作。
	    showForm.getOpenStyle().setTargetKey("yem_billinfotab");

	    // 设置表单的ID，这个ID可以用于唯一标识表单，也可以用于在系统中检索表单的定义。
	    showForm.setFormId(KEY_INFORM);

	    // 在给定的视图中显示表单，视图根据配置的参数来呈现表单。
	    view.showForm(showForm);
	}
	
/**
 * 注册事件监听器。
 * 本方法在父类注册监听器的基础上，进一步为特定的界面组件添加了行点击监听。
 * @param e 事件对象，用于注册监听器。
 */
@Override
public void registerListener(EventObject e) {
	// 调用父类方法注册事件监听器
	super.registerListener(e);
	// 获取当前视图
	IFormView view = this.getView();
	// 为视图中的EntryGrid组件添加行点击监听
	((EntryGrid) view.getControl("yem_entryentity")).addRowClickListener(this);
}
	
	/**
	 * 处理行点击事件。
	 * 当用户点击表格中的行时，此方法被调用。它首先调用超类的方法来处理基本的行点击行为，
	 * 然后根据当前行的数据和一些预定义的参数来构建并显示一个表单。
	 *
	 * @param evt 行点击事件的对象，包含有关点击事件的详细信息。
	 */
	@Override
	public void entryRowClick(RowClickEvent evt) {
	    // 调用超类方法处理行点击事件
	    RowClickEventListener.super.entryRowClick(evt);

	    // 获取当前的数据模型，用于后续获取特定字段的值
	    IDataModel model = this.getModel();
	    // 获取当前的视图对象，用于后续获取表单展示参数和显示表单
	    IFormView view = this.getView();
	    // 获取页面缓存对象，用于后续获取特定的缓存数据
	    IPageCache pageCache = this.getPageCache();
	    // 从视图对象中获取表单展示参数
	    FormShowParameter showParameter = view.getFormShowParameter();
	    // 从表单展示参数中尝试获取名为"data"的自定义参数
	    JSONObject data = showParameter.getCustomParam("data");

	    // 如果"data"参数不存在，则不执行后续逻辑，直接返回
	    if(data == null) {
	        return;
	    }

	    // 创建一个JSONObject，用于存储即将传递给表单的自定义参数
	    JSONObject customParams = new JSONObject();
	    // 从页面缓存中获取名为"billsJson"的数据，并将其添加到customParams中
	    customParams.put("billsJson", pageCache.get("billsJson"));
	    // 从"data"参数中获取名为"yem_changebill"的值，并将其添加到customParams中
	    customParams.put("yem_changebill", data.getString("yem_changebill"));
	    // 从数据模型中获取名为"yem_pkid"的字段值，使用当前行作为参数，并将其添加到customParams中
	    customParams.put("pkid", model.getValue("yem_pkid", evt.getRow()));

	    // 使用当前视图和自定义参数显示表单
	    this.showForm(view, customParams);
	}
	
	@Override
	public void afterDoOperation(AfterDoOperationEventArgs evt) {
		super.afterDoOperation(evt);
		String key = evt.getOperateKey();
		switch (key) {
		case "refresh":
			this.initData();
			break;
		default:
			break;
		}
	}
	
	@Override
	public void click(EventObject evt) {
		super.click(evt);
		String key = ((Control) evt.getSource()).getKey().toLowerCase();
		switch (key) {
//		case "yem_buttonap":
//			EntryGrid entryGrid = this.getView().getControl("yem_entryentity");
//			entryGrid.selectRows(0);
//			break;
		default:
			break;
		}
	}
	
}
