namespace Scry.Core.Models;

/// <summary>
/// Represents a specific printing of a card in a set.
/// Maps to Scryfall's Card object (which is really a printing).
/// Contains the perceptual hash for image matching.
/// Includes denormalized Oracle data for convenience.
/// </summary>
public record Card
{
    /// <summary>
    /// Scryfall's unique card ID for this specific printing.
    /// </summary>
    public required string Id { get; init; }
    
    /// <summary>
    /// Oracle ID linking to the abstract game card.
    /// </summary>
    public required string OracleId { get; init; }
    
    /// <summary>
    /// Set ID this printing belongs to.
    /// </summary>
    public required string SetId { get; init; }
    
    /// <summary>
    /// Set code (e.g., "lea", "mh2") - denormalized for convenience.
    /// </summary>
    public string? SetCode { get; init; }
    
    /// <summary>
    /// Set name - denormalized for convenience.
    /// </summary>
    public string? SetName { get; init; }
    
    /// <summary>
    /// Card name - denormalized from Oracle for convenience.
    /// </summary>
    public required string Name { get; init; }
    
    /// <summary>
    /// Collector number within the set.
    /// </summary>
    public string? CollectorNumber { get; init; }
    
    /// <summary>
    /// Rarity (common, uncommon, rare, mythic).
    /// </summary>
    public string? Rarity { get; init; }
    
    /// <summary>
    /// Artist name.
    /// </summary>
    public string? Artist { get; init; }
    
    /// <summary>
    /// Illustration ID - same across printings with identical art.
    /// </summary>
    public string? IllustrationId { get; init; }
    
    /// <summary>
    /// URI to the card image (normal size).
    /// </summary>
    public string? ImageUri { get; init; }
    
    /// <summary>
    /// Perceptual hash for image matching.
    /// </summary>
    public byte[]? Hash { get; init; }
    
    /// <summary>
    /// Language code (e.g., "en", "ja").
    /// </summary>
    public string? Lang { get; init; }
    
    /// <summary>
    /// USD price for non-foil.
    /// </summary>
    public decimal? PricesUsd { get; init; }
    
    /// <summary>
    /// USD price for foil.
    /// </summary>
    public decimal? PricesUsdFoil { get; init; }
    
    #region Denormalized Oracle Fields (for App layer convenience)
    
    /// <summary>
    /// Mana cost in Scryfall notation (e.g., "{2}{U}{U}").
    /// Denormalized from Oracle.
    /// </summary>
    public string? ManaCost { get; init; }
    
    /// <summary>
    /// Full type line (e.g., "Legendary Creature — Human Wizard").
    /// Denormalized from Oracle.
    /// </summary>
    public string? TypeLine { get; init; }
    
    /// <summary>
    /// Official Oracle rules text.
    /// Denormalized from Oracle.
    /// </summary>
    public string? OracleText { get; init; }
    
    /// <summary>
    /// Power for creatures (may contain non-numeric values like "*").
    /// Denormalized from Oracle.
    /// </summary>
    public string? Power { get; init; }
    
    /// <summary>
    /// Toughness for creatures (may contain non-numeric values like "*").
    /// Denormalized from Oracle.
    /// </summary>
    public string? Toughness { get; init; }
    
    #endregion
    
    #region Compatibility Aliases
    
    /// <summary>
    /// Alias for ImageUri for compatibility.
    /// </summary>
    public string? ImageUrl => ImageUri;
    
    /// <summary>
    /// Alias for PricesUsd for compatibility.
    /// </summary>
    public decimal? Price => PricesUsd;
    
    /// <summary>
    /// Alias for Id (Scryfall ID) for compatibility.
    /// </summary>
    public string ScryfallId => Id;
    
    /// <summary>
    /// Alias for PricesUsd for compatibility.
    /// </summary>
    public decimal? PriceUsd => PricesUsd;
    
    #endregion
}
