package com.fjhx.utils;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TreeUtil {

    /**
     * 节点ID名称
     */
    public static final String ID_NAME = "id";

    /**
     * 节点名称
     */
    public static final String LABEL_NAME = "label";

    /**
     * 子节点名称
     */
    public static final String CHILDREN_NAME = "children";

    /**
     * 父id名称
     */
    private static final String PARENT_ID_NAME = "parentId";

    /**
     * 构建树形列表
     *
     * @param labelName 需要构建的节点名称
     * @param list      需要构建的数组
     * @return 树形map
     */
    public static List<JSONObject> buildTree(String labelName, List<?> list) {
        return buildTree(ID_NAME, labelName, PARENT_ID_NAME, list);
    }

    /**
     * 构建树形列表
     *
     * @param idName       需要构建的节点ID名称
     * @param labelName    需要构建的节点名称
     * @param parentIdName 需要构建的节点父节点名称
     * @param list         需要构建的数组
     * @return 树形map
     */
    public static List<JSONObject> buildTree(String idName, String labelName, String parentIdName, List<?> list) {
        List<JSONObject> collect = list.stream().map(item -> {
            JSONObject data = JSON.parseObject(JSONObject.toJSONString(item));

            JSONObject jsonObject = new JSONObject();
            jsonObject.put(ID_NAME, data.get(idName));
            jsonObject.put(PARENT_ID_NAME, data.get(parentIdName));
            jsonObject.put(LABEL_NAME, data.get(labelName));

            return jsonObject;
        }).collect(Collectors.toList());
        return buildTreeObj(collect);
    }

    public static List<JSONObject> buildTreeObj(List<?> list) {
        return buildTreeObj(ID_NAME, PARENT_ID_NAME, CHILDREN_NAME, list);
    }

    public static List<JSONObject> buildTreeObj(String idName, String parentName, String childrenName, List<?> list) {

        // 将数据转为map形式
        List<JSONObject> dataList = JSONArray.parseArray(JSONObject.toJSONString(list), JSONObject.class);

        // 通过id作为key，转为map
        Map<String, JSONObject> idDataMap = dataList.stream().collect(Collectors.toMap(
                item -> item.getString(idName),
                item -> item,
                (v1, v2) -> v1
        ));

        // 封装树形
        return dataList.stream()
                .filter(data -> null == idDataMap.get(data.getString(parentName)))
                .peek(data -> {
                    // 递归找出子级节点
                    List<JSONObject> childNodes = findChildNodes(dataList, idName, parentName, childrenName, data.getString(idName));
                    if (childNodes.size() > 0) {
                        data.put(childrenName, childNodes);
                    }
                })
                .collect(Collectors.toList());
    }

    private static List<JSONObject> findChildNodes(List<JSONObject> dataList, String idName, String parentName, String childrenName, String id) {
        return dataList.stream()
                .filter(data -> ObjectUtil.equals(data.getString(parentName), id))
                .peek(data -> {
                    List<JSONObject> childNodes = findChildNodes(dataList, idName, parentName, childrenName, data.getString(idName));
                    if (childNodes.size() > 0) {
                        data.put(childrenName, childNodes);
                    }
                })
                .collect(Collectors.toList());
    }

}
