using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace XmlToTreeView
{
    public partial class NodeSelectionDialog : Form
    {
        private Node selectedValue;
        public Node SelectedValue { get => selectedValue; set => selectedValue = value; }
        static readonly string ConfigPath = @"D:\XmlParser\Config.txt";

        static readonly string TreeViewState = @"D:\XmlParser\treeview_state.xml";

        public NodeSelectionDialog()
        {
            InitializeComponent();
        }

        private void NodeSelectionDialog_Load(object sender, EventArgs e)
        {
            this.Size = new System.Drawing.Size(1024, 768);
            if (File.Exists(ConfigPath))
            {
                var xmlPath = File.ReadAllText(ConfigPath);
                LoadTree(xmlPath,false);
            }
            LoadTreeViewState(treeView);
            txtSearch.Focus();
        }

        private void LoadTree(string xmlPath,bool isUserLoad)
        {
            if (!File.Exists(xmlPath))
            {
                return;
            }
            try
            {
                var types = SymbolParser.ParseTypeList(xmlPath);
                var root = SymbolParser.ParseNode(xmlPath, types);
                treeView.Nodes.Clear();
                AddToTreeView(treeView.Nodes, root);
                foreach (TreeNode node in treeView.Nodes)
                {
                    node.Expand();
                }

                if (isUserLoad)//只有用户打开的时候才去保存
                {
                    FileInfo fileInfo = new FileInfo(ConfigPath);
                    DirectoryInfo dir = fileInfo.Directory;
                    Directory.CreateDirectory(dir.FullName);
                    File.WriteAllText(ConfigPath, xmlPath);

                    Node.AllNodes = new List<string>();
                    GenerateFullPaths(root, Node.AllNodes);
                    File.WriteAllLines(Node.NodeFilePath, Node.AllNodes.ToArray());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message,"错误",MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }
        private void AddToTreeView(TreeNodeCollection nodes, XmlVariable variableNode)
        {
            TreeNode tn = new TreeNode(variableNode.DisplayName);
            tn.Tag = variableNode.Name;

            foreach (var child in variableNode.Children)
            {
                AddToTreeView(tn.Nodes, child);
            }
            nodes.Add(tn);
        }

        private string GetFullPath(TreeNode node)
        {
            List<string> pathParts = new List<string>();
            TreeNode currentNode = node;
            
            while (currentNode != null)
            {
                // 获取当前节点显示的文本
                pathParts.Add(currentNode.Tag.ToString());
                // 获取父节点
                currentNode = currentNode.Parent;
            }

            pathParts.Reverse(); // 从根到叶子排列
            return string.Join(".", pathParts);
        }
        private void GenerateFullPaths(XmlVariable root, List<string> paths, string currentPath = "")
        {
            string newPath = string.IsNullOrEmpty(currentPath) ? root.Name : $"{currentPath}.{root.Name}";

            if (root.IsLeaf)
            {
                paths.Add(ProcessArrayPath(newPath));
            }
            else
            {
                foreach (var child in root.Children)
                {
                    GenerateFullPaths(child, paths, newPath);
                }
            }
        }
        string ProcessArrayPath(string path)
        {
            // 第一步：去掉 .[ 前面的点，变成 [
            string result = path;
            while (true)
            {
                int index = result.IndexOf(".[", StringComparison.Ordinal);
                if (index == -1) break;

                result = result.Substring(0, index) + "[" + result.Substring(index + 2);
            }
            // 第二步：合并 [1][2] → [1,2]
            while (true)
            {
                int index = result.IndexOf("][", StringComparison.Ordinal);
                if (index == -1) break;

                // 替换 ][ 为 ,，并删除多余的 ]
                result = result.Substring(0, index) + "," + result.Substring(index + 2);
            }
            return result;
        }

        private void 打开XMLOToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "XML文档|*.xml";
            openFileDialog.Multiselect = false;
            openFileDialog.RestoreDirectory = true;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                LoadTree(openFileDialog.FileName,true);
            }

        }
        private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
           
            if (e.Node.Nodes.Count > 0)
                return;
            var currentNode = treeView.GetNodeAt(e.X, e.Y);

            if (currentNode != null)
            {
                string fullPath = GetFullPath(currentNode);
                txtNode.Text = ProcessArrayPath(fullPath);

                txtType.Text = GetTypeString(currentNode.Text,'(',')');
                txtComment.Text = GetTypeString(currentNode.Text, '<', '>');
            }
        }
        string GetTypeString(string nodeTxt,char spliter1, char spliter2)
        {
            int startIndex = nodeTxt.LastIndexOf(spliter1);
            int endIndex = nodeTxt.LastIndexOf(spliter2);

            if (startIndex >= 0 && endIndex > startIndex)
            {
                string result = nodeTxt.Substring(startIndex + 1, endIndex - startIndex - 1);
                return result;
            }
            return null;
        }
        bool userSelectedNode;
        private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Nodes.Count > 0)
                return;

            var currentNode = treeView.GetNodeAt(e.X, e.Y);

            if (currentNode != null)
            {
                string fullPath = GetFullPath(currentNode);
                string rt = ProcessArrayPath(fullPath);
                txtNode.Text = rt;

                var typeString= GetTypeString(currentNode.Text, '(', ')');
                
                bool isDefinedType = Enum.TryParse<NodeType>(typeString, out NodeType type) && Enum.IsDefined(typeof(NodeType), type);
                if (isDefinedType)
                {
                    SelectedValue = new Node(rt, type, GetTypeString(currentNode.Text, '<', '>'));
                    DialogResult = DialogResult.OK;
                    userSelectedNode = true;
                    Close();
                }
                else
                {
                    MessageBox.Show($"暂不支持：{typeString}类型数据","错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
                    return;
                }
            }
        }

        private void LoadTreeViewState(System.Windows.Forms.TreeView treeView)
        {
            if (!File.Exists(TreeViewState)) return;

            using (FileStream fs = new FileStream(TreeViewState, FileMode.Open))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(TreeViewState));
                var state = (TreeViewState)serializer.Deserialize(fs);

                // 恢复展开状态
                foreach (var node in GetAllNodes(treeView.Nodes))
                {
                    if (state.ExpandedNodeKeys.Contains(GetNodeKey(node)))
                    {
                        node.Expand();
                    }
                }

                // 恢复选中状态
                if (!string.IsNullOrEmpty(state.SelectedNodeKey))
                {
                    TreeNode selectedNode = FindNodeByPath(treeView, state.SelectedNodeKey);
                    if (selectedNode != null)
                    {
                        treeView.SelectedNode = selectedNode;
                        string fullPath = GetFullPath(selectedNode);
                        txtNode.Text = ProcessArrayPath(fullPath);
                    }
                }
            }
        }

        // 根据 FullPath 查找节点
        private TreeNode FindNodeByPath(System.Windows.Forms.TreeView treeView, string fullPath)
        {
            foreach (var node in GetAllNodes(treeView.Nodes))
            {
                if (((TreeNode)node).FullPath == fullPath)
                {
                    return (TreeNode)node;
                }
            }
            return null;
        }

        private void NodeSelectionDialog_FormClosed(object sender, FormClosedEventArgs e)
        {
            if(userSelectedNode)
                SaveTreeViewState(treeView);
        }
        private void SaveTreeViewState(System.Windows.Forms.TreeView treeView)
        {
            TreeViewState state = new TreeViewState();

            // 保存选中节点
            if (treeView.SelectedNode != null)
            {
                state.SelectedNodeKey = GetNodeKey(treeView.SelectedNode);
            }

            // 保存所有已展开的节点
            foreach (TreeNode node in GetAllNodes(treeView.Nodes))
            {
                if (node.IsExpanded)
                {
                    state.ExpandedNodeKeys.Add(GetNodeKey(node));
                }
            }
            
            // 使用序列化保存到文件或其他地方
            using (FileStream fs = new FileStream(TreeViewState, FileMode.Create))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(TreeViewState));
                serializer.Serialize(fs, state);
            }
        }

        // 获取唯一标识符（可以是 FullPath、Text 或你自己设计的 Key）
        private string GetNodeKey(TreeNode node)
        {
            return node.FullPath;
        }

        // 遍历所有节点（递归）
        private IEnumerable<TreeNode> GetAllNodes(TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                yield return node;
                foreach (var child in GetAllNodes(node.Nodes))
                {
                    yield return child;
                }
            }
        }



        private void btnSearch_Click(object sender, EventArgs e)
        {
            string searchText = txtSearch.Text.Trim();
            if (string.IsNullOrEmpty(searchText)) return;
            treeView.SelectedNode = null;
            _firstMatchNode = null;
            matchCount = 0;
            CollapseAllNodes(treeView);

            FindAndExpandNodes(treeView,txtSearch.Text);

            // 如果有第一个匹配项，手动滚动到顶部
            if (_firstMatchNode != null && matchCount>1)
            {
                // 先确保节点可见（再次调用，避免 EnsureVisible 未生效）
                _firstMatchNode.EnsureVisible();

                // 使用反射或 API 设置滚动条位置到顶部
                ScrollTreeViewToTopLeft(treeView, _firstMatchNode);
            }
        }
        private TreeNode _firstMatchNode = null;
        int matchCount = 0;
        private void FindAndExpandNodes(System.Windows.Forms.TreeView treeView, string searchText)
        {
            if (string.IsNullOrEmpty(searchText)) return;
            foreach (var item in foundedNodes)
            {
                item.BackColor = Color.Transparent;
            }
            foundedNodes.Clear();
            foreach (TreeNode node in treeView.Nodes)
            {
                SearchNodeRecursively(node, searchText);
            }
        }
        List<TreeNode> foundedNodes=new List<TreeNode> ();
        private bool SearchNodeRecursively(TreeNode node, string searchText)
        {
            bool found = false;

            // 先检查当前节点是否匹配
            if (node.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                node.Expand(); // 展开当前节点
                node.EnsureVisible(); // 确保节点可见
                if (treeView.SelectedNode == null)
                {
                    treeView.SelectedNode = node; // 选中第一个匹配的节点
                }
                Color color = node.BackColor;
                node.BackColor = Color.LimeGreen;
                //var timer = new Timer() { Tag = node, Interval = 10000 };
                //timer.Tick += (object s, EventArgs e) => { ((TreeNode)((Timer)s).Tag).BackColor = Color.Transparent; ((Timer)s).BackgroundRefreshEnable = false; };
                //timer.Start();
                foundedNodes.Add(node);
                if (_firstMatchNode == null)
                {
                    _firstMatchNode = node; // 记录第一个匹配的节点
                }
                matchCount++;
                found = true;
            }

            // 再检查子节点
            foreach (TreeNode child in node.Nodes)
            {
                if (SearchNodeRecursively(child, searchText))
                {
                    matchCount++;
                    found = true;
                    node.Expand(); // 如果子节点匹配，父节点也要展开
                }
            }

            return found;
        }
        private void CollapseAllNodes(System.Windows.Forms.TreeView treeView)
        {
            foreach (TreeNode node in treeView.Nodes)
            {
                CollapseNodeRecursively(node);
            }
        }

        private void CollapseNodeRecursively(TreeNode node)
        {
            if (node.IsExpanded)
            {
                node.Collapse(); // 折叠当前节点
            }

            foreach (TreeNode child in node.Nodes)
            {
                CollapseNodeRecursively(child); // 递归处理子节点
            }
        }


        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

        private const int WM_VSCROLL = 0x0115;
        private const int WM_HSCROLL = 0x0114;
        private const int SB_TOP = 6;
        private const int SB_LEFT = 6;

        private void ScrollTreeViewToTopLeft(System.Windows.Forms.TreeView treeView, TreeNode node)
        {
            // 确保节点可见（垂直方向）
            node.EnsureVisible();

            // 垂直滚动到顶部
            SendMessage(treeView.Handle, WM_VSCROLL, (IntPtr)SB_TOP, IntPtr.Zero);

            // 水平滚动到最左边
            SendMessage(treeView.Handle, WM_HSCROLL, (IntPtr)SB_LEFT, IntPtr.Zero);
        }
        private void txtNode_DoubleClick(object sender, EventArgs e)
        {
            txtNode.SelectAll();
        }

        private void txtSearch_Click(object sender, EventArgs e)
        {
            txtSearch.SelectAll();
        }
    }

    [Serializable]
    public class TreeViewState
    {
        public string SelectedNodeKey { get; set; }
        public List<string> ExpandedNodeKeys { get; set; } = new List<string>();
        public List<string> AllNodes { get; set; } = new List<string>();
    }
}
