namespace PSLauncher.Models;

public sealed class LocalConfig
{
    public int SchemaVersion { get; set; } = 1;
    public string ServerBaseUrl { get; set; } = "https://example.com/PS_Launcher/api";
    public string InstallRoot { get; set; } = string.Empty;
    public string? LastLaunchedVersion { get; set; }

    /// <summary>
    /// Code de langue de l'UI : "auto" (suit la langue Windows), "fr", "en",
    /// "zh", "th" ou "ar". Tout changement nécessite un redémarrage du launcher.
    /// </summary>
    public string Language { get; set; } = "auto";

    /// <summary>
    /// Nombre de connexions HTTP parallèles utilisées pour télécharger un build.
    /// 1 = comportement legacy single-connection. 4-8 contourne le throttling
    /// per-connection d'Apache/OVH mutualisé. 8 est un bon défaut.
    /// </summary>
    public int ParallelDownloadSegments { get; set; } = 8;

    /// <summary>
    /// Si false, ignore la vérification SHA-256 même si le manifest l'exige.
    /// Utile sur les machines lentes ou pour gagner 30 s-3 min en fin de DL d'un gros build.
    /// La sécurité repose alors uniquement sur la signature Ed25519 du manifest + HTTPS,
    /// ce qui reste robuste.
    /// </summary>
    public bool VerifyDownloadHash { get; set; } = true;

    /// <summary>
    /// URL de l'outil de reporting local (page web embarquée dans le launcher,
    /// onglet "Report"). Par défaut pointe vers l'install standard ASTERION
    /// dans XAMPP. Surchargeable dans Settings → Avancés.
    /// </summary>
    public string ReportUrl { get; set; } = "http://localhost/ProserveReport/";

    /// <summary>
    /// URL de la documentation locale (onglet "Documentation"). Vide par défaut :
    /// l'utilisateur peut pointer vers une URL locale ou web. Si vide, l'onglet
    /// affiche un placeholder avec les liens vers les fichiers .pptx du dossier
    /// d'install du launcher.
    /// </summary>
    public string DocumentationUrl { get; set; } = string.Empty;

    public LicenseConfig License { get; set; } = new();

    /// <summary>
    /// Connexion à la base MySQL locale (XAMPP) utilisée par PROSERVE pour ses
    /// statistiques. Le launcher s'en sert pour appliquer les migrations bundled
    /// dans <c>_migrations/</c> au moment de l'install d'une nouvelle version.
    /// </summary>
    public DatabaseConfig Database { get; set; } = new();
}

/// <summary>
/// Paramètres de connexion à la base MySQL locale. Les valeurs par défaut
/// correspondent à un XAMPP standard fraîchement installé. Override possible
/// via Settings → Base de données.
/// </summary>
public sealed class DatabaseConfig
{
    public string Host { get; set; } = "localhost";
    public uint Port { get; set; } = 3306;
    public string User { get; set; } = "root";

    /// <summary>
    /// Mot de passe MySQL stocké chiffré DPAPI (CurrentUser scope) en base64.
    /// Vide = pas de password (config XAMPP par défaut). NE PAS écrire en clair.
    /// </summary>
    public string? EncryptedPassword { get; set; }

    /// <summary>
    /// Nom de la base de données qui contient les tables de PROSERVE.
    /// Default "proserveapi" — c'est le nom utilisé par le script d'install ASTERION
    /// qui provisionne XAMPP sur les machines clients. À surcharger seulement si la DB
    /// a été créée sous un autre nom.
    /// </summary>
    public string Database { get; set; } = "proserveapi";

    /// <summary>
    /// Si true, le launcher applique automatiquement les migrations SQL bundled
    /// dans <c>_migrations/</c> de chaque ZIP, juste après l'extraction.
    /// Sécurité : on n'applique JAMAIS sans cette opt-in (au cas où certains users
    /// auraient une config DB exotique non gérée par le defaut).
    /// </summary>
    public bool AutoApplyMigrations { get; set; } = true;
}

public sealed class LicenseConfig
{
    public string? EncryptedKey { get; set; }

    /// <summary>
    /// Date UTC de la dernière validation online réussie. Utilise <c>response.ServerTime</c>
    /// (signé Ed25519) plutôt que l'horloge locale, donc non manipulable par l'utilisateur.
    /// Sert de point de départ au calcul d'expiration du cache offline.
    /// </summary>
    public DateTime? LastValidationAt { get; set; }

    public DateTime? CachedEntitlementUntil { get; set; }
    public string? CachedOwnerName { get; set; }

    /// <summary>
    /// Statut tel que renvoyé par le serveur lors de la dernière validation : "valid",
    /// "expired", "revoked", "invalid", "machine_limit_exceeded". Persisté pour qu'une
    /// révocation effectuée pendant que le user est offline soit toujours visible
    /// même après son expiration de cache local. Le calcul "valid → expired" basé
    /// sur la date est aussi appliqué côté lecture (sanity) si le temps a passé.
    /// </summary>
    public string? CachedStatus { get; set; }

    /// <summary>
    /// Compteur monotone : date UTC la plus récente jamais observée par le launcher
    /// sur cette machine. Mise à jour à chaque démarrage si <c>now</c> est postérieur.
    /// Sert d'anti-rollback : si l'utilisateur recule l'horloge PC, on détecte
    /// (now &lt; LastSeenUtc - grace) et on invalide le cache → forçage d'une
    /// re-validation online la prochaine fois qu'il sera connecté.
    /// </summary>
    public DateTime? LastSeenUtc { get; set; }
}
