using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using MusicBeePlugin.Clouseau.Introspection;
using NLog;

namespace MusicBeePlugin.Clouseau.UI
{
    /// <summary>
    /// Transparent overlay form that highlights UI elements in real-time when hovering.
    /// Shows control properties and parent chain in an info panel.
    /// </summary>
    public class SpyOverlayForm : Form
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        #region Win32 API for Click-Through Transparency

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll")]
        private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);

        private const int GWL_EXSTYLE = -20;
        private const int WS_EX_LAYERED = 0x80000;
        private const int WS_EX_TRANSPARENT = 0x20;
        private const int WS_EX_TOOLWINDOW = 0x80;
        private const int WS_EX_NOACTIVATE = 0x08000000;
        private const uint LWA_ALPHA = 0x2;

        #endregion

        // Configuration
        private const int UPDATE_INTERVAL_MS = 50; // ~20fps
        private const int HIGHLIGHT_BORDER_WIDTH = 3;
        private const int INFO_PANEL_WIDTH = 320;
        private const int INFO_PANEL_MAX_HEIGHT = 280;
        private const int INFO_PANEL_OFFSET_X = 15;
        private const int INFO_PANEL_OFFSET_Y = 15;

        // Colors
        private static readonly Color HighlightColor = Color.FromArgb(0, 174, 255);
        private static readonly Color HighlightColorAlt = Color.FromArgb(255, 128, 0);
        private static readonly Color InfoPanelBackground = Color.FromArgb(230, 30, 30, 30);
        private static readonly Color InfoPanelBorder = Color.FromArgb(255, 0, 174, 255);
        private static readonly Color InfoPanelText = Color.FromArgb(255, 241, 241, 241);
        private static readonly Color InfoPanelTextDim = Color.FromArgb(255, 153, 153, 153);
        private static readonly Color InfoPanelHeader = Color.FromArgb(255, 100, 200, 255);

        // Components
        private Timer _updateTimer;
        private SpyInfoPanel _infoPanel;

        // State
        private IntPtr _lastHighlightedHandle;
        private Rectangle _lastHighlightRect;
        private SpyControlInfo _currentControlInfo;
        private List<string> _currentParentChain;
        private bool _isActive;
        private int _currentProcessId;
        private IntPtr _targetWindowHandle;

        /// <summary>
        /// Event raised when the spy mode is toggled.
        /// </summary>
        public event EventHandler<bool> SpyModeChanged;

        /// <summary>
        /// Event raised when a control is selected (clicked while spy mode is active).
        /// </summary>
        public event EventHandler<SpyControlInfo> ControlSelected;

        /// <summary>
        /// Gets whether spy mode is currently active.
        /// </summary>
        public bool IsSpyModeActive => _isActive;

        /// <summary>
        /// Gets or sets the window handle to restrict spying to.
        /// If set, only controls within this window will be highlighted.
        /// </summary>
        public IntPtr TargetWindowHandle
        {
            get => _targetWindowHandle;
            set => _targetWindowHandle = value;
        }

        /// <summary>
        /// Creates a new SpyOverlayForm.
        /// </summary>
        public SpyOverlayForm()
        {
            InitializeForm();
            InitializeInfoPanel();
            InitializeTimer();

            _currentProcessId = System.Diagnostics.Process.GetCurrentProcess().Id;
        }

        /// <summary>
        /// Initializes the overlay form properties.
        /// </summary>
        private void InitializeForm()
        {
            // Form properties for transparent overlay
            FormBorderStyle = FormBorderStyle.None;
            ShowInTaskbar = false;
            TopMost = true;
            StartPosition = FormStartPosition.Manual;
            BackColor = Color.Magenta;
            TransparencyKey = Color.Magenta;
            DoubleBuffered = true;

            // Cover all screens
            var bounds = SystemInformation.VirtualScreen;
            Location = bounds.Location;
            Size = bounds.Size;

            // Custom painting
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.UserPaint |
                     ControlStyles.OptimizedDoubleBuffer, true);
        }

        /// <summary>
        /// Sets up extended window styles for click-through transparency.
        /// </summary>
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);

            // Make window click-through and non-activating
            int exStyle = GetWindowLong(Handle, GWL_EXSTYLE);
            exStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE;
            SetWindowLong(Handle, GWL_EXSTYLE, exStyle);
        }

        /// <summary>
        /// Prevents the overlay from gaining focus.
        /// </summary>
        protected override bool ShowWithoutActivation => true;

        /// <summary>
        /// Initializes the info panel control.
        /// </summary>
        private void InitializeInfoPanel()
        {
            _infoPanel = new SpyInfoPanel
            {
                Visible = false,
                Size = new Size(INFO_PANEL_WIDTH, INFO_PANEL_MAX_HEIGHT)
            };
            Controls.Add(_infoPanel);
        }

        /// <summary>
        /// Initializes the update timer.
        /// </summary>
        private void InitializeTimer()
        {
            _updateTimer = new Timer
            {
                Interval = UPDATE_INTERVAL_MS
            };
            _updateTimer.Tick += OnUpdateTimerTick;
        }

        /// <summary>
        /// Starts spy mode - shows overlay and begins tracking.
        /// </summary>
        public void StartSpyMode()
        {
            if (_isActive)
                return;

            _isActive = true;
            _lastHighlightedHandle = IntPtr.Zero;
            _lastHighlightRect = Rectangle.Empty;

            // Resize to cover all screens
            var bounds = SystemInformation.VirtualScreen;
            Location = bounds.Location;
            Size = bounds.Size;

            Show();
            _updateTimer.Start();

            SpyModeChanged?.Invoke(this, true);
            Logger.Info("Spy mode started");
        }

        /// <summary>
        /// Stops spy mode - hides overlay and stops tracking.
        /// </summary>
        public void StopSpyMode()
        {
            if (!_isActive)
                return;

            _isActive = false;
            _updateTimer.Stop();
            Hide();

            _lastHighlightedHandle = IntPtr.Zero;
            _lastHighlightRect = Rectangle.Empty;
            _currentControlInfo = null;
            _currentParentChain = null;

            SpyModeChanged?.Invoke(this, false);
            Logger.Info("Spy mode stopped");
        }

        /// <summary>
        /// Toggles spy mode on/off.
        /// </summary>
        public void ToggleSpyMode()
        {
            if (_isActive)
                StopSpyMode();
            else
                StartSpyMode();
        }

        /// <summary>
        /// Timer callback - updates highlighted control based on cursor position.
        /// </summary>
        private void OnUpdateTimerTick(object sender, EventArgs e)
        {
            if (!_isActive)
                return;

            try
            {
                // Get cursor position
                Point cursorPos = SpyHelper.GetCursorPosition();

                // Get window at cursor
                IntPtr hwnd = SpyHelper.GetDeepestWindowAtPoint(cursorPos);

                // Skip if cursor is over our own windows
                if (IsOwnWindow(hwnd))
                {
                    return;
                }

                // Filter to target window if specified
                if (_targetWindowHandle != IntPtr.Zero)
                {
                    IntPtr root = SpyHelper.GetRootWindow(hwnd);
                    if (root != _targetWindowHandle && hwnd != _targetWindowHandle)
                    {
                        // Outside target - clear highlight
                        if (_lastHighlightedHandle != IntPtr.Zero)
                        {
                            _lastHighlightedHandle = IntPtr.Zero;
                            _lastHighlightRect = Rectangle.Empty;
                            _currentControlInfo = null;
                            _infoPanel.Visible = false;
                            Invalidate();
                        }
                        return;
                    }
                }

                // Check if we're still over the same control
                if (hwnd == _lastHighlightedHandle)
                {
                    // Just update info panel position
                    UpdateInfoPanelPosition(cursorPos);
                    return;
                }

                // New control - get info
                _lastHighlightedHandle = hwnd;
                _currentControlInfo = SpyHelper.GetControlInfo(hwnd);

                if (_currentControlInfo != null)
                {
                    _lastHighlightRect = _currentControlInfo.ScreenBounds;

                    // Get parent chain
                    if (_currentControlInfo.ManagedControl != null)
                    {
                        _currentParentChain = SpyHelper.GetParentChain(_currentControlInfo.ManagedControl);
                    }
                    else
                    {
                        _currentParentChain = new List<string>();
                        var parentChainInfo = SpyHelper.GetParentChain(hwnd);
                        foreach (var info in parentChainInfo)
                        {
                            _currentParentChain.Add($"{info.DisplayName} ({info.DisplayTypeName})");
                        }
                    }

                    // Update info panel
                    _infoPanel.SetControlInfo(_currentControlInfo, _currentParentChain);
                    UpdateInfoPanelPosition(cursorPos);
                    _infoPanel.Visible = true;
                }
                else
                {
                    _lastHighlightRect = Rectangle.Empty;
                    _infoPanel.Visible = false;
                }

                // Trigger repaint
                Invalidate();
            }
            catch (Exception ex)
            {
                Logger.Trace($"Error in spy update: {ex.Message}");
            }
        }

        /// <summary>
        /// Checks if a window handle belongs to this overlay or the info panel.
        /// </summary>
        private bool IsOwnWindow(IntPtr hwnd)
        {
            if (hwnd == IntPtr.Zero)
                return false;

            if (hwnd == Handle)
                return true;

            if (_infoPanel != null && hwnd == _infoPanel.Handle)
                return true;

            // Check if it's a child of our form
            Control ctrl = Control.FromHandle(hwnd);
            if (ctrl != null)
            {
                Control parent = ctrl;
                while (parent != null)
                {
                    if (parent == this)
                        return true;
                    parent = parent.Parent;
                }
            }

            return false;
        }

        /// <summary>
        /// Updates the info panel position near the cursor.
        /// </summary>
        private void UpdateInfoPanelPosition(Point cursorPos)
        {
            // Convert to form coordinates
            Point formPos = PointToClient(cursorPos);

            // Position info panel to the right and below cursor
            int x = formPos.X + INFO_PANEL_OFFSET_X;
            int y = formPos.Y + INFO_PANEL_OFFSET_Y;

            // Ensure panel stays within bounds
            var virtualScreen = SystemInformation.VirtualScreen;
            var panelBounds = new Rectangle(
                cursorPos.X + INFO_PANEL_OFFSET_X,
                cursorPos.Y + INFO_PANEL_OFFSET_Y,
                _infoPanel.Width,
                _infoPanel.Height);

            // Flip horizontally if needed
            if (panelBounds.Right > virtualScreen.Right)
            {
                x = formPos.X - INFO_PANEL_OFFSET_X - _infoPanel.Width;
            }

            // Flip vertically if needed
            if (panelBounds.Bottom > virtualScreen.Bottom)
            {
                y = formPos.Y - INFO_PANEL_OFFSET_Y - _infoPanel.Height;
            }

            _infoPanel.Location = new Point(x, y);
        }

        /// <summary>
        /// Paints the highlight rectangle around the current control.
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            if (!_isActive || _lastHighlightRect.IsEmpty)
                return;

            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // Convert screen rect to form coordinates
            Rectangle highlightRect = new Rectangle(
                _lastHighlightRect.X - Location.X,
                _lastHighlightRect.Y - Location.Y,
                _lastHighlightRect.Width,
                _lastHighlightRect.Height);

            // Draw highlight border
            using (var pen = new Pen(HighlightColor, HIGHLIGHT_BORDER_WIDTH))
            {
                pen.DashStyle = DashStyle.Solid;
                g.DrawRectangle(pen, highlightRect);
            }

            // Draw inner glow effect
            using (var pen = new Pen(Color.FromArgb(100, HighlightColor), 1))
            {
                var innerRect = highlightRect;
                innerRect.Inflate(-HIGHLIGHT_BORDER_WIDTH, -HIGHLIGHT_BORDER_WIDTH);
                if (innerRect.Width > 0 && innerRect.Height > 0)
                {
                    g.DrawRectangle(pen, innerRect);
                }
            }

            // Draw corner markers
            DrawCornerMarkers(g, highlightRect, HighlightColor);
        }

        /// <summary>
        /// Draws corner markers on the highlight rectangle.
        /// </summary>
        private void DrawCornerMarkers(Graphics g, Rectangle rect, Color color)
        {
            int markerSize = 8;

            using (var brush = new SolidBrush(color))
            {
                // Top-left
                g.FillRectangle(brush, rect.Left - 1, rect.Top - 1, markerSize, 3);
                g.FillRectangle(brush, rect.Left - 1, rect.Top - 1, 3, markerSize);

                // Top-right
                g.FillRectangle(brush, rect.Right - markerSize + 1, rect.Top - 1, markerSize, 3);
                g.FillRectangle(brush, rect.Right - 2, rect.Top - 1, 3, markerSize);

                // Bottom-left
                g.FillRectangle(brush, rect.Left - 1, rect.Bottom - 2, markerSize, 3);
                g.FillRectangle(brush, rect.Left - 1, rect.Bottom - markerSize + 1, 3, markerSize);

                // Bottom-right
                g.FillRectangle(brush, rect.Right - markerSize + 1, rect.Bottom - 2, markerSize, 3);
                g.FillRectangle(brush, rect.Right - 2, rect.Bottom - markerSize + 1, 3, markerSize);
            }
        }

        /// <summary>
        /// Cleanup on disposal.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _updateTimer?.Stop();
                _updateTimer?.Dispose();
                _infoPanel?.Dispose();
            }
            base.Dispose(disposing);
        }
    }

    /// <summary>
    /// Info panel that displays control details during spy mode.
    /// </summary>
    internal class SpyInfoPanel : Control
    {
        private static readonly Color BackgroundColor = Color.FromArgb(245, 30, 30, 30);
        private static readonly Color BorderColor = Color.FromArgb(255, 0, 174, 255);
        private static readonly Color TextColor = Color.FromArgb(255, 241, 241, 241);
        private static readonly Color TextDimColor = Color.FromArgb(255, 153, 153, 153);
        private static readonly Color HeaderColor = Color.FromArgb(255, 100, 200, 255);
        private static readonly Color TypeColor = Color.FromArgb(255, 78, 201, 176);
        private static readonly Color ValueColor = Color.FromArgb(255, 206, 145, 120);

        private SpyControlInfo _controlInfo;
        private List<string> _parentChain;
        private Font _headerFont;
        private Font _normalFont;
        private Font _smallFont;

        public SpyInfoPanel()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.UserPaint |
                     ControlStyles.OptimizedDoubleBuffer, true);

            _headerFont = new Font("Segoe UI", 10F, FontStyle.Bold);
            _normalFont = new Font("Consolas", 9F);
            _smallFont = new Font("Consolas", 8F);
        }

        /// <summary>
        /// Sets the control info to display.
        /// </summary>
        public void SetControlInfo(SpyControlInfo info, List<string> parentChain)
        {
            _controlInfo = info;
            _parentChain = parentChain;
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            // Draw background with slight transparency
            using (var brush = new SolidBrush(BackgroundColor))
            {
                g.FillRectangle(brush, ClientRectangle);
            }

            // Draw border
            using (var pen = new Pen(BorderColor, 2))
            {
                g.DrawRectangle(pen, 1, 1, Width - 3, Height - 3);
            }

            if (_controlInfo == null)
                return;

            int y = 8;
            int leftMargin = 10;
            int rightMargin = Width - 10;

            // Draw header with type name
            using (var brush = new SolidBrush(HeaderColor))
            {
                string typeName = _controlInfo.IsManagedControl
                    ? _controlInfo.DisplayTypeName
                    : _controlInfo.ClassName;
                g.DrawString(typeName, _headerFont, brush, leftMargin, y);
            }
            y += 22;

            // Draw separator
            using (var pen = new Pen(Color.FromArgb(100, BorderColor)))
            {
                g.DrawLine(pen, leftMargin, y, rightMargin, y);
            }
            y += 8;

            // Draw properties
            y = DrawProperty(g, "Name:", _controlInfo.DisplayName, leftMargin, y);

            if (!string.IsNullOrEmpty(_controlInfo.WindowText) && _controlInfo.WindowText.Length < 40)
            {
                var displayText = _controlInfo.WindowText.Replace("\r", "").Replace("\n", " ");
                if (displayText.Length > 35)
                    displayText = displayText.Substring(0, 32) + "...";
                y = DrawProperty(g, "Text:", displayText, leftMargin, y);
            }

            y = DrawProperty(g, "Size:",
                $"{_controlInfo.ScreenBounds.Width} x {_controlInfo.ScreenBounds.Height}",
                leftMargin, y);

            y = DrawProperty(g, "Location:",
                $"{_controlInfo.ScreenBounds.X}, {_controlInfo.ScreenBounds.Y}",
                leftMargin, y);

            y = DrawProperty(g, "Visible:", _controlInfo.IsVisible.ToString(), leftMargin, y);
            y = DrawProperty(g, "Enabled:", _controlInfo.IsEnabled.ToString(), leftMargin, y);

            // Draw handle
            y = DrawProperty(g, "Handle:",
                $"0x{_controlInfo.Handle.ToInt64():X8}",
                leftMargin, y);

            y += 4;

            // Draw parent chain header
            if (_parentChain != null && _parentChain.Count > 1)
            {
                using (var pen = new Pen(Color.FromArgb(100, BorderColor)))
                {
                    g.DrawLine(pen, leftMargin, y, rightMargin, y);
                }
                y += 6;

                using (var brush = new SolidBrush(TextDimColor))
                {
                    g.DrawString("Parent Chain:", _smallFont, brush, leftMargin, y);
                }
                y += 14;

                // Draw parent chain (skip first item which is current control)
                for (int i = 1; i < Math.Min(_parentChain.Count, 5); i++)
                {
                    string prefix = new string(' ', (i - 1) * 2) + "> ";
                    string text = _parentChain[i];
                    if (text.Length > 35)
                        text = text.Substring(0, 32) + "...";

                    using (var brush = new SolidBrush(TextDimColor))
                    {
                        g.DrawString(prefix + text, _smallFont, brush, leftMargin, y);
                    }
                    y += 13;
                }

                if (_parentChain.Count > 5)
                {
                    using (var brush = new SolidBrush(TextDimColor))
                    {
                        g.DrawString($"  ... +{_parentChain.Count - 5} more", _smallFont, brush, leftMargin, y);
                    }
                }
            }
        }

        /// <summary>
        /// Draws a property label and value.
        /// </summary>
        private int DrawProperty(Graphics g, string label, string value, int x, int y)
        {
            using (var labelBrush = new SolidBrush(TextDimColor))
            using (var valueBrush = new SolidBrush(ValueColor))
            {
                g.DrawString(label, _normalFont, labelBrush, x, y);

                var labelSize = g.MeasureString(label, _normalFont);
                g.DrawString(value, _normalFont, valueBrush, x + labelSize.Width + 4, y);
            }
            return y + 16;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _headerFont?.Dispose();
                _normalFont?.Dispose();
                _smallFont?.Dispose();
            }
            base.Dispose(disposing);
        }
    }

    /// <summary>
    /// Floating toolbar for spy mode controls.
    /// </summary>
    public class SpyToolbar : Form
    {
        private static readonly Color DarkBackground = Color.FromArgb(45, 45, 48);
        private static readonly Color DarkBorder = Color.FromArgb(0, 174, 255);
        private static readonly Color DarkText = Color.FromArgb(241, 241, 241);

        private Button _toggleButton;
        private Button _closeButton;
        private Label _statusLabel;
        private SpyOverlayForm _overlayForm;
        private bool _isDragging;
        private Point _dragOffset;

        /// <summary>
        /// Event raised when the toolbar is closed.
        /// </summary>
        public event EventHandler ToolbarClosed;

        /// <summary>
        /// Gets the spy overlay form managed by this toolbar.
        /// </summary>
        public SpyOverlayForm OverlayForm => _overlayForm;

        /// <summary>
        /// Creates a new SpyToolbar.
        /// </summary>
        /// <param name="targetWindow">Optional window handle to restrict spying to.</param>
        public SpyToolbar(IntPtr targetWindow = default)
        {
            InitializeForm();
            InitializeControls();

            _overlayForm = new SpyOverlayForm
            {
                TargetWindowHandle = targetWindow
            };
            _overlayForm.SpyModeChanged += OnSpyModeChanged;
        }

        private void InitializeForm()
        {
            FormBorderStyle = FormBorderStyle.None;
            ShowInTaskbar = false;
            TopMost = true;
            StartPosition = FormStartPosition.Manual;
            BackColor = DarkBackground;
            Size = new Size(200, 32);
            Padding = new Padding(2);

            // Position at top-right of primary screen
            var screen = Screen.PrimaryScreen.WorkingArea;
            Location = new Point(screen.Right - Width - 20, screen.Top + 20);

            // Enable dragging
            MouseDown += OnFormMouseDown;
            MouseMove += OnFormMouseMove;
            MouseUp += OnFormMouseUp;
        }

        private void InitializeControls()
        {
            // Toggle button
            _toggleButton = new Button
            {
                Text = "Start Spy",
                Location = new Point(4, 4),
                Size = new Size(80, 24),
                FlatStyle = FlatStyle.Flat,
                BackColor = Color.FromArgb(60, 60, 60),
                ForeColor = DarkText,
                Font = new Font("Segoe UI", 8F)
            };
            _toggleButton.FlatAppearance.BorderColor = DarkBorder;
            _toggleButton.FlatAppearance.MouseOverBackColor = Color.FromArgb(80, 80, 80);
            _toggleButton.Click += OnToggleClick;
            Controls.Add(_toggleButton);

            // Status label
            _statusLabel = new Label
            {
                Text = "Off",
                Location = new Point(88, 8),
                Size = new Size(70, 16),
                ForeColor = Color.Gray,
                Font = new Font("Segoe UI", 8F),
                TextAlign = ContentAlignment.MiddleCenter
            };
            Controls.Add(_statusLabel);

            // Close button
            _closeButton = new Button
            {
                Text = "X",
                Location = new Point(Width - 28, 4),
                Size = new Size(24, 24),
                FlatStyle = FlatStyle.Flat,
                BackColor = Color.FromArgb(60, 60, 60),
                ForeColor = DarkText,
                Font = new Font("Segoe UI", 8F, FontStyle.Bold)
            };
            _closeButton.FlatAppearance.BorderSize = 0;
            _closeButton.FlatAppearance.MouseOverBackColor = Color.FromArgb(200, 50, 50);
            _closeButton.Click += OnCloseClick;
            Controls.Add(_closeButton);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            // Draw border
            using (var pen = new Pen(DarkBorder, 1))
            {
                e.Graphics.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);
            }
        }

        private void OnToggleClick(object sender, EventArgs e)
        {
            _overlayForm.ToggleSpyMode();
        }

        private void OnSpyModeChanged(object sender, bool isActive)
        {
            if (isActive)
            {
                _toggleButton.Text = "Stop Spy";
                _toggleButton.BackColor = Color.FromArgb(0, 100, 150);
                _statusLabel.Text = "Active";
                _statusLabel.ForeColor = Color.FromArgb(0, 174, 255);
            }
            else
            {
                _toggleButton.Text = "Start Spy";
                _toggleButton.BackColor = Color.FromArgb(60, 60, 60);
                _statusLabel.Text = "Off";
                _statusLabel.ForeColor = Color.Gray;
            }
        }

        private void OnCloseClick(object sender, EventArgs e)
        {
            _overlayForm.StopSpyMode();
            ToolbarClosed?.Invoke(this, EventArgs.Empty);
            Close();
        }

        private void OnFormMouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _isDragging = true;
                _dragOffset = e.Location;
            }
        }

        private void OnFormMouseMove(object sender, MouseEventArgs e)
        {
            if (_isDragging)
            {
                var newLocation = PointToScreen(e.Location);
                Location = new Point(newLocation.X - _dragOffset.X, newLocation.Y - _dragOffset.Y);
            }
        }

        private void OnFormMouseUp(object sender, MouseEventArgs e)
        {
            _isDragging = false;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_overlayForm != null)
                {
                    _overlayForm.SpyModeChanged -= OnSpyModeChanged;
                    _overlayForm.Dispose();
                }
            }
            base.Dispose(disposing);
        }
    }
}
