package com.hdkj.lt.utils.tree;

import java.util.*;

/**
 * @author luorui
 * @date 2025/6/23 16:01
 */
public class TreeBuilder {

    /**
     * @param nodes 节点列表
     * @param <T>   节点类型，需要实现TreeNode 接口
     * @return 根节点列表（只返回根节点列表）
     * @author luorui
     * @date 2025/6/23 16:03
     * @discription
     **/
    public static <T extends TreeNode<T>> List<T> buildTree(List<T> nodes) {
        if (nodes == null || nodes.isEmpty()) {
            return Collections.emptyList();
        }
        //使用Map 缓存节点，便于快速查找
        Map<Long, T> nodeMap = new HashMap<>();
        List<T> rootNodes = new ArrayList<>();

        //1.将所有node 添加到map中
        for (T node : nodes) {
            nodeMap.put(node.getId(), node);
        }

        //2.遍历节点，构建父子关系
        for (T node : nodes) {
            Long parentId = node.getParentId();
            //如果父节点为null或者不存在，则当前节点为根节点
            if (parentId == null || !nodeMap.containsKey(parentId)) {
                rootNodes.add(node);
                continue;
            }
            //找到父节点，将当前节点添加到父节点的子节点列表中
            T parentNode = nodeMap.get(parentId);
            if (parentNode.getChildren() == null) {
                parentNode.setChildren(new ArrayList<>());
            }
            parentNode.getChildren().add(node);
        }
        return rootNodes;
    }

    /**
     * @param nodes 节点列表
     * @param <T>   节点类型，需要实现TreeNode 接口
     * @return 返回完整的树结构 （入参节点列表中每个元素都是一棵树）
     * @author luorui
     * @date 2025/6/25 17:53
     * @discription 构建完整的树结构,包含所有的节点树。
     **/
    public static <T extends TreeNode<T>> Map<Long, T> buildFullTree(List<T> nodes) {
        if (nodes == null || nodes.isEmpty()) {
            return null;
        }
        //使用Map 缓存节点，便于快速查找
        Map<Long, T> nodeMap = new HashMap<>();

        //1.将所有node 添加到map中
        for (T node : nodes) {
            nodeMap.put(node.getId(), node);
        }
        //2.遍历节点，构建父子关系
        for (T node : nodes) {
            Long parentId = node.getParentId();
            if (parentId != null && nodeMap.containsKey(parentId)) {
                T parentNode = nodeMap.get(parentId);
                if (parentNode.getChildren() == null) {
                    parentNode.setChildren(new ArrayList<>());
                }
                //没有children的也加上空集合
                if(node.getChildren()==null){
                    node.setChildren(new ArrayList<>());
                }
                parentNode.getChildren().add(node);
            }
        }
        return nodeMap;
    }




}
