using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using MusicBeePlugin.Clouseau.Introspection;
using NLog;

namespace MusicBeePlugin.Clouseau.UI
{
    /// <summary>
    /// Form for inspecting event handlers attached to controls in the MusicBee application.
    /// Provides a TreeView of controls with their attached handlers and the ability to invoke/detach them.
    /// </summary>
    public class EventInspectorForm : Form
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        // Dark theme colors
        private static readonly Color DarkBackground = Color.FromArgb(30, 30, 30);
        private static readonly Color DarkPanel = Color.FromArgb(45, 45, 48);
        private static readonly Color DarkBorder = Color.FromArgb(67, 67, 70);
        private static readonly Color DarkText = Color.FromArgb(241, 241, 241);
        private static readonly Color DarkTextDim = Color.FromArgb(153, 153, 153);
        private static readonly Color DarkAccent = Color.FromArgb(0, 122, 204);
        private static readonly Color DarkHover = Color.FromArgb(62, 62, 64);
        private static readonly Color DarkWarning = Color.FromArgb(255, 200, 100);
        private static readonly Color DarkSuccess = Color.FromArgb(100, 200, 100);

        // UI Controls
        private SplitContainer _mainSplit;
        private TreeView _controlTree;
        private ListView _handlerList;
        private TextBox _searchBox;
        private Label _statusLabel;
        private Button _refreshButton;
        private Button _invokeButton;
        private Button _detachButton;
        private CheckBox _showAllControlsCheck;
        private Panel _detailPanel;
        private Label _detailLabel;

        // Data
        private readonly EventInspector _eventInspector;
        private readonly ReflectionExplorer _reflectionExplorer;
        private Form _targetForm;
        private List<ControlEventInfo> _allControlsWithHandlers;
        private EventHandlerDetail _selectedHandler;

        /// <summary>
        /// Creates a new EventInspectorForm.
        /// </summary>
        public EventInspectorForm() : this(null)
        {
        }

        /// <summary>
        /// Creates a new EventInspectorForm with a specific target form.
        /// </summary>
        /// <param name="targetForm">The form to inspect (null to auto-detect MusicBee main form).</param>
        public EventInspectorForm(Form targetForm)
        {
            _eventInspector = new EventInspector();
            _reflectionExplorer = new ReflectionExplorer();
            _targetForm = targetForm;

            InitializeComponents();
            LoadControlTree();
        }

        private void InitializeComponents()
        {
            // Form properties
            Text = "Event Handler Inspector";
            Size = new Size(1000, 700);
            MinimumSize = new Size(800, 500);
            StartPosition = FormStartPosition.CenterScreen;
            BackColor = DarkBackground;
            ForeColor = DarkText;
            SizeGripStyle = SizeGripStyle.Show;

            // Main split container (left: tree, right: details)
            _mainSplit = new SplitContainer
            {
                Dock = DockStyle.Fill,
                Orientation = Orientation.Vertical,
                SplitterWidth = 4,
                BackColor = DarkBackground
            };
            _mainSplit.Panel1.BackColor = DarkBackground;
            _mainSplit.Panel2.BackColor = DarkBackground;
            Shown += (s, e) => {
                try {
                    _mainSplit.SplitterDistance = 400;
                    _mainSplit.Panel1MinSize = 250;
                    _mainSplit.Panel2MinSize = 300;
                } catch { }
            };

            // Left panel - Control tree
            var leftPanel = new Panel
            {
                Dock = DockStyle.Fill,
                BackColor = DarkBackground
            };

            // Toolbar
            var toolbar = new Panel
            {
                Dock = DockStyle.Top,
                Height = 45,
                BackColor = DarkPanel
            };

            _refreshButton = CreateButton("Refresh", 10, 8, 80);
            _refreshButton.Height = 28;
            _refreshButton.Click += (s, e) => LoadControlTree();
            toolbar.Controls.Add(_refreshButton);

            _showAllControlsCheck = new CheckBox
            {
                Text = "Show All Controls",
                Location = new Point(90, 12),
                AutoSize = true,
                ForeColor = DarkText,
                Checked = false
            };
            _showAllControlsCheck.CheckedChanged += (s, e) => LoadControlTree();
            toolbar.Controls.Add(_showAllControlsCheck);

            leftPanel.Controls.Add(toolbar);

            // Search box
            _searchBox = new TextBox
            {
                Dock = DockStyle.Top,
                BackColor = DarkPanel,
                ForeColor = DarkText,
                BorderStyle = BorderStyle.FixedSingle,
                Font = new Font("Segoe UI", 9F),
                Height = 24
            };
            _searchBox.TextChanged += OnSearchChanged;
            _searchBox.GotFocus += (s, e) => { if (_searchBox.Text == "Search controls...") _searchBox.Text = ""; _searchBox.ForeColor = DarkText; };
            _searchBox.LostFocus += (s, e) => { if (string.IsNullOrEmpty(_searchBox.Text)) { _searchBox.Text = "Search controls..."; _searchBox.ForeColor = DarkTextDim; } };
            _searchBox.Text = "Search controls...";
            _searchBox.ForeColor = DarkTextDim;
            leftPanel.Controls.Add(_searchBox);

            // Tree view
            _controlTree = new TreeView
            {
                Dock = DockStyle.Fill,
                BackColor = DarkPanel,
                ForeColor = DarkText,
                BorderStyle = BorderStyle.None,
                Font = new Font("Consolas", 9F),
                ShowLines = true,
                ShowPlusMinus = true,
                ShowRootLines = true,
                FullRowSelect = true
            };
            _controlTree.AfterSelect += OnControlSelected;
            _controlTree.NodeMouseDoubleClick += OnControlDoubleClick;
            leftPanel.Controls.Add(_controlTree);

            _mainSplit.Panel1.Controls.Add(leftPanel);

            // Right panel - Handler details
            var rightPanel = new Panel
            {
                Dock = DockStyle.Fill,
                BackColor = DarkBackground
            };

            // WinForms Dock order: add Bottom first, then Fill, then Top last

            // Detail panel (Bottom - add first)
            _detailPanel = new Panel
            {
                Dock = DockStyle.Bottom,
                Height = 140,
                BackColor = DarkPanel
            };

            var detailTitleLabel = new Label
            {
                Text = "Handler Details",
                Location = new Point(10, 10),
                AutoSize = true,
                ForeColor = DarkText,
                Font = new Font("Segoe UI", 9F, FontStyle.Bold)
            };
            _detailPanel.Controls.Add(detailTitleLabel);

            _detailLabel = new Label
            {
                Location = new Point(10, 35),
                Size = new Size(380, 95),
                ForeColor = DarkTextDim,
                Font = new Font("Consolas", 9F),
                Text = "Select a handler to view details"
            };
            _detailPanel.Controls.Add(_detailLabel);

            rightPanel.Controls.Add(_detailPanel);

            // Handler list (Fill - add second)
            _handlerList = new ListView
            {
                Dock = DockStyle.Fill,
                View = View.Details,
                FullRowSelect = true,
                GridLines = true,
                BackColor = DarkPanel,
                ForeColor = DarkText,
                BorderStyle = BorderStyle.None,
                Font = new Font("Consolas", 9F)
            };
            _handlerList.Columns.Add("Event", 100);
            _handlerList.Columns.Add("Handler Method", 200);
            _handlerList.Columns.Add("Target Type", 200);
            _handlerList.Columns.Add("Access", 60);
            _handlerList.SelectedIndexChanged += OnHandlerSelected;
            _handlerList.DoubleClick += OnHandlerDoubleClick;

            rightPanel.Controls.Add(_handlerList);

            // Handler list toolbar (Top - add last so it appears at top)
            var handlerToolbar = new Panel
            {
                Dock = DockStyle.Top,
                Height = 55,
                BackColor = DarkPanel
            };

            _invokeButton = CreateButton("Invoke", 10, 10, 80);
            _invokeButton.Height = 30;
            _invokeButton.BackColor = Color.FromArgb(70, 130, 180);
            _invokeButton.Click += OnInvokeHandler;
            _invokeButton.Enabled = false;
            handlerToolbar.Controls.Add(_invokeButton);

            _detachButton = CreateButton("Detach", 100, 10, 90);
            _detachButton.Height = 30;
            _detachButton.BackColor = Color.FromArgb(180, 80, 80);
            _detachButton.Click += OnDetachHandler;
            _detachButton.Enabled = false;
            handlerToolbar.Controls.Add(_detachButton);

            var handlerToolbarLabel = new Label
            {
                Text = "Event Handlers",
                Location = new Point(195, 16),
                AutoSize = true,
                ForeColor = DarkText,
                Font = new Font("Segoe UI", 9F, FontStyle.Bold)
            };
            handlerToolbar.Controls.Add(handlerToolbarLabel);

            rightPanel.Controls.Add(handlerToolbar);

            _mainSplit.Panel2.Controls.Add(rightPanel);

            // Status bar with resize grip
            var statusStrip = new StatusStrip
            {
                BackColor = DarkPanel,
                SizingGrip = true
            };
            var statusLabel = new ToolStripStatusLabel("Ready")
            {
                ForeColor = DarkTextDim,
                Spring = true,
                TextAlign = ContentAlignment.MiddleLeft
            };
            statusStrip.Items.Add(statusLabel);
            _statusLabel = new Label { Text = "Ready" }; // Keep for compatibility

            Controls.Add(_mainSplit);
            Controls.Add(statusStrip);
        }

        private Button CreateButton(string text, int x, int y, int width)
        {
            var button = new Button
            {
                Text = text,
                Location = new Point(x, y),
                Size = new Size(width, 25),
                BackColor = DarkPanel,
                ForeColor = DarkText,
                FlatStyle = FlatStyle.Flat
            };
            button.FlatAppearance.BorderColor = DarkBorder;
            button.FlatAppearance.MouseOverBackColor = DarkHover;
            return button;
        }

        private void LoadControlTree()
        {
            _controlTree.Nodes.Clear();
            _handlerList.Items.Clear();
            _selectedHandler = null;
            UpdateButtons();

            try
            {
                // Find target form if not specified
                if (_targetForm == null || _targetForm.IsDisposed)
                {
                    _targetForm = _reflectionExplorer.FindMainForm();
                }

                if (_targetForm == null)
                {
                    _controlTree.Nodes.Add("Could not find MusicBee main form");
                    _statusLabel.Text = "Error: Could not find target form";
                    return;
                }

                // Get all controls with handlers
                _allControlsWithHandlers = _eventInspector.GetAllControlsWithHandlers(_targetForm);

                // Build tree
                var rootNode = _controlTree.Nodes.Add(_targetForm.Text ?? _targetForm.Name ?? "Main Form");
                rootNode.Tag = _targetForm;
                rootNode.ForeColor = DarkAccent;

                if (_showAllControlsCheck.Checked)
                {
                    // Show full control tree
                    BuildFullControlTree(rootNode, _targetForm);
                }
                else
                {
                    // Show only controls with handlers
                    foreach (var controlInfo in _allControlsWithHandlers.OrderBy(c => c.Depth).ThenBy(c => c.ControlName))
                    {
                        var nodeText = $"{controlInfo.ControlName} ({controlInfo.ControlTypeName}) [{controlInfo.EventCount}]";
                        var node = rootNode.Nodes.Add(nodeText);
                        node.Tag = controlInfo;
                        node.ForeColor = DarkSuccess;
                    }
                }

                rootNode.Expand();

                // Get statistics
                var stats = _eventInspector.GetEventStatistics(_targetForm);
                _statusLabel.Text = $"Controls: {stats.TotalControlsWithHandlers} | Handlers: {stats.TotalHandlers}";
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error loading control tree");
                _controlTree.Nodes.Add($"Error: {ex.Message}");
                _statusLabel.Text = $"Error: {ex.Message}";
            }
        }

        private void BuildFullControlTree(TreeNode parentNode, Control parentControl)
        {
            foreach (Control child in parentControl.Controls)
            {
                var handlers = _eventInspector.GetEventHandlers(child);
                var name = string.IsNullOrEmpty(child.Name) ? $"[{child.GetType().Name}]" : child.Name;
                var nodeText = handlers.Count > 0 ? $"{name} ({child.GetType().Name}) [{handlers.Count}]" : $"{name} ({child.GetType().Name})";

                var node = parentNode.Nodes.Add(nodeText);

                if (handlers.Count > 0)
                {
                    node.Tag = new ControlEventInfo
                    {
                        Control = child,
                        ControlName = name,
                        ControlType = child.GetType(),
                        ControlTypeName = child.GetType().Name,
                        EventHandlers = handlers,
                        EventCount = handlers.Count
                    };
                    node.ForeColor = DarkSuccess;
                }
                else
                {
                    node.Tag = child;
                    node.ForeColor = DarkTextDim;
                }

                if (child.Controls.Count > 0)
                {
                    BuildFullControlTree(node, child);
                }
            }
        }

        private void OnSearchChanged(object sender, EventArgs e)
        {
            var searchText = _searchBox.Text?.ToLowerInvariant();
            if (string.IsNullOrEmpty(searchText) || searchText == "search controls...")
                return;

            foreach (TreeNode node in GetAllNodes(_controlTree.Nodes))
            {
                if (node.Text.ToLowerInvariant().Contains(searchText))
                {
                    _controlTree.SelectedNode = node;
                    node.EnsureVisible();
                    break;
                }
            }
        }

        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 OnControlSelected(object sender, TreeViewEventArgs e)
        {
            _handlerList.Items.Clear();
            _selectedHandler = null;
            UpdateButtons();

            var tag = e.Node?.Tag;
            if (tag == null)
                return;

            List<EventHandlerDetail> handlers = null;

            if (tag is ControlEventInfo controlInfo)
            {
                handlers = controlInfo.EventHandlers;
            }
            else if (tag is Control control)
            {
                handlers = _eventInspector.GetEventHandlers(control);
            }

            if (handlers == null || handlers.Count == 0)
            {
                _detailLabel.Text = "No event handlers attached to this control";
                return;
            }

            foreach (var handler in handlers)
            {
                var item = new ListViewItem(new[]
                {
                    handler.EventName,
                    handler.HandlerMethodName ?? "?",
                    handler.TargetTypeName ?? "?",
                    handler.IsPrivate ? "private" : "public"
                });
                item.Tag = handler;
                item.ForeColor = handler.IsPrivate ? DarkWarning : DarkText;
                item.BackColor = DarkPanel;
                _handlerList.Items.Add(item);
            }

            _statusLabel.Text = $"Showing {handlers.Count} handler(s) for {e.Node.Text}";
        }

        private void OnControlDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            // Expand/collapse or highlight control
            var tag = e.Node?.Tag;
            if (tag is ControlEventInfo controlInfo && controlInfo.Control != null)
            {
                HighlightControl(controlInfo.Control);
            }
            else if (tag is Control control)
            {
                HighlightControl(control);
            }
        }

        private void HighlightControl(Control control)
        {
            try
            {
                // Briefly highlight the control
                var originalColor = control.BackColor;
                control.BackColor = Color.Yellow;
                control.Refresh();

                var timer = new Timer { Interval = 500 };
                timer.Tick += (s, e) =>
                {
                    control.BackColor = originalColor;
                    timer.Stop();
                    timer.Dispose();
                };
                timer.Start();
            }
            catch (Exception ex)
            {
                Logger.Debug($"Could not highlight control: {ex.Message}");
            }
        }

        private void OnHandlerSelected(object sender, EventArgs e)
        {
            _selectedHandler = null;
            UpdateButtons();

            if (_handlerList.SelectedItems.Count == 0)
            {
                _detailLabel.Text = "Select a handler to view details";
                return;
            }

            _selectedHandler = _handlerList.SelectedItems[0].Tag as EventHandlerDetail;
            if (_selectedHandler != null)
            {
                _detailLabel.Text = _selectedHandler.GetDetailedDescription();
                UpdateButtons();
            }
        }

        private void OnHandlerDoubleClick(object sender, EventArgs e)
        {
            if (_selectedHandler != null)
            {
                OnInvokeHandler(sender, e);
            }
        }

        private void UpdateButtons()
        {
            _invokeButton.Enabled = _selectedHandler != null;
            _detachButton.Enabled = _selectedHandler != null;
        }

        private void OnInvokeHandler(object sender, EventArgs e)
        {
            if (_selectedHandler == null)
                return;

            var result = MessageBox.Show(
                $"Invoke event handler?\n\n" +
                $"Event: {_selectedHandler.EventName}\n" +
                $"Handler: {_selectedHandler.TargetTypeName}.{_selectedHandler.HandlerMethodName}()\n\n" +
                $"This may trigger UI actions in MusicBee.",
                "Confirm Invoke",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question);

            if (result != DialogResult.Yes)
                return;

            try
            {
                // Get the control for sender
                object senderControl = null;
                var selectedNode = _controlTree.SelectedNode;
                if (selectedNode?.Tag is ControlEventInfo controlInfo)
                {
                    senderControl = controlInfo.Control;
                }
                else if (selectedNode?.Tag is Control control)
                {
                    senderControl = control;
                }

                _eventInspector.InvokeHandler(_selectedHandler, senderControl, EventArgs.Empty);

                _statusLabel.Text = $"Invoked: {_selectedHandler.HandlerMethodName}";
                Logger.Info($"User invoked handler: {_selectedHandler}");
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error invoking handler");
                MessageBox.Show(
                    $"Error invoking handler:\n{ex.Message}",
                    "Invoke Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                _statusLabel.Text = $"Error: {ex.Message}";
            }
        }

        private void OnDetachHandler(object sender, EventArgs e)
        {
            if (_selectedHandler == null)
                return;

            var result = MessageBox.Show(
                $"WARNING: Detach event handler?\n\n" +
                $"Event: {_selectedHandler.EventName}\n" +
                $"Handler: {_selectedHandler.TargetTypeName}.{_selectedHandler.HandlerMethodName}()\n\n" +
                $"This may break MusicBee functionality!\n" +
                $"The change will persist until MusicBee is restarted.",
                "Confirm Detach",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning);

            if (result != DialogResult.Yes)
                return;

            try
            {
                // Get the control
                Control targetControl = null;
                var selectedNode = _controlTree.SelectedNode;
                if (selectedNode?.Tag is ControlEventInfo controlInfo)
                {
                    targetControl = controlInfo.Control;
                }
                else if (selectedNode?.Tag is Control control)
                {
                    targetControl = control;
                }

                if (targetControl == null)
                {
                    MessageBox.Show("Could not find target control", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (_eventInspector.DetachEventHandler(targetControl, _selectedHandler))
                {
                    _statusLabel.Text = $"Detached: {_selectedHandler.HandlerMethodName}";
                    Logger.Warn($"User detached handler: {_selectedHandler}");

                    // Refresh the display
                    LoadControlTree();
                }
                else
                {
                    MessageBox.Show("Failed to detach handler", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Error detaching handler");
                MessageBox.Show(
                    $"Error detaching handler:\n{ex.Message}",
                    "Detach Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
        }
    }
}
