using System;
using System.Collections.Generic;
using System.Linq;

namespace YGNT.Infrastructure.Helper
{

    /// <summary>
    /// 树节点（可以转化为树对象）
    /// 把你的原对象转为这个对象的时候可以使用ConvertAll()
    /// 使用方法【data.ConvertAll(o => new TreeNode() { ID = o.ID, Label = o.Name, PID = o.PID, Value = o });】
    /// </summary>
    public class TreeNode
    {
        private string _ID;
        /// <summary>
        /// ID（不能等于0）
        /// </summary>
        public string Id
        {
            get { return _ID; }
            set
            {
                if (string.IsNullOrEmpty(value))
                    throw new Exception("ID不能等于空");
                _ID = value;
            }
        }

        /// <summary>
        /// 父级ID（0为首级）
        /// </summary>
        public string Pid { get; set; }
        /// <summary>
        /// 显示的值
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 数据
        /// </summary>
        public object Value { get; set; }
    }
    /// <summary>
    /// 树对象(更好的针对于前端来使用)
    /// </summary>
    public class TreeObject
    {
        /// <summary>
        /// ID
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// 显示的值
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 值
        /// </summary>
        public object Value { get; set; }

        private List<TreeObject> _Children = new List<TreeObject>();
        /// <summary>
        /// 子级
        /// </summary>
        public List<TreeObject> Children
        {
            get { return _Children; }
            set { _Children = value; }
        }
    }

    /// <summary>
    /// 树类
    /// </summary>
    public static class Tree
    {
        #region 转对象
        /// <summary>
        /// 转化为树对象
        /// </summary>
        /// <param name="treeNodes"></param>
        /// <returns></returns>
        public static List<TreeObject> ToTree(this List<TreeNode> treeNodes)
        {
            List<TreeObject> result = new List<TreeObject>();
            foreach (TreeNode item in treeNodes.Where(a => a.Pid == "0"))
            {
                TreeObject tree = new TreeObject();
                tree.Name = item.Name;
                tree.Value = item.Value;
                tree.Id = item.Id;

                GetChildArea(tree, treeNodes, item.Id);
                result.Add(tree);
            }
            return result;
        }

        /// <summary>
        /// 使用递归方式转化
        /// </summary>
        private static void GetChildArea(TreeObject currentArea, List<TreeNode> data, string id)
        {
            List<TreeNode> child = data.Where(d => d.Pid == id).ToList();

            //还有子节点
            if (child.Count != 0)
            {
                List<TreeObject> Tchild = new List<TreeObject>();
                foreach (TreeNode item in child)
                {
                    TreeObject tree = new TreeObject();
                    tree.Name = item.Name;
                    tree.Value = item.Value;
                    tree.Id = item.Id;

                    GetChildArea(tree, data, item.Id);
                    Tchild.Add(tree);
                }
                currentArea.Children = Tchild;
            }
        }
        #endregion

        #region 得到父级
        /// <summary>
        /// 得到树节点的父级（根据子节点的ID来查找），比如[重庆市,渝中区,解放碑]
        /// </summary>
        /// <param name="treeNodes"></param>
        /// <param name="childrenID">最底下的子级ID，如[解放碑]的ID</param>
        /// <returns>按照父到子的大小顺序排列的树节点对象</returns>
        public static List<TreeNode> GetParent(this List<TreeNode> treeNodes, string childrenID)
        {
            List<TreeNode> result = new List<TreeNode>();
            if (treeNodes == null || treeNodes.Count < 1)
                return result;

            TreeNode item = treeNodes.Where(o => o.Id == childrenID).FirstOrDefault();
            if (item == null)
                return result;

            result.Add(item);

            GetParent(result, treeNodes, item.Pid);

            return result;
        }

        /// <summary>
        /// 使用递归方式转化
        /// </summary>
        private static void GetParent(List<TreeNode> currentArea, List<TreeNode> data, string pid)
        {
            TreeNode child = data.Where(d => d.Id == pid).FirstOrDefault();

            //还有子节点
            if (child != null)
            {
                currentArea.Insert(0, child);
                GetParent(currentArea, data, child.Pid);
            }
        }
        #endregion

        #region 得到子级

        /// <summary>
        /// 得到所有的子级（节点下没有任何子级的）（非递归方式）
        /// </summary>
        /// <param name="treeNodes"></param>
        /// <param name="isPidZero">是否包含PID为零的</param>
        /// <returns>所有的子节点</returns>
        public static List<TreeNode> GetChildrenAll(this List<TreeNode> treeNodes, bool isPidZero = true)
        {
            List<TreeNode> result = new List<TreeNode>();
            if (treeNodes == null || treeNodes.Count < 1)
                return result;

            IEnumerable<TreeNode> NoTr = treeNodes.Where(o => o.Id != "0");
            foreach (var item in treeNodes)
            {
                if (item.Id == "0" && isPidZero)
                {
                    if (NoTr.Count(o => o.Pid == item.Id) == 0)
                        result.Add(item);
                }
                else if (item.Id != "0" && NoTr.Count(o => o.Pid == item.Id) == 0)
                    result.Add(item);
            }
            return result;
        }

        #endregion

    }
}
