using ITNexusAgent.Models;
using System.Diagnostics;
using System.Management;
using System.Net.Http;

namespace ITNexusAgent.Services;

public class CommandExecutor(ApiService api, string hostname, string dataDir, string exePath)
{
    private readonly ApiService _api = api;
    private readonly string _hostname = hostname;
    private readonly string _dataDir = dataDir;
    private readonly string _exePath = exePath;

    private static void RunSchtasks(string args) =>
        Process.Start(new ProcessStartInfo("schtasks.exe", args) { CreateNoWindow = true })?.WaitForExit();

    public async Task ExecuteAsync(PatchCommand cmd)
    {
        string result;
        try
        {
            result = cmd.Command switch
            {
                "check_updates"   => await CheckUpdates(),
                "install_updates" => await InstallUpdates(),
                "reboot"          => await Reboot(cmd.Id),
                "upgrade_win11"   => await UpgradeWin11(),
                "update_agent"    => await UpdateAgent(),
                "shell_exec"      => await ShellExec(cmd.Params ?? ""),
                _                 => $"Unbekannter Command: {cmd.Command}"
            };
        }
        catch (Exception ex)
        {
            result = $"Fehler: {ex.Message}";
        }

        if (cmd.Command != "reboot")
        {
            await _api.ReportCommandResultAsync(new CommandResult
            {
                CommandId = cmd.Id,
                Status = "done",
                Result = result
            });
        }
    }

    private Task<string> CheckUpdates()
    {
        Process.Start(new ProcessStartInfo("UsoClient.exe", "StartScan") { CreateNoWindow = true });
        Thread.Sleep(5000);
        return Task.FromResult("Update-Scan gestartet");
    }

    private Task<string> InstallUpdates()
    {
        Process.Start(new ProcessStartInfo("UsoClient.exe", "StartDownload") { CreateNoWindow = true });
        Thread.Sleep(3000);
        Process.Start(new ProcessStartInfo("UsoClient.exe", "StartInstall") { CreateNoWindow = true });
        return Task.FromResult("Update-Installation gestartet");
    }

    private async Task<string> Reboot(int cmdId)
    {
        await _api.ReportCommandResultAsync(new CommandResult
        {
            CommandId = cmdId,
            Status = "done",
            Result = "Neustart wird in 60 Sekunden durchgeführt"
        });
        Process.Start("shutdown.exe", "/r /t 60 /c \"IT Nexus Patch Management - Geplanter Neustart\"");
        return "";
    }

    private Task<string> UpgradeWin11()
    {
        var exePath = Path.Combine(_dataDir, "Win11Upgrade.exe");
        using var client = new HttpClient();
        var bytes = client.GetByteArrayAsync("https://go.microsoft.com/fwlink/?linkid=2171764").Result;
        if (bytes.Length < 1024 * 1024) return Task.FromResult("Download fehlgeschlagen");
        File.WriteAllBytes(exePath, bytes);

        var fullUser = NotificationService.GetLoggedOnUser();
        if (!string.IsNullOrEmpty(fullUser))
        {
            RunSchtasks("/delete /tn \"IT Nexus Win11 Upgrade\" /f");
            RunSchtasks($"/create /tn \"IT Nexus Win11 Upgrade\" /tr \"\\\"{exePath}\\\" /skipeula /auto upgrade\" /sc ONCE /st {DateTime.Now.AddSeconds(20):HH:mm} /ru \"{fullUser}\" /it /rl HIGHEST /f");
        }
        else
        {
            Process.Start(new ProcessStartInfo(exePath, "/quietinstall /skipeula /auto upgrade")
            { CreateNoWindow = true });
        }
        return Task.FromResult("running");
    }

    private Task<string> ShellExec(string command)
    {
        if (string.IsNullOrWhiteSpace(command)) return Task.FromResult("Kein Befehl angegeben");
        try
        {
            var psi = new ProcessStartInfo("powershell.exe",
                $"-NonInteractive -NoProfile -ExecutionPolicy Bypass -Command \"{command.Replace("\"", "\\\"")}\"")
            {
                CreateNoWindow = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false
            };
            var p = Process.Start(psi)!;
            var stdout = p.StandardOutput.ReadToEnd();
            var stderr = p.StandardError.ReadToEnd();
            p.WaitForExit(30000);
            var output = stdout;
            if (!string.IsNullOrEmpty(stderr)) output += "\n[STDERR] " + stderr;
            return Task.FromResult(string.IsNullOrEmpty(output) ? "(kein Output)" : output.Trim());
        }
        catch (Exception ex)
        {
            return Task.FromResult($"Fehler: {ex.Message}");
        }
    }

    private async Task<string> UpdateAgent()
    {
        var bytes = await _api.DownloadSetupAsync(_hostname);
        if (bytes.Length < 512 * 1024) return "Download fehlgeschlagen - Installer zu klein";

        var setupPath = Path.Combine(_dataDir, "IT-Nexus-Agent-Setup-Update.exe");
        var batchPath = Path.Combine(_dataDir, "update.cmd");

        await File.WriteAllBytesAsync(setupPath, bytes);

        // Batch: wartet kurz, führt Installer silent aus, löscht sich selbst
        var batch = $"""
            @echo off
            timeout /t 5 /nobreak > nul
            "{setupPath}" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART
            del "{setupPath}" > nul
            del "%~f0"
            """;

        await File.WriteAllTextAsync(batchPath, batch, System.Text.Encoding.ASCII);
        Process.Start(new ProcessStartInfo("cmd.exe", $"/c \"{batchPath}\"")
        { CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden });

        return "Update-Installer gestartet";
    }
}
