using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Xml.Linq;

namespace Ramitta
{
    public partial class winTreeList : UserControl
    {
        public winTreeList()
        {
            InitializeComponent();
            Nodes = new ObservableCollection<TreeNode>();
        }

        #region 公共属性
        /// <summary>
        /// 获取或设置树形列表的节点集合
        /// </summary>
        public ObservableCollection<TreeNode> Nodes
        {
            get { return (ObservableCollection<TreeNode>)GetValue(NodesProperty); }
            set { SetValue(NodesProperty, value); }
        }

        public static readonly DependencyProperty NodesProperty =
            DependencyProperty.Register("Nodes", typeof(ObservableCollection<TreeNode>),
                typeof(winTreeList), new PropertyMetadata(null, OnNodesChanged));

        private static void OnNodesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (winTreeList)d;
            control.treeView.ItemsSource = control.Nodes;
        }

        #endregion

        #region 公共方法

        #region 增
        public LabelTreeNode AddLabelNode(string text, TreeNode parent = null)
        {
            var node = new LabelTreeNode { Text = text };
            AddNode(node, parent);
            return node;
        }
        public CheckboxTreeNode AddCheckboxNode(string text, string? tag=null, bool isChecked = false, TreeNode parent = null)
        {
            var node = new CheckboxTreeNode { 
                Text = text, 
                IsChecked = isChecked, 
                Tag = tag ?? text };
            AddNode(node, parent);
            return node;
        }
        public ComboboxTreeNode AddComboboxNode(string text, string[]? item=null, TreeNode parent = null)
        {
            var node = new ComboboxTreeNode { 
                Text = text,
                ComboBoxItems = new ObservableCollection<string>(item  ?? []),
            };
            AddNode(node, parent);
            return node;
        }
        #endregion

        #region 查
        public TreeNode? FindNode(IEnumerable<TreeNode> nodes, List<string> key) {

            if(key.Count == 0) return null;

            foreach (var node in nodes)
            {
                if (node is TreeNode obj && 
                    obj.Text == key[0] && 
                    key.Count==1)
                {
                    //  最后的层级,且符合指标的第一个值
                    return obj;
                }

                var foundNode = FindNode(node.Children, key.Skip(1).ToList());

                if (foundNode != null)
                {
                    return foundNode;
                }
            }
            return null;
        }
        public List<TreeNode> FindAllTreeNodes(IEnumerable<TreeNode> nodes, string key, Type? targetType = null)
        {
            List<TreeNode> foundNodes = new List<TreeNode>();

            foreach (var node in nodes)
            {
                // 检查当前节点是否匹配
                if (node.Text == key && (targetType == null || targetType.IsAssignableFrom(node.GetType())))
                {
                    foundNodes.Add(node);
                }

                // 递归查找子节点
                foundNodes.AddRange(FindAllTreeNodes(node.Children, key, targetType));
            }

            return foundNodes;
        }

        /// <summary>
        /// 获取所有被勾选的Checkbox节点的Tag
        /// </summary>
        /// <param name="nodes">当前节点集合</param>
        /// <returns>被勾选Checkbox节点的Tag列表</returns>
        public List<string> GetCheckedCheckboxTags(IEnumerable<TreeNode> nodes)
        {
            var tags = new List<string>();
            foreach (var node in nodes)
            {
                if (node is CheckboxTreeNode checkboxNode && checkboxNode.IsChecked)
                {
                    tags.Add(checkboxNode.Tag);
                }

                // 递归查找子节点
                tags.AddRange(GetCheckedCheckboxTags(node.Children));
            }
            return tags;
        }

        /// <summary>
        /// 获取所有被勾选的Checkbox节点的Tag
        /// </summary>
        /// <param name="nodes">当前节点集合</param>
        /// <returns>被勾选Checkbox节点的Tag列表</returns>
        public List<string> GetNoCheckedCheckboxTags(IEnumerable<TreeNode> nodes)
        {
            var tags = new List<string>();
            foreach (var node in nodes)
            {
                if (node is CheckboxTreeNode checkboxNode && checkboxNode.IsChecked != true)
                {
                    tags.Add(checkboxNode.Tag);
                }

                // 递归查找子节点
                tags.AddRange(GetCheckedCheckboxTags(node.Children));
            }
            return tags;
        }

        public List<CheckboxTreeNode> GetNoCheckBoxNodes(bool check)
        {
            return GetAllNodes().OfType<CheckboxTreeNode>().
                Where(n =>
                    (check ? n.IsChecked : !n.IsChecked)
                    ).ToList();
        }

        /// <summary>
        /// 获取指定Label节点下所有被勾选的Checkbox节点的Tag列表
        /// </summary>
        /// <param name="labelNodeName">Label节点的名称</param>
        /// <returns>被勾选Checkbox节点的Tag列表</returns>
        public List<string> GetCheckboxTagsUnderLabelNode(string labelNodeName)
        {
            var tags = new List<string>();

            List<TreeNode> getTreeNode = FindAllTreeNodes(Nodes, labelNodeName, typeof(LabelTreeNode));
            var labelNode = getTreeNode.Count != 0 ? getTreeNode[0] : null;

            if (labelNode != null)
            {
                // 如果找到了Label节点，搜索其子节点
                tags.AddRange(GetCheckedCheckboxTags(labelNode.Children));
            }
            return tags;
        }



        public xTreeNode? FindTreeNodes<xTreeNode>(IEnumerable<TreeNode>? nodes, string key)
            where xTreeNode : class
        {
            if (nodes == null) nodes = Nodes;

            foreach (var node in nodes)
            {
                // 检查当前节点是否匹配
                if (node.Text == key)
                {
                    return node as xTreeNode;
                }

                if (node.Children == null) return null;
                
                //FindTreeNodes<xTreeNode>(node.Children, key);
            }
            return null;
//            throw new NotImplementedException($"方法：{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的targetNode为空");
        }


        public xControl? Find<xTreeNode, xControl>(IEnumerable<TreeNode>? nodes, string key)
            where xTreeNode : class
            where xControl : DependencyObject
        {
            if (nodes == null) nodes = Nodes;
            xTreeNode targetNode = FindTreeNodes<xTreeNode>(nodes, key);
            if (targetNode == null)
                throw new NotImplementedException($"方法：{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的targetNode为空");
            return To<xTreeNode, xControl>(targetNode);
        }

        public xControl? To<xTreeNode, xControl>(xTreeNode node)
            where xTreeNode : class
            where xControl : DependencyObject
        {
            var treeViewItem = FindTreeViewItem<xTreeNode>(treeView, node);

            if (treeViewItem != null)
            {
                xControl xCtrl = FindVisualChild<xControl>(treeViewItem);
                if (xCtrl != null)
                {
                    return xCtrl;
                }
            }
            throw new NotImplementedException(
                $"方法：{System.Reflection.MethodBase.GetCurrentMethod()?.Name}的{treeViewItem}为空");
        }

        private TreeViewItem FindTreeViewItem<T>(ItemsControl container, T xTreeNode) where T : class
        {
            for (int i = 0; i < container.Items.Count; i++)
            {
                TreeViewItem item = container.ItemContainerGenerator.ContainerFromIndex(i) as TreeViewItem;
                if (item != null)
                {
                    if (item.DataContext == xTreeNode)
                    {
                        return item;
                    }
                    TreeViewItem childItem = FindTreeViewItem<T>(item, xTreeNode);
                    if (childItem != null)
                    {
                        return childItem;
                    }
                }
            }
            return null;
        }

        private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);
                if (child is T)
                {
                    return (T)child;
                }

                T childOfChild = FindVisualChild<T>(child);
                if (childOfChild != null)
                {
                    return childOfChild;
                }
            }
            return null;
        }

        #endregion

        #region 删

        #endregion

        #region 动力学
        public void Clear()
        {
            Nodes.Clear();
        }
        public void ExpandAll()
        {
            foreach (var node in Nodes)
            {
                ExpandNode(node);
            }
        }
        public void CollapseAll()
        {
            foreach (var node in Nodes)
            {
                CollapseNode(node);
            }
        }
        #endregion

        #endregion

        #region 私有方法

        private void AddNode(TreeNode node, TreeNode parent)
        {
            if (parent == null)
            {
                Nodes.Add(node);
            }
            else
            {
                parent.Children.Add(node);
            }
        }

        private IEnumerable<TreeNode> GetAllNodes()
        {
            return GetAllNodes(Nodes);
        }

        private IEnumerable<TreeNode> GetAllNodes(IEnumerable<TreeNode> nodes)
        {
            foreach (var node in nodes)
            {
                yield return node;
                foreach (var child in GetAllNodes(node.Children))
                {
                    yield return child;
                }
            }
        }

        private void ExpandNode(TreeNode node)
        {
            var container = treeView.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem;
            if (container != null)
            {
                container.IsExpanded = true;
            }

            foreach (var child in node.Children)
            {
                ExpandNode(child);
            }
        }

        private void CollapseNode(TreeNode node)
        {
            var container = treeView.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem;
            if (container != null)
            {
                container.IsExpanded = false;
            }

            foreach (var child in node.Children)
            {
                CollapseNode(child);
            }
        }

        #endregion
    }

    #region 数据模型
    public abstract class TreeNode
    {
        public TreeNode()
        {
            Children = new ObservableCollection<TreeNode>();
        }

        public string Text { get; set; }
        public ObservableCollection<TreeNode> Children { get; set; }
    }

    /// <summary>
    /// Label类型的树节点
    /// </summary>
    public class LabelTreeNode : TreeNode
    {
    }

    /// <summary>
    /// Label类型的树节点
    /// </summary>
    public class ComboboxTreeNode : TreeNode
    {
        public string SelectedItem { get; set; }
        public ObservableCollection<string> ComboBoxItems { get; set; } = new ObservableCollection<string>();
    }

    /// <summary>
    /// Checkbox类型的树节点
    /// </summary>
    public class CheckboxTreeNode : TreeNode
    {
        public string Tag { get; set; }
        private bool _isChecked;
        public bool IsChecked
        {
            get { return _isChecked; }
            set
            {
                if (_isChecked != value)
                {
                    _isChecked = value;
                }
            }
        }
    }

    #endregion
}