using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;

namespace SolviaOneDriveKillerLib.Helpers
{
    public class WindowsRegistry
    {

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern int RegLoadKey(uint hKey, string lpSubKey, string lpFile);

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern int RegUnloadKey(uint hKey, string lpSubKey);

        // HKEY_USERS
        private const uint HKEY_CLASSES_ROOT = 0x80000000;
        private const uint HKEY_CURRENT_USER = 0x80000001;
        private const uint HKEY_LOCAL_MACHINE = 0x80000002;
        private const uint HKEY_USERS = 0x80000003;
        private const uint HKEY_CURRENT_CONFIG = 0x80000005;

        public static bool LoadHive(string subKey, string fileName)
        {
            int result = RegLoadKey(HKEY_USERS, subKey, fileName);
            return result == 0;
        }

        public static bool UnloadHive(string subKey)
        {
            int result = RegUnloadKey(HKEY_USERS, subKey);
            return result == 0;
        }

        public static void DeleteRegistryValue(string keyPath, string valueName)
        {
            using (var key = Registry.Users.OpenSubKey(keyPath, true))
            {
                if (key != null)
                {
                    key.DeleteValue(valueName, false);
                }
            }
        }

        public static string GetOneDriveUninstallStringUser()
        {
            string uninstallString = "";
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OneDriveSetup.exe");
            
            if (key != null)
            {
                uninstallString = key.GetValue("UninstallString")?.ToString();
                
                key.Close();
            }
            return uninstallString;
        }

        public static string GetOneDriveUninstallStringMachine()
        {
            RegistryKey localMachine64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);

            string uninstallString = "";
            RegistryKey key = localMachine64.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OneDriveSetup.exe");

            if (key != null)
            {
                uninstallString = key.GetValue("UninstallString")?.ToString();

                key.Close();
            }
            return uninstallString;
        }
        /// <summary>
        /// Deletes a specified registry value or key.
        /// </summary>
        /// <param name="hive">The registry hive where the key or value resides.</param>
        /// <param name="subKeyPath">The path to the subkey containing the value or to be deleted.</param>
        /// <param name="valueName">The name of the value to delete. If null or empty, the subkey itself will be deleted.</param>
        /// <returns>True if successfully deleted, false otherwise.</returns>
        public static bool DeleteRegistryEntry(RegistryHive hive, string subKeyPath, string valueName = null)
        {
            try
            {
                using (RegistryKey baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Default))
                {
                    using (RegistryKey subKey = baseKey.OpenSubKey(subKeyPath, true))
                    {
                        if (subKey != null)
                        {
                            if (string.IsNullOrEmpty(valueName))
                            {
                                // If no valueName is provided, delete the subkey
                                baseKey.DeleteSubKey(subKeyPath, throwOnMissingSubKey: false);
                                Logging.SendToLog( $"Subkey '{subKeyPath}' deleted.");
                            }
                            else
                            {
                                // If a valueName is provided, delete the value
                                if (subKey.GetValue(valueName) != null)
                                {
                                    subKey.DeleteValue(valueName);
                                    Logging.SendToLog($"Value '{valueName}' deleted from '{subKeyPath}'.");
                                }
                                else
                                {
                                    Logging.SendToLog($"Value '{valueName}' not found in '{subKeyPath}'.");
                                    return false;
                                }
                            }
                        }
                        else
                        {
                            Logging.SendToLog($"Subkey '{subKeyPath}' not found.");
                            return false;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.SendToLog($"An error occurred: {ex.Message}");
                return false;
            }
            return true;
        }

        private static bool DeleteRegistryKey(RegistryKey rootKey, string subKeyPath)
        {
            if (rootKey == null) return false;

            try
            {
                // Check if the subKey exists
                if (rootKey.OpenSubKey(subKeyPath) != null)
                {
                    rootKey.DeleteSubKeyTree(subKeyPath);
                    return true;
                }
            }
            catch (Exception ex)
            {
                Logging.Log(Logging.LogLevel.Error, $"An error occurred: {ex.Message}");
            }
            return false;
        }
    }
}
