using Avalonia.Controls;
using Avalonia.Threading;
using ClawdDotNet.App.Services;
using ClawdDotNet.Desktop.ViewModels;
using ClawdDotNet.Desktop.Views;

namespace ClawdDotNet.Desktop.Services;

/// <summary>
/// Lizenzabfrage über Fenster.
///
/// Der Aufbau läuft auf einem Hintergrundfaden — Avalonia besteht aber darauf, dass
/// Fenster auf dem Oberflächenfaden entstehen. Deshalb geht hier alles über
/// <see cref="Dispatcher.UIThread"/>. Das ist der Grund, warum
/// <see cref="ILicensePrompt"/> durchgehend asynchron ist: Die WinForms-Fassung konnte
/// <c>ShowDialog</c> einfach blockierend aufrufen, weil sie ohnehin auf dem
/// Oberflächenfaden lief.
/// </summary>
public sealed class AvaloniaLicensePrompt : ILicensePrompt
{
    public async Task<string?> RequestKeyAsync(string hardwareId, string? problem, string? currentKey)
        => await Dispatcher.UIThread.InvokeAsync(async () =>
        {
            var viewModel = new LicenseViewModel(hardwareId, problem, currentKey);
            var window = new LicenseWindow { DataContext = viewModel };

            window.Show();

            var key = await viewModel.Result;
            window.Close();

            return key;
        });

    public Task ShowInfoAsync(string title, string message)
        => ShowMessageAsync(title, message);

    public Task ShowErrorAsync(string title, string message)
        => ShowMessageAsync(title, message);

    /// <summary>
    /// Ein Meldungsfenster.
    ///
    /// Avalonia bringt kein <c>MessageBox</c> mit — bewusst, weil es auf allen
    /// Plattformen anders aussähe. Ein schlichtes Fenster ist hier ausreichend und
    /// erspart uns eine weitere Abhängigkeit für drei Aufrufstellen.
    /// </summary>
    private static async Task ShowMessageAsync(string title, string message)
        => await Dispatcher.UIThread.InvokeAsync(async () =>
        {
            var completion = new TaskCompletionSource();

            var button = new Button
            {
                Content = "OK",
                HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
                IsDefault = true
            };

            var window = new Window
            {
                Title = title,
                Width = 460,
                SizeToContent = SizeToContent.Height,
                CanResize = false,
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                Content = new StackPanel
                {
                    Margin = new Avalonia.Thickness(20),
                    Spacing = 16,
                    Children =
                    {
                        new TextBlock { Text = message, TextWrapping = Avalonia.Media.TextWrapping.Wrap },
                        button
                    }
                }
            };

            button.Click += (_, _) => window.Close();
            window.Closed += (_, _) => completion.TrySetResult();

            window.Show();
            await completion.Task;
        });
}
