package yem.base.common.module.meta.propselect.dynamic;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.dataentity.metadata.IMetadata;
import kd.bos.entity.*;
import kd.bos.entity.property.BasedataProp;
import kd.bos.entity.property.EntryProp;
import kd.bos.entity.property.LinkEntryProp;
import kd.bos.entity.tree.TreeNode;
import kd.bos.form.ClientProperties;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IFormView;
import kd.bos.form.control.Control;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.control.Search;
import kd.bos.form.control.TreeView;
import kd.bos.form.control.events.SearchEnterEvent;
import kd.bos.form.control.events.SearchEnterListener;
import kd.bos.form.control.events.TreeNodeClickListener;
import kd.bos.form.control.events.TreeNodeEvent;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.util.StringUtils;
import yem.base.common.utils.YEM;

import java.util.*;

/**
 * 字段选择器-表单插件
 *
 * @author longh
 * @description: 用于批量选择单据实体字段值
 * @date 2022年6月27日 下午4:29:21
 */
public class MetaPropertyEdit extends AbstractFormPlugin implements TreeNodeClickListener, SearchEnterListener {
    private static final List<String> noPropNames = new ArrayList<>();

    static {
        noPropNames.add("LongProp");
        noPropNames.add("LinkEntryProp");
        noPropNames.add("DynamicLocaleProperty");
    }

    @Override
    public void afterCreateNewData(EventObject e) {
        super.afterCreateNewData(e);
        IFormView view = this.getView();
        FormShowParameter fsp = view.getFormShowParameter();
        String entityKey = fsp.getCustomParam("entityKey");
        boolean isMulti = fsp.getCustomParam("isMulti") == null ? false : fsp.getCustomParam("isMulti");
        boolean alone = fsp.getCustomParam("alone") == null ? false : fsp.getCustomParam("alone");
        Collection<String> showKeys = fsp.getCustomParam("showKeys");
        if (StringUtils.isEmpty(entityKey)) {
            entityKey = "pm_purorderbill";//用于预览展示
        }
        if (entityKey != null) {
            MainEntityType entityType = EntityMetadataCache.getDataEntityType(entityKey);
            DynamicObjectCollection entryEntity = this.getModel().getDataEntity(true).getDynamicObjectCollection("yem_entryentity");
            entryEntity.clear();
            TreeView tree = view.getControl("yem_treeviewap");
            this.initMetaData(tree, entryEntity, entityType, alone, showKeys);
        }
        Map<String, Object> param = new HashMap<>();
        param.put(ClientProperties.IsMultiSelect, isMulti);
        view.updateControlMetadata("yem_entryentity", param);
    }

    private void initMetaData(TreeView tree, DynamicObjectCollection entryEntity, IDataEntityType entityType, boolean alone, Collection<String> showKeys) {
        boolean isInit = false;
        String entityKey = entityType.getName();
        if (!alone || (alone && showKeys.contains(entityKey))) {
            isInit = true;
        }
        if (tree != null) {
            TreeNode node = new TreeNode("", entityKey, getDisplayName(entityType));
            node.setIsOpened(true);
            if (entityType instanceof BillEntityType) {
                if (isInit) {
                    node.addChild(new TreeNode(entityKey, "head", "单据头"));
                }
                tree.addNode(node);
            } else if (isInit && entityType instanceof EntryType) {
                node.setParentid(entityType.getParent().getName());
                tree.addNode(node);
            }
        }
        List<IDataEntityType> entryTypes = new ArrayList<>();
        for (IDataEntityProperty property : entityType.getProperties()) {
            String number = property.getName();
            String classSimpleName = property.getClass().getSimpleName();
            if (property instanceof EntryProp && !(property instanceof LinkEntryProp)) {
                entryTypes.add(((EntryProp) property).getItemType());
            } else if (isInit && (!noPropNames.contains(classSimpleName) || "id".equals(number))) {
                DynamicObject row = entryEntity.addNew();
                String displayName = property.getDisplayName() != null ? getDisplayName(property) : "id".equals(number) ? "ID" : "";
                String fullnumber = number;
                String fullname = displayName;
                IDataEntityType parent = property.getParent();
                if (parent instanceof SubEntryType) {
                    IDataEntityType grandParent = parent.getParent();
                    fullnumber = grandParent.getName() + "." + parent.getName() + "." + fullnumber;
                    fullname = getDisplayName(grandParent) + "." + getDisplayName(parent) + "." + fullname;
                } else if (parent instanceof EntryType) {
                    fullnumber = parent.getName() + "." + fullnumber;
                    fullname = getDisplayName(parent) + "." + fullname;
                }
                row.set("yem_number", number);
                row.set("yem_fullnumber", fullnumber);
                row.set("yem_name", displayName);
                row.set("yem_fullname", fullname);
                row.set("yem_datatype", classSimpleName);
                if (property instanceof BasedataProp) {
                    BasedataProp basedataProp = (BasedataProp) property;
                    String baseEntityId = basedataProp.getBaseEntityId();
                    String baseEntityName = getDisplayName(basedataProp.getComplexType());
                    String baseEntity = String.format("%s（%s）", baseEntityName, baseEntityId);
                    row.set("yem_basedatakey", baseEntity);
                    row.set("yem_basedataname", baseEntityName);
                    row.set("yem_basedataid", baseEntityId);
                }
            }
        }
        for (IDataEntityType entryType : entryTypes) {
            initMetaData(tree, entryEntity, entryType, alone, showKeys);
        }
    }

    private String getDisplayName(IMetadata iMetadata) {
        return iMetadata.getDisplayName() != null ? iMetadata.getDisplayName().getLocaleValue() : "";
    }

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addClickListeners("btnok");
        TreeView treeView = this.getControl("yem_treeviewap");
        treeView.addTreeNodeClickListener(this);
        Search searchap = this.getControl("yem_searchap");
        searchap.addEnterListener(this);
    }

    @Override
    public void treeNodeClick(TreeNodeEvent e) {
        String nodeId = e.getNodeId().toString();
        IFormView view = this.getView();
        FormShowParameter fsp = view.getFormShowParameter();
        String entityKey = fsp.getCustomParam("entityKey");
        boolean alone = fsp.getCustomParam("alone") == null ? false : fsp.getCustomParam("alone");
        Collection<String> showKeys = fsp.getCustomParam("showKeys") == null ? Collections.emptyList() : fsp.getCustomParam("showKeys");
        if (StringUtils.isEmpty(entityKey)) {
            entityKey = "pm_purorderbill";//用于预览展示
        }
        MainEntityType entityType = EntityMetadataCache.getDataEntityType(entityKey);
        DynamicObjectCollection entryEntity = this.getModel().getDataEntity(true).getDynamicObjectCollection("yem_entryentity");
        entryEntity.clear();
        List<String> showList = new ArrayList<>();
        if (nodeId.equals(entityKey) && !alone) {
            this.initMetaData(null, entryEntity, entityType, false, showList);
        } else {
            if (nodeId.equals(entityKey) && alone) {
                showList.addAll(showKeys);
            } else if (nodeId.equals("head")) {
                showList.add(entityKey);
            } else {
                showList.add(nodeId);
            }
            this.initMetaData(null, entryEntity, entityType, true, showList);
        }
        view.updateView("yem_entryentity");
    }

    @Override
    public void search(SearchEnterEvent e) {
        String text = e.getText();
        IFormView view = this.getView();
        view.updateView("yem_entryentity");
        DynamicObjectCollection entryEntity = this.getModel().getEntryEntity("yem_entryentity");
        EntryGrid grid = view.getControl("yem_entryentity");
        if (YEM.isNotEmpty(text)) {
            List<Integer> indexs = new ArrayList<>();
            for (int rowIndex = 0; rowIndex < entryEntity.size(); ++rowIndex) {
                DynamicObject o = entryEntity.get(rowIndex);
                if (o.getString("yem_number").contains(text) || o.getString("yem_name").contains(text)) {
                    indexs.add(rowIndex);
                }
            }
            if (indexs.isEmpty()) {
                view.showTipNotification("未找到符合条件的数据。");
            } else {
                int[] rowIndexes = indexs.stream().mapToInt(Integer::valueOf).toArray();
                grid.setRowBackcolor("#eff3fd", rowIndexes);
                grid.focusCell(rowIndexes[0], "yem_number");
            }
        }
    }

    @Override
    public void click(EventObject evt) {
        super.click(evt);
        String key = ((Control) evt.getSource()).getKey();
        if ("btnok".equals(key)) {
            IFormView view = this.getView();
            EntryGrid entry = view.getControl("yem_entryentity");
            int[] selectRowIndexs = entry.getSelectRows();
            if (selectRowIndexs.length > 0) {
                DynamicObjectCollection selectRows = new DynamicObjectCollection();
                for (int i : selectRowIndexs) {
                    selectRows.add(this.getModel().getEntryRowEntity("yem_entryentity", i));
                }
                view.returnDataToParent(selectRows);
                view.close();
            } else {
                view.showTipNotification("未选择数据。");
            }
        }
    }

}
