package com.dayou.utils;

import com.dayou.bo.Tree;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

public class TreeUtil {

    /**
     * 根据平铺列表构建树(多个树)
     * @param list
     * @param <K>
     * @param <V>
     * @return
     */
    public static<K,V> List<? extends Tree<K,V>> buildTree(Collection<? extends Tree<K,V>> list,Long rootId){
        List<Tree<K, V>> trees = new LinkedList<>();

        if(org.apache.commons.collections4.CollectionUtils.isEmpty(list)){
            return trees;
        }

        //找出所有根节点
        List<? extends Tree<K,V>>  root = null;
        if (rootId!=null){
            root =  list.stream().filter(t->(t.getParentId().equals(rootId))).collect(Collectors.toList());
        }else {
            root = list.stream().filter(t->(t.getParentId()==null||t.getParentId().equals(0L))).collect(Collectors.toList());
        }
        if(CollectionUtils.isNotEmpty(root)){
            Collections.sort(root,(o1, o2) -> o1.order() - o2.order());
            //为每个节点找出它的children
            for (Tree<K,V> leaf:root){
                findChildren(leaf,list);
                trees.add(leaf);
            }
        }

        return trees;
    }

    /**
     * 根据平铺列表构建树
     * @param list
     * @param <K>
     * @param <V>
     * @return
     */
    public static<K,V> List<? extends Tree<K,V>> buildTree(Collection<? extends Tree<K,V>> list){
        List<Tree<K, V>> trees = new LinkedList<>();

        if(CollectionUtils.isEmpty(list)){
            return trees;
        }

        //找出所有根节点
        List<? extends Tree<K,V>>  root = list.stream().filter(t->(t.getParentId()==null||t.getParentId().equals(0L))).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(root)){
            Collections.sort(root,(o1, o2) -> o1.order() - o2.order());
            //为每个节点找出它的children
            for (Tree<K,V> leaf:root){
                findChildren(leaf,list);
                trees.add(leaf);
            }
        }

        return trees;
    }

    /**
     * 将树转换为平铺列表
     * @param trees
     * @param <K>
     * @param <V>
     * @return
     */
    public static<K,V> Collection<? extends Tree<K,V>> treeTile(Collection<? extends Tree<K,V>> trees){
        Collection<Tree<K, V>> list = new LinkedList<>();

        if(CollectionUtils.isEmpty(trees)){
            return Collections.EMPTY_LIST;
        }

        for(Tree<K,V> node:trees){
//            Tree<K, V> tiledNode = new Tree<K, V>() {
//                @Override
//                public K getId() {
//                    return node.getId();
//                }
//
//                @Override
//                public V getName() {
//                    return node.getName();
//                }
//
//                @Override
//                public K getParentId() {
//                    return node.getParentId();
//                }
//
//                @Override
//                public List<? extends Tree<K, V>> getChildren() {
//                    return null;
//                }
//
//                @Override
//                public void setChildren(List<? extends Tree<K, V>> children) {
//
//                }
//            };
            list.add(node);
            Collection<? extends Tree<K,V>> children=node.getChildren();
            if(CollectionUtils.isNotEmpty(children)){
                Collection<? extends Tree<K,V>> subList=treeTile(children);
                list.addAll(subList);
            }
            node.setChildren(null);
        }

        return list;

    }

    private static<K,V> void findChildren(Tree<K,V> leaf, Collection<? extends Tree<K,V>> list) {
        K id=leaf.getId();
        List<? extends Tree<K,V>> children = list.stream().filter(t->id.equals(t.getParentId())).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(children)){
            Collections.sort(children,(o1, o2) -> o1.order() - o2.order());
            leaf.setChildren(children);
        }
        list = list.stream().filter(t->!id.equals(t.getId())).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(children)){
            for(Tree<K,V> subLeaf:children){
                findChildren(subLeaf, list);
            }
        }
    }

    /**
     * 检测树中是否包含环
     * todo
     * @param list
     * @param <K>
     * @param <V>
     * @return
     */
    public static<K,V> boolean checkIfExistRecycle(Collection<? extends Tree<K,V>> list){
        return false;
    }
}
