namespace ClawdDotNet.App.Services;

/// <summary>
/// Wie der <see cref="LicenseGate"/> mit dem Benutzer spricht.
///
/// Vorher rief er unmittelbar <c>MessageBox.Show</c> und einen WinForms-Dialog.
/// Das band die Lizenzprüfung an WinForms — und wäre im kopflosen Betrieb fatal
/// gewesen: Ein Dienst, der beim Start ein Fenster öffnet und auf eine Eingabe wartet,
/// hängt für immer, ohne dass jemand die Meldung je zu sehen bekäme.
///
/// Es gibt drei Umsetzungen:
/// <list type="bullet">
/// <item><c>AvaloniaLicensePrompt</c> — Dialoge im Fenster (Desktop).</item>
/// <item><see cref="ConsoleLicensePrompt"/> — Eingabe über die Konsole (Kommandozeile).</item>
/// <item><see cref="NonInteractiveLicensePrompt"/> — antwortet nie (systemd-Dienst).</item>
/// </list>
/// </summary>
public interface ILicensePrompt
{
    /// <summary>
    /// Fragt einen Lizenzschlüssel ab. <c>null</c> heißt Abbruch — der Aufrufer beendet
    /// die Anwendung.
    /// </summary>
    /// <param name="hardwareId">Wird angezeigt, damit der Nutzer ihn an den Support geben kann.</param>
    /// <param name="problem">Warum der bisherige Schlüssel nicht taugt; <c>null</c> beim ersten Fragen.</param>
    /// <param name="currentKey">Vorbelegung des Eingabefelds.</param>
    Task<string?> RequestKeyAsync(string hardwareId, string? problem, string? currentKey);

    /// <summary>Eine Meldung, die keine Antwort braucht (etwa „offline gültig bis …").</summary>
    Task ShowInfoAsync(string title, string message);

    /// <summary>Ein Fehler, nach dem die Anwendung nicht weiterläuft.</summary>
    Task ShowErrorAsync(string title, string message);
}

/// <summary>
/// Für den kopflosen Betrieb: fragt nicht, sondern lehnt ab.
///
/// Ein Dienst ohne Sitzung kann keinen Schlüssel entgegennehmen. Statt zu blockieren
/// meldet er, was zu tun ist — der Schlüssel wird vorab über die Kommandozeile
/// hinterlegt (<c>--license-set-key</c>).
/// </summary>
public sealed class NonInteractiveLicensePrompt(Action<string> log) : ILicensePrompt
{
    public Task<string?> RequestKeyAsync(string hardwareId, string? problem, string? currentKey)
    {
        log($"Lizenz erforderlich, aber kein Eingabeweg vorhanden. Hardware-ID: {hardwareId}. "
            + (problem is null ? "" : $"Grund: {problem}. ")
            + "Schlüssel mit '--license-set-key <SCHLÜSSEL>' hinterlegen.");

        return Task.FromResult<string?>(null);
    }

    public Task ShowInfoAsync(string title, string message)
    {
        log($"{title}: {message}");
        return Task.CompletedTask;
    }

    public Task ShowErrorAsync(string title, string message)
    {
        log($"{title}: {message}");
        return Task.CompletedTask;
    }
}

/// <summary>Eingabe über die Konsole — für Kommandozeilenaufrufe.</summary>
public sealed class ConsoleLicensePrompt : ILicensePrompt
{
    public Task<string?> RequestKeyAsync(string hardwareId, string? problem, string? currentKey)
    {
        if (problem is not null)
            Console.Error.WriteLine($"Lizenz: {problem}");

        Console.WriteLine($"Hardware-ID: {hardwareId}");
        Console.Write("Lizenzschlüssel: ");

        var input = Console.ReadLine()?.Trim();
        return Task.FromResult(string.IsNullOrWhiteSpace(input) ? null : input);
    }

    public Task ShowInfoAsync(string title, string message)
    {
        Console.WriteLine($"{title}: {message}");
        return Task.CompletedTask;
    }

    public Task ShowErrorAsync(string title, string message)
    {
        Console.Error.WriteLine($"{title}: {message}");
        return Task.CompletedTask;
    }
}
