package com.gyee.wisdom.common.data.system.model;

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

/**
 * @author northriver
 * @date 2017/5/11
 * id   label   path        level order
 * 1    水果      0           1   1
 * 2    苹果      0,1         2   1
 * 3    梨子      0,1         2   2
 * 4    雪梨      0,1,3       3   1
 * 5    鸭梨      0,1,3       3   2
 */
public class TreeModel {

    private String id;

    private String label;

    private String path="0";  //父节点的路径与父节点的id路径，用","分开，0表示父节点是根节点

    private int orderNo=1;  //排序

    private int type;//扩展字段。菜单类型，供不同业务区分

    private String style;//样式，方便ui展现

    /** 状态 是否禁用*/
    private boolean disabled;

    private List<? extends TreeModel> childNodes=new ArrayList<>();

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public int getLayer() {
        if(path==null){
            return 1;
        }
        return path.split(",").length;
    }


    public int getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(int orderNo) {
        this.orderNo = orderNo;
    }

    public boolean isDisabled() {
        return disabled;
    }

    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

    public String getStyle() {
        return style;
    }

    public void setStyle(String style) {
        this.style = style;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public TreeModel newChildNode(String nodeId, String label, int order){
        TreeModel node=new TreeModel();
        node.path =this.path +","+this.id;
        node.id=nodeId;
        node.orderNo=order;
        node.label=label;
        return node;
    }

    public List<? extends TreeModel> getChildNodes() {
        return childNodes;
    }

    @Override
    public String toString() {
        return label+"-"+ path +"-"+id+"-"+orderNo;
    }

    /***
     * 以level==1的节点作为开始节点构建树结构
     * @param nodes
     * @return
     */
    public static List<? extends TreeModel> buildTree(List<? extends TreeModel> nodes){
        if (isEmpty(nodes)){
            return null;
        }
        List<? extends TreeModel> firstLevels=nodes.stream().filter(node->!node.isDisabled() && node.getLayer()==1).collect(Collectors.toList());
        sortByOrder(firstLevels);
        firstLevels.stream().forEach(node-> setChildren(node,nodes));
        return firstLevels;
    }


    private static  void setChildren(TreeModel currentNode, List<? extends TreeModel> nodeList){
        List<? extends TreeModel> childrens=nodeList.stream().filter(node->(!node.isDisabled() && node.getPath().equals(currentNode.getPath()+","+currentNode.getId()))).collect(Collectors.toList());
        currentNode.childNodes=childrens;
        if (isEmpty(childrens)){
            return;
        }
        sortByOrder(childrens);
        childrens.stream().forEach(node-> setChildren(node,nodeList));

    }

    private static void sortByOrder(List<? extends TreeModel> firstLevels) {
        firstLevels.sort((node1,node2)->Integer.valueOf(node1.getOrderNo()).compareTo(Integer.valueOf(node2.getOrderNo())));
    }


    /***
     * 按数结构给节点排序
     * @param nodes
     */
    public static void sortByTree(List<? extends TreeModel> nodes) {
        if(isEmpty(nodes)){
            return;
        }
        sortByOrder(nodes);
        nodes.sort((o1, o2) -> (o1.getPath()+","+o1.getId()).compareTo(o2.getPath()+","+o2.getId()));
    }

    private static boolean isEmpty(List nodes) {
        return nodes == null || nodes.isEmpty();
    }


    //按节点的父子层次顺序展示
    private static void printTreeToConsole(List<TreeModel> nodes){
        if (isEmpty(nodes)){
            return;
        }

        sortByTree(nodes);

        nodes.stream().forEach(node->{
            if(node.isDisabled()){
                return;
            }
            for(int i=1;i<node.getLayer();i++){
                System.out.print("\t");
            }
            System.out.println(node);
        });
    }


    //以第一层为起点，递归方式展示父子层次树
    private static void printFirstLevelTreeToConsole(List<? extends TreeModel> nodes){
        if (isEmpty(nodes)){
            return;
        }
        nodes.forEach(item->{
            if(item.isDisabled()){
                return;
            }
            for(int i=1;i<item.getLayer();i++){
                System.out.print("\t");
            }
            System.out.println(item);

            printFirstLevelTreeToConsole(item.getChildNodes());
        });
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        TreeModel treeModel = (TreeModel) o;

        return id != null ? id.equals(treeModel.id) : treeModel.id == null;

    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;
    }

    public static void main1(String[] arg){
        List<TreeModel> nodes=new ArrayList<>();
        TreeModel fruit=new TreeModel();
        fruit.setId("1");
        fruit.setLabel("水果");
        fruit.setOrderNo(2);
        nodes.add(fruit);

        TreeModel apple=fruit.newChildNode("7","苹果",2);
        nodes.add(apple);
        nodes.add(apple.newChildNode("4","红富士",2));
        nodes.add(apple.newChildNode("15","山东苹果",1));

        TreeModel lizi=fruit.newChildNode("e8","梨子",1);
        nodes.add(lizi);
        nodes.add(lizi.newChildNode("7r7","雪梨",1));
        nodes.add(lizi.newChildNode("t31o","鸭梨",2));

        TreeModel shucai=new TreeModel();
        shucai.setId("a101");
        shucai.setLabel("蔬菜");
        shucai.setOrderNo(1);
        shucai.setDisabled(true);
         nodes.add(shucai);
        nodes.add(shucai.newChildNode("213","白菜",2));
        printTreeToConsole(nodes);

        System.out.println("====================");
        List<? extends TreeModel> tree= TreeModel.buildTree(nodes);
        printFirstLevelTreeToConsole(tree);






    }

}
