using System.Text.Json.Serialization;

namespace NeonSprawl.Server.Game.Mastery;

/// <summary>JSON body for <c>GET /game/players/{{id}}/perk-state</c> (NEO-48).</summary>
public sealed class PerkStateSnapshotResponse
{
    public const int CurrentSchemaVersion = 1;

    [JsonPropertyName("schemaVersion")]
    public int SchemaVersion { get; init; } = CurrentSchemaVersion;

    [JsonPropertyName("playerId")]
    public required string PlayerId { get; init; }

    /// <summary>Branch picks per skill. Consumers key by <see cref="PerkBranchPickTrackJson.SkillId"/> — array order is not part of the contract.</summary>
    [JsonPropertyName("branchPicks")]
    public required IReadOnlyList<PerkBranchPickTrackJson> BranchPicks { get; init; }

    [JsonPropertyName("unlockedPerkIds")]
    public required IReadOnlyList<string> UnlockedPerkIds { get; init; }
}

public sealed class PerkBranchPickTrackJson
{
    [JsonPropertyName("skillId")]
    public required string SkillId { get; init; }

    [JsonPropertyName("picks")]
    public required IReadOnlyList<PerkBranchPickRowJson> Picks { get; init; }
}

public sealed class PerkBranchPickRowJson
{
    [JsonPropertyName("tierIndex")]
    public int TierIndex { get; init; }

    [JsonPropertyName("branchId")]
    public required string BranchId { get; init; }
}

/// <summary>POST body for branch selection on <c>POST …/perk-state</c> (NEO-48).</summary>
public sealed class PerkBranchSelectRequest
{
    public const int CurrentSchemaVersion = 1;

    [JsonPropertyName("schemaVersion")]
    public int SchemaVersion { get; init; }

    [JsonPropertyName("skillId")]
    public required string SkillId { get; init; }

    [JsonPropertyName("tierIndex")]
    public int TierIndex { get; init; }

    [JsonPropertyName("branchId")]
    public required string BranchId { get; init; }
}

/// <summary>POST responses for branch selection — success (<see cref="Selected"/>) or structured deny (<see cref="ReasonCode"/>).</summary>
public sealed class PerkBranchSelectResponse
{
    public const int CurrentSchemaVersion = 1;

    [JsonPropertyName("schemaVersion")]
    public int SchemaVersion { get; init; } = CurrentSchemaVersion;

    [JsonPropertyName("selected")]
    public bool Selected { get; init; }

    [JsonPropertyName("reasonCode")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? ReasonCode { get; init; }

    [JsonPropertyName("perkState")]
    public required PerkStateSnapshotResponse PerkState { get; init; }

    [JsonPropertyName("unlockedEvents")]
    public required IReadOnlyList<PerkUnlockedEventJson> UnlockedEvents { get; init; }
}

public sealed class PerkUnlockedEventJson
{
    [JsonPropertyName("perkId")]
    public required string PerkId { get; init; }

    [JsonPropertyName("skillId")]
    public required string SkillId { get; init; }

    [JsonPropertyName("tierIndex")]
    public int TierIndex { get; init; }

    [JsonPropertyName("branchId")]
    public string? BranchId { get; init; }

    [JsonPropertyName("source")]
    public required string Source { get; init; }
}
