using System.Text.Json.Serialization;

namespace NeonSprawl.Server.Game.AbilityInput;

/// <summary>POST body for ability cast intent (NEO-31).</summary>
public sealed class AbilityCastRequest
{
    public const int CurrentSchemaVersion = 1;

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

    [JsonPropertyName("slotIndex")]
    public int SlotIndex { get; init; }

    [JsonPropertyName("abilityId")]
    public string? AbilityId { get; init; }

    /// <summary>
    /// Must match the server's current combat lock (same string as <c>GET …/target</c> <c>lockedTargetId</c>) for
    /// <c>accepted: true</c>; NEO-28 adds <c>invalid_target</c> / <c>out_of_range</c> denies when it does not.
    /// </summary>
    [JsonPropertyName("targetId")]
    public string? TargetId { get; init; }
}

/// <summary>Combat outcome block on successful cast accept (NEO-82).</summary>
public sealed class CombatResolutionJson
{
    [JsonPropertyName("abilityId")]
    public required string AbilityId { get; init; }

    [JsonPropertyName("targetId")]
    public required string TargetId { get; init; }

    [JsonPropertyName("damageDealt")]
    public int DamageDealt { get; init; }

    [JsonPropertyName("targetRemainingHp")]
    public int TargetRemainingHp { get; init; }

    [JsonPropertyName("targetDefeated")]
    public bool TargetDefeated { get; init; }
}

/// <summary>POST response for cast submit (prototype accept/deny; NEO-31 + NEO-28 target rules).</summary>
public sealed class AbilityCastResponse
{
    public const int CurrentSchemaVersion = 1;

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

    [JsonPropertyName("accepted")]
    public bool Accepted { get; init; }

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

    /// <summary>Present only when <see cref="Accepted"/> is true after combat resolve (NEO-82).</summary>
    [JsonPropertyName("combatResolution")]
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public CombatResolutionJson? CombatResolution { get; init; }
}
