using System;
using System.Drawing;
using System.Windows.Forms;
using LicenseLabrador.Client;
using PolyTraderSharp.Licensing;

namespace PolyTraderSharp.Ui
{
    /// <summary>
    /// Modaler Lizenzdialog beim Programmstart, wenn keine gültige Lizenz vorliegt. Zeigt die
    /// Hardware-ID (kopierbar, für die Aktivierung im Lizenz-Admin), nimmt einen Lizenzschlüssel
    /// entgegen und validiert ihn gegen den Lizenzserver. Bei Erfolg werden <see cref="ValidatedKey"/>
    /// und <see cref="ValidatedResult"/> gesetzt; der Aufrufer (LicenseGate) speichert den Schlüssel.
    /// Ohne gültige Lizenz kann der Nutzer eingeschränkt (nur Core-Shell) weiterstarten.
    /// </summary>
    public partial class LicenseDialog : Form
    {
        private readonly LicenseClient _client;

        /// <summary>Nur gesetzt, wenn im Dialog erfolgreich validiert wurde.</summary>
        public LicenseResult? ValidatedResult { get; private set; }

        /// <summary>Der erfolgreich validierte Schlüssel (für die verschlüsselte Ablage).</summary>
        public string? ValidatedKey { get; private set; }

        /// <param name="startupContext">
        /// true = Aufruf beim Programmstart (keine gültige Lizenz): der Abbruch-Button bietet
        /// „eingeschränkt starten". false = Aufruf aus den Einstellungen (App läuft bereits): der
        /// Button heißt „Schließen".
        /// </param>
        public LicenseDialog(LicenseClient client, string prefillKey, LicenseResult? initialResult, bool startupContext = true)
        {
            _client = client ?? throw new ArgumentNullException(nameof(client));
            InitializeComponent();

            txtHardwareId.Text = SafeHardwareId(client);
            txtKey.Text = prefillKey ?? string.Empty;

            if (initialResult != null)
            {
                lblStatus.Text = "Status: " + LicenseGate.Describe(initialResult) +
                    (string.IsNullOrEmpty(initialResult.Message) ? string.Empty : $" – {initialResult.Message}");
            }
            else
            {
                lblStatus.Text = "Status: noch nicht geprüft – bitte „Validieren“ klicken.";
            }

            if (startupContext)
            {
                lblHeadline.Text = "Für PolyTrader wird eine gültige Lizenz benötigt.";
                btnLimited.Text = "Ohne Lizenz starten (eingeschränkt)";
            }
            else
            {
                lblHeadline.Text = "Lizenz prüfen / hinterlegen";
                btnLimited.Text = "Schließen";
            }

            btnValidate.Click += (_, _) => ValidateKey();
            btnCopyHwId.Click += (_, _) => CopyHardwareId();
            btnLimited.Click += (_, _) => { DialogResult = DialogResult.Cancel; Close(); };
            AcceptButton = btnValidate;
        }

        private static string SafeHardwareId(LicenseClient client)
        {
            try { return client.GetHardwareId(); }
            catch { return "(nicht ermittelbar)"; }
        }

        /// <summary>
        /// Prüft den eingegebenen Schlüssel gegen den Lizenzserver. Bewusst NICHT „Validate" genannt:
        /// das würde <see cref="ContainerControl.Validate()"/> verdecken (CS0108), sodass ein Aufruf
        /// über eine <see cref="Form"/>-Referenz statt der Control-Validierung einen Netzwerk-Call
        /// auslösen würde.
        /// </summary>
        private void ValidateKey()
        {
            string key = txtKey.Text.Trim();
            if (string.IsNullOrWhiteSpace(key))
            {
                lblResult.ForeColor = Color.Firebrick;
                lblResult.Text = "Bitte einen Lizenzschlüssel eingeben.";
                return;
            }

            btnValidate.Enabled = false;
            Cursor = Cursors.WaitCursor;
            lblResult.ForeColor = SystemColors.ControlText;
            lblResult.Text = "Prüfe Lizenz …";
            lblResult.Refresh();

            try
            {
                // Blockierend: das SDK nutzt durchgängig ConfigureAwait(false) → kein Deadlock auf dem
                // UI-Thread; der kurze Freeze (max. HTTP-Timeout) ist im modalen Startdialog vertretbar
                // und vermeidet jede Abhängigkeit vom WinForms-SynchronizationContext vor Application.Run.
                LicenseResult result = _client.ValidateAsync(key).GetAwaiter().GetResult();

                if (result.IsUsable)
                {
                    ValidatedResult = result;
                    ValidatedKey = key;
                    lblResult.ForeColor = Color.Green;
                    lblResult.Text = "Lizenz gültig – PolyTrader startet.";
                    DialogResult = DialogResult.OK;
                    Close();
                }
                else
                {
                    lblResult.ForeColor = Color.Firebrick;
                    string extra = string.IsNullOrEmpty(result.Message) ? string.Empty : $" ({result.Message})";
                    lblResult.Text = "Nicht gültig: " + LicenseGate.Describe(result) + extra;
                }
            }
            catch (Exception ex)
            {
                lblResult.ForeColor = Color.Firebrick;
                lblResult.Text = "Fehler bei der Prüfung: " + ex.Message;
            }
            finally
            {
                Cursor = Cursors.Default;
                btnValidate.Enabled = true;
            }
        }

        private void CopyHardwareId()
        {
            try { Clipboard.SetText(txtHardwareId.Text); }
            catch { /* Zwischenablage kann kurzzeitig belegt sein – kein harter Fehler */ }
        }
    }
}
