using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;

namespace PolyTrader.App.Avalonia.Views
{
    /// <summary>
    /// Kleiner Allzweck-Dialog: Hinweis, Ja/Nein-Rückfrage und (maskierte) Eingabe.
    /// Ersetzt die MessageBox-/Prompt-Aufrufe der WinForms-Oberfläche.
    ///
    /// <para>Seit der Umstellung auf die Einfenster-Shell rufen die Seiten (UserControls) hier auf
    /// und können kein <see cref="Window"/> mehr als Besitzer übergeben. Die Helfer nehmen deshalb
    /// ein beliebiges <see cref="Control"/> und suchen sich das Fenster selbst.</para>
    /// </summary>
    public partial class DialogWindow : Window
    {
        public DialogWindow() => AvaloniaXamlLoader.Load(this);

        private void Setup(string title, string message, bool withInput, bool masked, string okText, bool withCancel)
        {
            Title = title;
            this.FindControl<TextBlock>("lblTitle")!.Text = title;
            this.FindControl<TextBlock>("lblMessage")!.Text = message;

            var input = this.FindControl<TextBox>("txtInput")!;
            input.IsVisible = withInput;
            if (withInput)
            {
                input.PasswordChar = masked ? '•' : '\0';
                input.Text = string.Empty;
            }

            var ok = this.FindControl<Button>("btnOk")!;
            var cancel = this.FindControl<Button>("btnCancel")!;
            ok.Content = okText;
            cancel.IsVisible = withCancel;

            ok.Click += (_, _) => Close(true);
            cancel.Click += (_, _) => Close(false);
        }

        /// <summary>
        /// Fenster zum aufrufenden Steuerelement. Fällt auf das Hauptfenster zurück, falls das
        /// Steuerelement (noch) nicht im Baum hängt – etwa während der Konstruktionsprüfung.
        /// </summary>
        private static Window? OwnerOf(Control owner)
        {
            if (TopLevel.GetTopLevel(owner) is Window window) return window;
            return (global::Avalonia.Application.Current?.ApplicationLifetime
                    as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
        }

        /// <summary>Reiner Hinweis mit OK.</summary>
        public static async Task Info(Control owner, string title, string message)
        {
            if (OwnerOf(owner) is not { } window) return;
            var dlg = new DialogWindow();
            dlg.Setup(title, message, withInput: false, masked: false, okText: "OK", withCancel: false);
            await dlg.ShowDialog(window);
        }

        /// <summary>
        /// Ja/Nein-Rückfrage. Liefert <c>true</c> bei Bestätigung – und <c>false</c>, wenn sich gar
        /// kein Fenster finden lässt: ohne Oberfläche gilt nichts als bestätigt.
        /// </summary>
        public static async Task<bool> Confirm(Control owner, string title, string message, string okText = "Ja")
        {
            if (OwnerOf(owner) is not { } window) return false;
            var dlg = new DialogWindow();
            dlg.Setup(title, message, withInput: false, masked: false, okText: okText, withCancel: true);
            return await dlg.ShowDialog<bool>(window);
        }

        /// <summary>
        /// Eingabe. Liefert <c>null</c> bei Abbruch – leerer String bedeutet bewusst „Wert entfernen"
        /// (dieselbe Unterscheidung wie in der bisherigen Oberfläche).
        /// </summary>
        public static async Task<string?> Prompt(Control owner, string title, string message, bool masked = true)
        {
            if (OwnerOf(owner) is not { } window) return null;
            var dlg = new DialogWindow();
            dlg.Setup(title, message, withInput: true, masked: masked, okText: "OK", withCancel: true);
            bool ok = await dlg.ShowDialog<bool>(window);
            return ok ? dlg.FindControl<TextBox>("txtInput")!.Text ?? string.Empty : null;
        }
    }
}
