using System.Text.Json.Serialization;
namespace GoodWood.Application.Games;
///
/// Base class for game events that require UI notification (dialogs, toasts, etc.).
/// Events have a unique ID to prevent duplicate display.
///
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")]
[JsonDerivedType(typeof(PlayerEliminatedEvent), "PlayerEliminated")]
[JsonDerivedType(typeof(PlayerWonEvent), "PlayerWon")]
[JsonDerivedType(typeof(TeamWonEvent), "TeamWon")]
[JsonDerivedType(typeof(GameEndedEvent), "GameEnded")]
[JsonDerivedType(typeof(FoxChangedEvent), "FoxChanged")]
public abstract record GameEvent
{
///
/// Unique identifier for this event instance.
///
public Guid EventId { get; init; } = Guid.NewGuid();
///
/// Timestamp when the event was created.
///
public DateTime CreatedAt { get; init; } = DateTime.UtcNow;
///
/// Game-specific message to display in the UI.
///
public string? Message { get; init; }
}
///
/// Event when a player is eliminated from the game.
///
public record PlayerEliminatedEvent : GameEvent
{
///
/// ID of the eliminated player.
///
public required Guid PlayerId { get; init; }
///
/// Elimination rank (1 = first eliminated, 2 = second, etc.).
///
public int EliminationRank { get; init; }
///
/// Number of players still active after this elimination.
///
public int RemainingPlayerCount { get; init; }
}
///
/// Event when a single player wins the game.
///
public record PlayerWonEvent : GameEvent
{
///
/// ID of the winning player.
///
public required Guid PlayerId { get; init; }
}
///
/// Event when a team wins the game.
///
public record TeamWonEvent : GameEvent
{
///
/// Name or identifier of the winning team.
///
public required string TeamName { get; init; }
///
/// IDs of players in the winning team.
///
public required IReadOnlyList PlayerIds { get; init; }
}
///
/// Event when the fox role changes (fox escaped or was caught).
///
public record FoxChangedEvent : GameEvent
{
///
/// ID of the player who was fox.
///
public required Guid FoxPlayerId { get; init; }
///
/// True if the fox escaped, false if caught by hunters.
///
public bool FoxEscaped { get; init; }
///
/// ID of the next fox (null if game is over).
///
public Guid? NextFoxPlayerId { get; init; }
}
///
/// Event when the game ends (covers any end scenario).
///
public record GameEndedEvent : GameEvent
{
///
/// Optional winner ID (null for draws or no-winner scenarios).
///
public Guid? WinnerId { get; init; }
///
/// Optional winning team name.
///
public string? WinningTeamName { get; init; }
///
/// Whether the game ended in a draw.
///
public bool IsDraw { get; init; }
}