using System.Text.Json.Serialization;

namespace PSLauncher.Models;

public sealed class RemoteManifest
{
    [JsonPropertyName("schemaVersion")]
    public int SchemaVersion { get; set; }

    [JsonPropertyName("product")]
    public string Product { get; set; } = string.Empty;

    [JsonPropertyName("latest")]
    public string Latest { get; set; } = string.Empty;

    [JsonPropertyName("publishedAt")]
    public DateTime? PublishedAt { get; set; }

    [JsonPropertyName("minLauncherVersion")]
    public string? MinLauncherVersion { get; set; }

    [JsonPropertyName("versions")]
    public List<VersionManifest> Versions { get; set; } = new();

    [JsonPropertyName("signature")]
    public string? Signature { get; set; }

    [JsonPropertyName("launcher")]
    public LauncherInfo? Launcher { get; set; }
}

public sealed class LauncherInfo
{
    [JsonPropertyName("version")]
    public string Version { get; set; } = string.Empty;

    [JsonPropertyName("minRequired")]
    public string? MinRequired { get; set; }

    [JsonPropertyName("download")]
    public DownloadDescriptor Download { get; set; } = new();

    [JsonPropertyName("releaseNotesUrl")]
    public string? ReleaseNotesUrl { get; set; }
}

public sealed class VersionManifest
{
    [JsonPropertyName("version")]
    public string Version { get; set; } = string.Empty;

    [JsonPropertyName("releasedAt")]
    public DateTime ReleasedAt { get; set; }

    [JsonPropertyName("executable")]
    public string Executable { get; set; } = "PROSERVE_UE_5_5.exe";

    [JsonPropertyName("installFolderTemplate")]
    public string InstallFolderTemplate { get; set; } = "PROSERVE v{version}";

    [JsonPropertyName("download")]
    public DownloadDescriptor Download { get; set; } = new();

    [JsonPropertyName("releaseNotesUrl")]
    public string? ReleaseNotesUrl { get; set; }

    [JsonPropertyName("minLicenseDate")]
    public DateTime? MinLicenseDate { get; set; }

    [JsonPropertyName("availableForDownload")]
    public bool AvailableForDownload { get; set; } = true;

    [JsonPropertyName("heroImageUrl")]
    public string? HeroImageUrl { get; set; }

    public string GetInstallFolderName() => InstallFolderTemplate.Replace("{version}", Version);
}

public sealed class DownloadDescriptor
{
    [JsonPropertyName("url")]
    public string Url { get; set; } = string.Empty;

    [JsonPropertyName("sizeBytes")]
    public long SizeBytes { get; set; }

    [JsonPropertyName("sha256")]
    public string Sha256 { get; set; } = string.Empty;

    /// <summary>
    /// Algo de vérif d'intégrité du ZIP téléchargé.
    /// Valeurs : "sha256" (défaut, voir <see cref="Sha256"/>) — "none" (pas de vérif).
    /// La sécurité est déjà assurée par la signature Ed25519 du manifest et HTTPS ;
    /// le hash sert surtout à détecter la corruption disque/réseau sur 14 Go.
    /// Pour les très gros builds où on accepte le compromis, mettre "none" évite
    /// 30 s à 3 min de calcul à la fin du DL.
    /// </summary>
    [JsonPropertyName("hashAlgorithm")]
    public string? HashAlgorithm { get; set; }

    /// <summary>True si on doit vérifier le hash (sha256 non vide, non "REPLACE", algo != "none").</summary>
    public bool ShouldVerifyHash =>
        !string.IsNullOrEmpty(Sha256)
        && !Sha256.StartsWith("REPLACE", StringComparison.OrdinalIgnoreCase)
        && !string.Equals(HashAlgorithm, "none", StringComparison.OrdinalIgnoreCase);
}
