using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
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;
using static System.Net.Mime.MediaTypeNames;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Ramitta
{
    public partial class winTreeList : UserControl, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        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 label = new Label()
            {
                Content = text
            };

            var node = new LabelTreeNode
            {
                Text = text,
                obj = label
            };

            AddNode(node, parent);
            return node;
        }

        public CheckboxTreeNode AddCheckboxNode(string text, string? tag = null, bool isChecked = false, TreeNode? parent = null)
        {
            var checkbox = new CheckBox()
            {
                IsChecked = isChecked,
                Content = text,
                Tag = tag ?? text,
                ToolTip = tag ?? text,
                VerticalAlignment = VerticalAlignment.Center
            };

            // 处理选中状态变化
            checkbox.Checked += (s, e) => OnCheckboxStateChanged(checkbox, true);
            checkbox.Unchecked += (s, e) => OnCheckboxStateChanged(checkbox, false);

            var node = new CheckboxTreeNode
            {
                Text = text,
                obj = checkbox
            };

            AddNode(node, parent);
            return node;
        }

        public ComboboxTreeNode AddComboboxNode(string text, List<string>? items = null, TreeNode? parent = null)
        {
            var combobox = new ComboBox()
            {
                SelectedIndex = 0,
                VerticalAlignment = VerticalAlignment.Center,
                MinWidth = 100
            };

            // 处理选择改变事件
            combobox.SelectionChanged += (s, e) =>
            {
                if (combobox.SelectedItem is string selected)
                {
                    OnComboboxSelectionChanged(combobox, selected);
                }
            };

            var node = new ComboboxTreeNode
            {
                Text = text,
                obj = combobox
            };

            AddNode(node, parent);
            return node;
        }

        // 可选：添加事件处理方法
        private void OnCheckboxStateChanged(CheckBox checkbox, bool isChecked)
        {
            // 这里可以处理复选框状态变化逻辑
            Debug.WriteLine($"Checkbox '{checkbox.Tag}' changed to: {isChecked}");
        }

        private void OnComboboxSelectionChanged(ComboBox combobox, string selectedValue)
        {
            // 这里可以处理组合框选择变化逻辑
            Debug.WriteLine($"Combobox selection changed to: {selectedValue}");
        }
        #endregion

        #region 查(这里面的函数下一个版本全被杀)
        /// <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.obj.IsChecked ?? false))
                {
                    tags.Add(checkboxNode.obj.Tag.ToString());
                }

                // 递归查找子节点
                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.obj.IsChecked != true)
                {
                    tags.Add(checkboxNode.obj.Tag.ToString());
                }

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

        #endregion

        #region 查
        /// <summary>
        /// 按照指定key路径查找元素(返回一个)
        /// </summary>
        public TreeNode? FindArgvNode(IEnumerable<TreeNode> nodes, List<string> key) {
            if (nodes == null) nodes = Nodes;
            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 = FindArgvNode(node.Children, key.Skip(1).ToList());

                if (foundNode != null)
                {
                    return foundNode;
                }
            }
            return null;
        }
        public List<xTreeNode>? FindTreeNodes<xTreeNode>(IEnumerable<TreeNode>? nodes, string key)
            where xTreeNode : class
        {
            List<xTreeNode>? result = null;

            if (nodes == null) nodes = Nodes;

            foreach (var node in nodes)
            {
                // 检查当前节点是否匹配
                if (node.Text == key && node is xTreeNode)
                {
                    if(result == null) result = new List<xTreeNode>();
                        result.Add(node as xTreeNode);
                }
                //  跳过空子
                if (node.Children.Count == 0) 
                    continue;
                //  迭代下层
                List<xTreeNode>? res = FindTreeNodes<xTreeNode>(node.Children, key);

                if (res == null)continue;

                if (res.Count != 0) {
                    if (result == null) result = new List<xTreeNode>();
                    result.AddRange(res);
                }

            }
            return result;
        }


        //  改这个玩意
        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)[0];

            if (targetNode == null) 
                return null;
            else
                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;
                }
            }

            return null;
        }
        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;
        }





        public JObject JsonPrint(IEnumerable<TreeNode>? nodes, int loop = 0)
        {
            // 如果传入的节点为空，使用默认的 Nodes 集合
            if (nodes == null) nodes = Nodes;

            JObject resultObject = new JObject();

            // 为每个节点构建一个 JObject
            foreach (var node in nodes)
            {
                JObject nodeObject = new JObject();

                // 为当前节点添加基本信息
                nodeObject["Type"] = node.GetType().Name;

                if (node.GetType() == typeof(CheckboxTreeNode))
                {
                    nodeObject["IsChecked"] = (node as CheckboxTreeNode)?.obj.IsChecked.ToString();
                }

                
                if (node.GetType() == typeof(ComboboxTreeNode))
                {
                    var target = node as ComboboxTreeNode;
                    nodeObject["SelectedItem"] = target?.obj.SelectedItem.ToString();
                }
                

                // 处理子节点
                if (node.Children.Count > 0)
                {
                    // 递归调用以处理子节点，并将结果放在 "child" 属性下
                    JObject childrenObject = JsonPrint(node.Children, loop + 1);
                    nodeObject["child"] = childrenObject;
                }

                // 使用节点文本作为属性名，将当前节点对象添加到结果中
                resultObject.Add(node.Text, nodeObject);
            }

            // 返回结果对象
            return resultObject;
        }
        #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 : INotifyPropertyChanged
    {
        private string _text;
        private ObservableCollection<TreeNode> _children;

        public event PropertyChangedEventHandler? PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public TreeNode()
        {
            _children = new ObservableCollection<TreeNode>();
        }

        public string Text
        {
            get => _text;
            set
            {
                if (_text != value)
                {
                    _text = value;
                    OnPropertyChanged(nameof(Text));
                }
            }
        }

        public ObservableCollection<TreeNode> Children
        {
            get => _children;
            set
            {
                if (_children != value)
                {
                    _children = value;
                    OnPropertyChanged(nameof(Children));
                }
            }
        }
    }

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

        public Label obj
        {
            get => _obj;
            set
            {
                if (_obj != value)
                {
                    _obj = value;
                    OnPropertyChanged(nameof(obj));
                }
            }
        }
    }

    /// <summary>
    /// Combobox类型的树节点
    /// </summary>
    public class ComboboxTreeNode : TreeNode
    {
        private ComboBox _obj;

        public ComboBox obj
        {
            get => _obj;
            set
            {
                if (_obj != value)
                {
                    _obj = value;
                    OnPropertyChanged(nameof(obj));
                }
            }
        }
    }

    /// <summary>
    /// Checkbox类型的树节点
    /// </summary>
    public class CheckboxTreeNode : TreeNode
    {
        private CheckBox _obj;

        public CheckBox obj
        {
            get => _obj;
            set
            {
                if (_obj != value)
                {
                    _obj = value;
                    OnPropertyChanged(nameof(obj));
                }
            }
        }
    }
    #endregion
}