package nckd.jxccl.swc.hsas.formplugin.web.outdata.bill;

import nckd.jxccl.base.common.utils.DateTimeUtils;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.events.GetEntityTypeEventArgs;
import kd.bos.entity.property.DateProp;
import kd.bos.entity.property.TextProp;
import kd.bos.exception.KDBizException;
import kd.bos.form.FormShowParameter;
import kd.bos.form.container.Container;
import kd.bos.form.control.Control;
import kd.bos.form.events.BeforeCreateListColumnsArgs;
import kd.bos.form.events.BeforeCreateListDataProviderArgs;
import kd.bos.form.events.OnGetControlArgs;
import kd.bos.list.BillList;
import kd.bos.list.DateListColumn;
import kd.bos.list.IListColumn;
import kd.bos.list.ListColumn;
import kd.bos.list.plugin.AbstractListPlugin;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.mvc.list.ListDataProvider;
import kd.bos.mvc.list.ListView;
import kd.bos.orm.query.QFilter;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.swc.helper.SWCHelper;
import nckd.jxccl.sit.hcsi.formplugin.web.tp.SisurTempDataEntityTypeBillList;
import nckd.jxccl.swc.hsas.business.utils.OutImportTaskUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Tyx 2025-12-10
 * 外单位导入数据列表插件
 * 根据模板配置的项目动态配置列
 * 包含构建列及provider
 */
public class OutTempDataViewBillListPlugin extends AbstractListPlugin implements Plugin {
    private static final Log logger = LogFactory.getLog(OutTempDataViewBillListPlugin.class);
    private SisurTempDataEntityTypeBillList billList;
    // 定义一个静态集合，存储常用列的key
    private static final Set<String> COMMONCOLUMNSET = new HashSet(8);

    // 静态代码块，初始化常用列集合
    static {
        COMMONCOLUMNSET.add("fseq");
        COMMONCOLUMNSET.add("nckd_importtask.name");
        COMMONCOLUMNSET.add("billstatus");
        COMMONCOLUMNSET.add("nckd_importtask.nckd_outimptpl.name");
        COMMONCOLUMNSET.add("nckd_importtask.nckd_period.number");
        COMMONCOLUMNSET.add("nckd_datastatus");
    }

    /**
     * 获取实体类型
     * @param args 获取实体类型的事件参数
     */
    public void getEntityType(GetEntityTypeEventArgs args) {
        super.getEntityType(args);
        args.setNewEntityType(this.getEntityType());
    }

    /**
     * 获取新的实体类型
     * @return 返回处理后的实体类型
     */
    private MainEntityType getEntityType() {
        MainEntityType mainType = EntityMetadataCache.getDataEntityType("nckd_outtempdata");
        MainEntityType mainEntityType = null;

        try {
            mainEntityType = (MainEntityType)mainType.clone();
        } catch (CloneNotSupportedException var4) {
            logger.error("getNewEntityType: ", var4);
            throw new KDBizException(ExceptionUtils.getFullStackTrace(var4));
        }

        if (mainEntityType == null) {
            return mainType;
        } else {
            List<Map<String, String>> columnHeadList = this.getColumnHeadList();
            this.addItemProp(mainEntityType, columnHeadList);
            return mainEntityType;
        }
    }

    /**
     * 获取控件
     * @param args 获取控件的事件参数
     */
    public void onGetControl(OnGetControlArgs args) {
        super.onGetControl(args);
        String key = args.getKey();
        Control customControl = null;
        if ("billlistap".equals(key)) {
            customControl = this.createBillList(key);
        }
        if (customControl != null) {
            args.setControl(customControl);
        }
    }


    /**
     * 构建列表
     * @param key 列表的key值
     * @return 返回构建好的BillList对象
     */
    protected BillList createBillList(String key) {
        if (this.billList != null) {
            return this.billList;
        } else {
            this.billList = new SisurTempDataEntityTypeBillList(this.getEntityType());
            this.billList.setKey(key);
            this.billList.setEntityId("nckd_outtempdata");
            ListView listView = (ListView)this.getView();
            this.billList.setBillFormId(listView.getBillFormId());
            this.billList.setView(listView);
            Container rootControl = (Container)this.getView().getRootControl();
            this.replaceBillList(rootControl.getItems(), this.billList);
            return this.billList;
        }
    }

    /**
     * 替换列表控件
     * @param items 控件列表
     * @param billList 要替换的列表控件
     */
    private void replaceBillList(List<Control> items, Control billList) {
        for(int i = 0; i < items.size(); ++i) {
            Control control = (Control)items.get(i);
            if (control.getKey().equals(billList.getKey())) {
                items.set(i, billList);
                return;
            }
            if (control instanceof Container) {
                this.replaceBillList(((Container)control).getItems(), billList);
            }
        }
    }

    /**
     * 构建列表列之前方法
     * @param args
     */
    @Override
    public void beforeCreateListColumns(BeforeCreateListColumnsArgs args) {
        List<IListColumn> columnList = args.getListColumns();
        List<IListColumn> commonColumnList = new ArrayList(10);
        Map<String, IListColumn> otherFixColumnMap = new HashMap(16);
        Iterator it = columnList.iterator();

        while(it.hasNext()) {
            IListColumn obj = (IListColumn)it.next();
            if (COMMONCOLUMNSET.contains(obj.getListFieldKey())) {
                commonColumnList.add(obj);
            } else {
                otherFixColumnMap.put(obj.getListFieldKey(), obj);
            }
        }

        columnList.clear();
        columnList.addAll(commonColumnList);
        List<Map<String, String>> columnHeadList = this.getColumnHeadList();
        if (!SWCHelper.isEmpty(columnList)) {
            int seq = columnList.size() + 1;
            String key = null;
            String itemType = null;
            it = columnHeadList.iterator();

            while(it.hasNext()) {
                Map<String, String> tempMap = (Map)it.next();
                Long dataTypeId = Long.valueOf((String)tempMap.get("datatypeid"));
                String name = (String)tempMap.get("name");
                key = (String)tempMap.get("key");
                itemType = (String)tempMap.get("itemType");
                if ("999".equals(itemType)) {
                    if (!COMMONCOLUMNSET.contains(key)) {
                        IListColumn tempColumn = (IListColumn)otherFixColumnMap.get(key);
                        if (tempColumn != null) {
                            columnList.add(tempColumn);
                            ++seq;
                        }
                    }
                } else {
                    if (1050L == dataTypeId) {
                        DateListColumn dateListColumn = new DateListColumn();
                        dateListColumn.setDisplayFormatString("yyyy-MM-dd");
                        dateListColumn.setCaption(new LocaleString(name));
                        dateListColumn.setKey(key);
                        dateListColumn.setListFieldKey(key);
                        dateListColumn.setSeq(seq);
                        columnList.add(dateListColumn);
                    } else {
                        ListColumn column = new ListColumn();
                        column.setCaption(new LocaleString(name));
                        column.setKey(key);
                        column.setListFieldKey(key);
                        column.setSeq(seq);
                        columnList.add(column);
                    }
                    ++seq;
                }
            }

        }
    }

    /**
     * 获取导入任务模板上的字段
     * @return
     */
    private List<Map<String, String>> getColumnHeadList() {
        List<Map<String, String>> columnHeadList = new ArrayList(10);
        Long tplId = (Long)this.getView().getFormShowParameter().getCustomParam("outimpTplId");
        FormShowParameter parameter = this.getView().getFormShowParameter();
        return (List)(tplId != null && tplId != 0L ? OutImportTaskUtils.getColumnHeadList(tplId, (Long)parameter.getCustomParam("importTaskId")) : columnHeadList);
    }

    /**
     * 添加ListDataProvider
     * @param args
     */
    @Override
    public void beforeCreateListDataProvider(BeforeCreateListDataProviderArgs args) {
        args.setListDataProvider(new OutTempDataViewBillListPlugin.ImportItemDataResultImpl());
    }

    private void addItemProp(DynamicObjectType mainEntityType, List<Map<String, String>> columnHeadList) {
        // 遍历所有列定义
        for (Map<String, String> columnDef : columnHeadList) {
            String key = columnDef.get("key");
            String itemType = columnDef.get("itemType");

            // 只处理非固定列（itemType != "0"）
//            if ("0".equals(itemType)) {
//                continue;
//            }

            Long dataTypeId = Long.valueOf(columnDef.get("datatypeid"));
            String name = columnDef.get("name");

            // 根据数据类型创建相应属性
            if (dataTypeId == 1050L) {
                // 日期类型属性
                DateProp dateProperty = new DateProp();
                dateProperty.setName(key);
                dateProperty.setDisplayName(new LocaleString(name));
                mainEntityType.addProperty(dateProperty);
            } else if (dataTypeId == 1010L || dataTypeId == 1020L || dataTypeId == 1030L) {
                // 文本类型属性（包括数值）
                TextProp textProperty = new TextProp();
                textProperty.setName(key);
                textProperty.setDisplayName(new LocaleString(name));
                textProperty.setMaxLenth(200);
                mainEntityType.addProperty(textProperty);
            } else {
                // 其他文本类型属性
                TextProp otherProperty = new TextProp();
                otherProperty.setName(key);
                otherProperty.setDisplayName(new LocaleString(name));
                otherProperty.setMaxLenth(200);
                mainEntityType.addProperty(otherProperty);
            }
        }
    }


    public class ImportItemDataResultImpl extends ListDataProvider {
        public ImportItemDataResultImpl() {
        }
        @Override
        public DynamicObjectCollection getData(int start, int limit) {
            DynamicObjectCollection list = super.getData(start, limit);

            // 如果是全选操作，直接返回基础数据
            if (this.getQueryBuilder().isSelectedAllRows()) {
                return list;
            }

            List<Map<String, String>> columnHeadList = OutTempDataViewBillListPlugin.this.getColumnHeadList();
            if (SWCHelper.isEmpty(columnHeadList)) {
                return list;
            }

            // 添加动态属性到实体类型
            OutTempDataViewBillListPlugin.this.addItemProp(list.getDynamicObjectType(), columnHeadList);

            // 提取ID列表用于查询
            List<Long> idList = list.stream()
                    .map(obj -> obj.getLong("id"))
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if (idList.isEmpty()) {
                return list;
            }
            // 获取详细数据映射
            Map<Long, Map<String, Object>> itemDataMap = this.getItemDataMap(idList);
            if (itemDataMap.isEmpty()) {
                return list;
            }
            // 将详细数据填充到主列表中
            for (DynamicObject obj : list) {
                Long id = obj.getLong("id");
                Map<String, Object> detailData = itemDataMap.get(id);
                if (detailData != null && !detailData.isEmpty()) {
                    for (Map.Entry<String, Object> entry : detailData.entrySet()) {
                        obj.set(entry.getKey(), entry.getValue());
                    }
                }
            }
            return list;
        }

        private Map<Long, Map<String, Object>> getItemDataMap(List<Long> idList) {
            Map<Long, Map<String, Object>> itemDataMap = new HashMap<>(16);
            HRBaseServiceHelper helper = new HRBaseServiceHelper("nckd_outtempdata");
            String fields = "id,entryentity.nckd_itemtype,entryentity.nckd_itemid,entryentity.nckd_datatype,entryentity.nckd_itemvalue";
            QFilter qFilter = new QFilter("id", "in", idList);
            DynamicObjectCollection itemData = helper.queryOriginalCollection(fields, new QFilter[]{qFilter});

            if (itemData.isEmpty()) {
                return itemDataMap;
            }

            for (DynamicObject obj : itemData) {
                Long objectId = obj.getLong("id");
                String itemValue = obj.getString("entryentity.nckd_itemvalue");

                // 跳过空值记录
                if (itemValue == null) {
                    continue;
                }

                // 获取或创建该对象的属性映射
                Map<String, Object> objectProperties = itemDataMap.computeIfAbsent(objectId, k -> new HashMap<>(16));

                // 获取列键和数据类型
                String itemType = obj.getString("entryentity.nckd_itemtype");
                Long itemId = obj.getLong("entryentity.nckd_itemid");
                String columnKey = this.getColumnKey(itemType, itemId);
                Long dataTypeId = obj.getLong("entryentity.nckd_datatype");

                // 根据数据类型处理值
                try {
                    Object processedValue = this.processValueByDataType(dataTypeId, itemValue);
                    objectProperties.put(columnKey, processedValue);
                } catch (ParseException e) {
                    OutTempDataViewBillListPlugin.logger.error("parse itemValue error", e);
                    throw new KDBizException(ExceptionUtils.getFullStackTrace(e));
                }
            }

            return itemDataMap;
        }

        /**
         * 根据数据类型处理值
         * @param dataTypeId 数据类型ID
         * @param itemValue 原始值
         * @return 处理后的值
         * @throws ParseException 解析异常
         */
        private Object processValueByDataType(Long dataTypeId, String itemValue) throws ParseException {
            if (dataTypeId == null) {
                return itemValue;
            }

            if (dataTypeId == 1050L) {
                // 日期类型
                return DateTimeUtils.parseDate(itemValue, "yyyy-MM-dd");
            } else if (dataTypeId == 1010L || dataTypeId == 1020L) {
                // 数值类型
                return new BigDecimal(itemValue);
            } else {
                // 其他类型作为字符串处理
                return itemValue;
            }
        }

        private String getColumnKey(String itemType, long itemId) {
            String columnKey = "";
            if ("0".equals(itemType)) {
                columnKey = "fix" + itemId;
            } else if ("1".equals(itemType)) {
                columnKey = "ii" + itemId;
            }

            return columnKey;
        }


    }
}