package com.jy.framework.utils.tree;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public class TreeUtil {

    /**
     * 构件树形集合
     *
     * @param list 所有节点
     * @return 树形集合
     */
    public static <T extends Tree<T>> List<T> build(List<T> list) {
        // 获取节点id列表
        Map<Long, List<T>> map = list.stream().collect(Collectors.groupingBy(Tree::getParentId));
        Set<Long> idSet = list.stream().map(Tree::getId).collect(Collectors.toSet());

        return list.stream()
                // 过滤非顶级节点
                .filter(item -> !idSet.contains(item.getParentId()))
                // 赋值顶级节点子节点
                .peek(item -> item.setChildren(findChildren(item.getId(), map)))
                // 收集数据
                .toList();
    }

    /**
     * 获取子节点id列表
     *
     * @param id   父节点id集合
     * @param list 所有节点id集合
     * @return 子节点id集合
     */
    public static <T extends TreeId> Set<Long> getChildrenIdSet(Long id, List<T> list) {
        Set<Long> result = list.stream()
                .filter(item -> Objects.equals(id, item.getParentId()))
                .flatMap(item -> getChildrenIdSet(item.getId(), list).stream())
                .collect(Collectors.toSet());

        result.add(id);

        return result;
    }

    /**
     * 查找子节点集合
     *
     * @param id  节点id
     * @param map 父节点map
     * @return 子节点结果集
     */
    private static <T extends Tree<T>> List<T> findChildren(Long id, Map<Long, List<T>> map) {
        List<T> list = map.get(id);
        if (list == null) {
            return Collections.emptyList();
        }

        return list.stream()
                // 递归赋值子节点的子节点
                .peek(item -> item.setChildren(findChildren(item.getId(), map)))
                // 收集数据
                .toList();
    }

}
