using System.Diagnostics;
using System.Runtime.InteropServices;
using BrikInstaller.Utils;

namespace BrikInstaller.Services;

public static class InstallationService {
    public static bool CanCreateInPath(string folderPath) {
        if (string.IsNullOrWhiteSpace(folderPath)) return false;

        try {
            string fullPath = Path.GetFullPath(folderPath);
            DirectoryInfo di = new DirectoryInfo(fullPath);

            while (di != null && !di.Exists) {
                di = di.Parent!;
            }

            if (di == null) return false;

            string testPath = Path.Combine(di.FullName, Guid.NewGuid().ToString());
            
            Directory.CreateDirectory(testPath);
            Directory.Delete(testPath);
            
            return true;
        } catch (UnauthorizedAccessException) {
            return false;
        } catch (Exception) {
            return false;
        }
    }

    public static void ElevateAndRestart() {
        string exePath = Process.GetCurrentProcess().MainModule!.FileName;
        ProcessStartInfo startInfo = new ProcessStartInfo();

        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
            startInfo.FileName = exePath;
            startInfo.Verb = "runas";
            startInfo.UseShellExecute = true;
        } 
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
            startInfo.FileName = "pkexec";
            startInfo.Arguments = $"\"{exePath}\"";
            startInfo.UseShellExecute = false;
        } 
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
            startInfo.FileName = "osascript";
            startInfo.Arguments = $"-e \"do shell script \\\"{exePath}\\\" with administrator privileges\"";
            startInfo.UseShellExecute = false;
        }

        try {
            Process.Start(startInfo);
            Environment.Exit(0);
        } catch (Exception ex) {
            Console.WriteLine($"Elevation failed : {ex.Message}");
        }
    }

    public static string GetDefaultInstallationPath(string appName) {
        string final = "";
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
            string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            final = Path.Combine(localAppData, "Programs", appName);
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
            string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
            final = Path.Combine(home, ".local", "share", appName.ToLower().Replace(" ", "_"));
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
            final = $"/Applications/{appName}.app";
        }
        return final;
    }
    
    public static void LaunchApplication(string executablePath) {
        try {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
                startInfo.FileName = executablePath;
                startInfo.UseShellExecute = true;
            } 
            else {
                BashUtils.GetCommandOutput($"chmod +x \"{executablePath}\"");
                
                startInfo.FileName = executablePath;
                startInfo.UseShellExecute = false;
            }

            startInfo.WorkingDirectory = Path.GetDirectoryName(executablePath);
            
            Process.Start(startInfo);
        }
        catch (Exception ex) {
            Console.WriteLine($"[Launch Error] Unable to start : {ex.Message}");
        }
    }
}

public static class ShortcutService {
    public static void CreateShortcut(string appName, string targetExePath) {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
            CreateWindowsShortcut(appName, targetExePath);
        } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
            CreateLinuxShortcut(appName, targetExePath);
        } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
            CreateMacShortcut(appName, targetExePath);
        }
    }

    private static void CreateWindowsShortcut(string appName, string targetExePath) {
        string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        string shortcutLocation = Path.Combine(desktopPath, $"{appName}.lnk");
        string cmd = $"$s=(New-Object -ComObject WScript.Shell).CreateShortcut('{shortcutLocation}');$s.TargetPath='{targetExePath}';$s.Save()";
        BashUtils.GetCommandOutput($"powershell -Command \"{cmd}\"");
    }

    private static void CreateLinuxShortcut(string appName, string targetExePath) {
        string desktopEntry = $@"
[Desktop Entry]
Type=Application
Name={appName}
Exec=""{targetExePath}""
Terminal=false
";

        string desktopPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Desktop");
        string filePath = Path.Combine(desktopPath, $"{appName}.desktop");
        File.WriteAllText(filePath, desktopEntry);
        BashUtils.GetCommandOutput($"chmod +x \"{filePath}\"");
    }

    private static void CreateMacShortcut(string appName, string targetExePath) {
        string desktopPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Desktop");
        string shortcutPath = Path.Combine(desktopPath, appName);
        BashUtils.GetCommandOutput($"ln -sf \"{targetExePath}\" \"{shortcutPath}\"");
    }
}