using System.Text.Json.Serialization;

namespace NexusShell.Models;

public enum NexusPackageState
{
    Installed,
    Available,
    UpdateAvailable,
    Broken,
    Disabled,
}

public sealed class NexusInstalledPackage
{
    public required string Id { get; init; }
    public required NexusPackageManifest Manifest { get; init; }
    public NexusPackageState State { get; init; }
    public string? InstalledVersion { get; init; }
    public DateTimeOffset? InstalledAt { get; init; }
    public string? StateReason { get; init; }
}

public sealed class NexusPackageIndexEntry
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = string.Empty;

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

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

    [JsonPropertyName("cachedAt")]
    public DateTimeOffset CachedAt { get; set; }
}

public sealed class NexusPackageIndex
{
    [JsonPropertyName("version")]
    public string Version { get; set; } = "1.0";

    [JsonPropertyName("updatedAt")]
    public DateTimeOffset UpdatedAt { get; set; }

    [JsonPropertyName("packages")]
    public List<NexusPackageIndexEntry> Packages { get; set; } = [];
}

public sealed class NexusInstalledPackageRecord
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = string.Empty;

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

    [JsonPropertyName("installedAt")]
    public DateTimeOffset InstalledAt { get; set; }

    [JsonPropertyName("state")]
    public NexusPackageState State { get; set; } = NexusPackageState.Installed;

    [JsonPropertyName("stateReason")]
    public string? StateReason { get; set; }
}

public sealed class NexusPackageValidationResult
{
    public bool IsValid { get; init; }
    public IReadOnlyList<string> Errors { get; init; } = [];
    public NexusPackageManifest? Manifest { get; init; }

    public static NexusPackageValidationResult Success(NexusPackageManifest manifest) =>
        new() { IsValid = true, Manifest = manifest };

    public static NexusPackageValidationResult Failure(params string[] errors) =>
        new() { IsValid = false, Errors = errors };
}
