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

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.tree.TreeNode;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.bos.util.CollectionUtils;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import nckd.jxccl.sit.hcsi.formplugin.web.tp.helper.SitItemSelectAddItemServiceHelper;
import nckd.jxccl.swc.constants.SwcConstant;

import java.util.*;
import java.util.stream.Collectors;

public class OutItemSelectAddItemServiceHelper {

    private static final String SALARYITEM_ENTITY = "hsbs_salaryitem";
    private static final String QUERY_FIELDS = "id,number,name,statisticstag.name,statisticstag.number,statisticstag.id";
    private static final String DEFAULT_ORDER = "number asc";

    private static final String SALARYITEM_KEY = "salaryitemkey";
    private static final String BASEITEM_KEY = "baseitemkey";
    private static final String ITEM_TYPE_SI = "SI";
    private static final String BASE_TYPE_BI = "BI";
    private static final String PREFIX_SEPARATOR = "_@_";

    /**
     * 获取所有需要展示的项目，目前就险种
     * @param orgId
     * @return
     */
    public Map<String, Map<String, Map<String, Object>>> getAllItemData(long orgId) {
        Map<String, Map<String, Map<String, Object>>> dataMap = new HashMap(4);
        Map<String, Map<String, Object>> salaryItemMap = this.getSalaryItemList(false, (QFilter)null, (QFilter)null, orgId);
        Map<String, Map<String, Object>> baseItemMap = this.getBaseItemList();
        dataMap.put("salaryitemkey", salaryItemMap);
        dataMap.put("baseitemkey", baseItemMap);
        return dataMap;
    }

    private Map<String, Map<String, Object>> getBaseItemList() {
        QFilter filter = new QFilter ("enable", QCP.equals, "1");
        filter.and("nckd_ispreset", QCP.equals, false);
        String queryFields = "id,number,name,group.name,group.number,group.id";
        DynamicObjectCollection dyns = SwcConstant.OUTIMPORTITEM_ENTITY.queryOriginalCollection(queryFields, new QFilter[]{filter});
        return dyns.stream()
                .collect(Collectors.toMap(
                        item -> item.getString("name"),
                        item -> this.convertToItemMap(item, BASE_TYPE_BI),
                        (existing, replacement) -> existing,
                        LinkedHashMap::new
                ));
    }

    public Map<String, Map<String, Object>> getBaseItemMap() {
        return null;
    }

    private Map<String, Map<String, Object>> getSalaryItemList(boolean isProrationFormula, QFilter countryQFilter, QFilter calBlockQFilter, long orgId) {
        if (isProrationFormula) {
            return Collections.emptyMap();
        }
        List<QFilter> qFilters = buildFilters(countryQFilter, calBlockQFilter, orgId);
        DynamicObjectCollection result = querySalaryItems(qFilters);
        return result.stream()
                .collect(Collectors.toMap(
                        item -> item.getString("name"),
                        item -> this.convertToItemMap(item, ITEM_TYPE_SI),
                        (existing, replacement) -> existing,
                        LinkedHashMap::new
                ));
    }

    private static List<Map<String, Object>> getSalaryItemList(String name, String key,
                                                                  Map<String, Map<String, Map<String, Object>>> dataMap) {
        return StringUtils.isEmpty(name)
                ? SitItemSelectAddItemServiceHelper.mapToList(dataMap.get(key))
                : SitItemSelectAddItemServiceHelper.findItemByName(name, key, dataMap);
    }

    private List<QFilter> buildFilters(QFilter countryQFilter, QFilter calBlockQFilter, long orgId) {
        List<QFilter> filters = new ArrayList<>();
        Optional.ofNullable(countryQFilter).ifPresent(filters::add);
        Optional.ofNullable(calBlockQFilter).ifPresent(filters::add);
        QFilter baseFilter = new QFilter("enable", "=", "1")
                .and(new QFilter("status", "=", "C"));
                //.and(new QFilter("insurancetypeattr.number", QCP.not_in, new String[]{"1007_S","1008_S","1013_S","1014_S"}));
        filters.add(baseFilter);
        filters.add(BaseDataServiceHelper.getBaseDataFilter(SALARYITEM_ENTITY, orgId));
        return filters;
    }

    private DynamicObjectCollection querySalaryItems(List<QFilter> filters) {
        HRBaseServiceHelper helper = new HRBaseServiceHelper(SALARYITEM_ENTITY);
        return helper.queryOriginalCollection(
                QUERY_FIELDS,
                filters.toArray(new QFilter[0]),
                DEFAULT_ORDER
        );
    }

    private Map<String, Object> convertToItemMap(DynamicObject item, String key) {
        Map<String, Object> itemMap = new HashMap<>(3);
        itemMap.put("id", item.getLong("id"));
        itemMap.put("number", item.getString("number"));
        itemMap.put("name", item.getString("name"));

        if(key.equals(ITEM_TYPE_SI)) {
            itemMap.put("group_name", item.getString("statisticstag.name"));
            itemMap.put("group_number", item.getString("statisticstag.number"));
            itemMap.put("group_id", item.getString("statisticstag.id"));
        }
        else {
            itemMap.put("group_name", item.getString("group.name"));
            itemMap.put("group_number", item.getString("group.number"));
            itemMap.put("group_id", item.getString("group.id"));
        }
        return itemMap;
    }

    /**
     * 构建薪酬项目树结构
     * 顶层ID ： SI
     * 分类节点ID：薪酬分类编码 + _@_
     * 薪酬项目子节点ID：薪酬项目ID
     * @param name
     * @param isExpend
     * @param dataMap
     * @return
     */
    public static List<TreeNode> loadSalaryItemChildNode(String name, boolean isExpend,
                                                            Map<String, Map<String, Map<String, Object>>> dataMap) {
        // 所有险种项目
        List<Map<String, Object>> salaryItemList = getSalaryItemList(name, SALARYITEM_KEY, dataMap);
        List<TreeNode> tree = createRootNode(isExpend, SALARYITEM_KEY);
        if (CollectionUtils.isEmpty(salaryItemList)) {
            return tree;
        }

        // 最后返回树：
        List<TreeNode> totalNodeList = new ArrayList<>(salaryItemList.size() + 1);

        // 构建根节点：
        TreeNode itemRoot = new TreeNode("", ITEM_TYPE_SI,
                ResManager.loadKDString("薪酬项目-SI", "FormulaItemOrFuncTreeHelper_1",
                        "swc-hsas-business", new Object[0]));
        itemRoot.setExpend(isExpend);
        itemRoot.setIsOpened(isExpend);
        totalNodeList.add(itemRoot);

        // 构建子节点：
        if (!CollectionUtils.isEmpty(salaryItemList)) {
            Map<String, TreeNode> itemTypeNodeMap = new LinkedHashMap(salaryItemList.size());
            Map<String, List<TreeNode>> insuranceItemNodeMap = new HashMap(16);
            List<TreeNode> treeNodeList = null;
            String itemTypeNum = null;
            for (Map<String, Object> map : salaryItemList) {
                itemTypeNum = (String)map.get("group_number");
                String itemTypeName = (String)map.get("group_name");
                treeNodeList = (List)insuranceItemNodeMap.get(itemTypeNum);
                if (treeNodeList == null) {
                    treeNodeList = new ArrayList(10);
                    insuranceItemNodeMap.put(itemTypeNum, treeNodeList);
                }
                ((List)treeNodeList).add(new TreeNode(ITEM_TYPE_SI + itemTypeNum + PREFIX_SEPARATOR, String.valueOf(map.get("id")), (String)map.get("name")));
                if (!itemTypeNodeMap.containsKey(itemTypeNum)) {
                    TreeNode itemTreeNode = new TreeNode(ITEM_TYPE_SI, ITEM_TYPE_SI + itemTypeNum + PREFIX_SEPARATOR, itemTypeName);
                    itemTreeNode.setExpend(isExpend);
                    itemTreeNode.setIsOpened(isExpend);
                    itemTypeNodeMap.put(itemTypeNum, itemTreeNode);
                }
            }
            treeNodeList = new ArrayList(itemTypeNodeMap.size());
            Iterator it = itemTypeNodeMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, TreeNode> entry = (Map.Entry)it.next();
                TreeNode typeNode = (TreeNode)entry.getValue();
                typeNode.setChildren((List)insuranceItemNodeMap.get(entry.getKey()));
                treeNodeList.add(typeNode);
            }
            itemRoot.setChildren(treeNodeList);
            return totalNodeList;
        }
        else {
            return totalNodeList;
        }
    }

    /**
     * 构建基本项目树结构
     * 顶层ID ： BI
     * 基本项目分类节点ID：项目分类编码 + _@_
     * 基本项目子节点ID：基本项目ID
     * @param name
     * @param isExpend
     * @param dataMap
     * @return
     */
    public static List<TreeNode> loadBaseItemChildNode(String name, boolean isExpend,
                                                         Map<String, Map<String, Map<String, Object>>> dataMap) {
        // 所有基本项目
        List<Map<String, Object>> baseItemList = getSalaryItemList(name, BASEITEM_KEY, dataMap);
        List<TreeNode> tree = createRootNode(isExpend, BASEITEM_KEY);
        if (CollectionUtils.isEmpty(baseItemList)) {
            return tree;
        }

        // 最后返回树：
        List<TreeNode> totalNodeList = new ArrayList<>(baseItemList.size() + 1);

        // 构建根节点：
        TreeNode itemRoot = new TreeNode("", BASE_TYPE_BI,
                ResManager.loadKDString("基本项目-BI", "FormulaItemOrFuncTreeHelper_1",
                        "swc-hsas-business", new Object[0]));
        itemRoot.setExpend(isExpend);
        itemRoot.setIsOpened(isExpend);
        totalNodeList.add(itemRoot);

        // 构建子节点：
        if (!CollectionUtils.isEmpty(baseItemList)) {
            Map<String, TreeNode> itemTypeNodeMap = new LinkedHashMap(baseItemList.size());
            Map<String, List<TreeNode>> baseItemNodeMap = new HashMap(16);
            List<TreeNode> treeNodeList = null;
            String itemTypeNum = null;
            for (Map<String, Object> map : baseItemList) {
                itemTypeNum = (String)map.get("group_number");
                String itemTypeName = (String)map.get("group_name");
                treeNodeList = (List)baseItemNodeMap.get(itemTypeNum);
                if (treeNodeList == null) {
                    treeNodeList = new ArrayList(10);
                    baseItemNodeMap.put(itemTypeNum, treeNodeList);
                }
                ((List)treeNodeList).add(new TreeNode(BASE_TYPE_BI + itemTypeNum + PREFIX_SEPARATOR, String.valueOf(map.get("id")), (String)map.get("name")));
                if (!itemTypeNodeMap.containsKey(itemTypeNum)) {
                    TreeNode itemTreeNode = new TreeNode(BASE_TYPE_BI, BASE_TYPE_BI + itemTypeNum + PREFIX_SEPARATOR, itemTypeName);
                    itemTreeNode.setExpend(isExpend);
                    itemTreeNode.setIsOpened(isExpend);
                    itemTypeNodeMap.put(itemTypeNum, itemTreeNode);
                }
            }
            treeNodeList = new ArrayList(itemTypeNodeMap.size());
            Iterator it = itemTypeNodeMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, TreeNode> entry = (Map.Entry)it.next();
                TreeNode typeNode = (TreeNode)entry.getValue();
                typeNode.setChildren((List)baseItemNodeMap.get(entry.getKey()));
                treeNodeList.add(typeNode);
            }
            itemRoot.setChildren(treeNodeList);
            return totalNodeList;
        }
        else {
            return totalNodeList;
        }
    }

    private static List<TreeNode> createRootNode(boolean isExpend, String key) {
        return createRootNode(isExpend, Collections.emptyList(), key);
    }

    private static List<TreeNode> createRootNode(boolean isExpend, List<TreeNode> children, String key) {
        String str = null;
        if(key.equals(BASE_TYPE_BI)) {
            str = ResManager.loadKDString("基本项目-BI", "FormulaItemOrFuncTreeHelper_1",
                    "swc-hsas-business", new Object[0]);
        }
        else if (key.equals(ITEM_TYPE_SI)) {
            str = ResManager.loadKDString("薪酬项目-SI", "FormulaItemOrFuncTreeHelper_1",
                    "swc-hsas-business", new Object[0]);
        }
        TreeNode itemRoot = new TreeNode("", key, str);
        itemRoot.setExpend(isExpend);
        itemRoot.setIsOpened(isExpend);
        itemRoot.setChildren(children);
        return Collections.singletonList(itemRoot);
    }
}
