namespace Theriapolis.Core.Rules.Combat;

/// <summary>
/// Outcome of a single <see cref="Resolver.AttemptAttack"/> call. Captures
/// every dice value for log reconstruction and test assertions.
/// </summary>
public sealed record AttackResult
{
    public required int  AttackerId      { get; init; }
    public required int  TargetId        { get; init; }
    public required string AttackName    { get; init; }
    public required int  D20Roll         { get; init; }   // the kept d20 (post advantage/disadvantage)
    public          int? D20Other        { get; init; }   // the other d20 when adv/disadv was rolled
    public required int  ToHitBonus      { get; init; }
    public required int  AttackTotal     { get; init; }   // D20Roll + ToHitBonus
    public required int  TargetAc        { get; init; }   // includes cover
    public required bool Hit             { get; init; }
    public required bool Crit            { get; init; }
    public required int  DamageRolled    { get; init; }   // 0 if missed
    public required int  TargetHpAfter   { get; init; }
    public required SituationFlags Situation { get; init; }

    public string FormatLog(string attackerName, string targetName)
    {
        if (!Hit)
            return $"{attackerName} → {targetName}: miss ({AttackName} {AttackTotal} vs AC {TargetAc})";
        string critTag = Crit ? " [CRIT]" : "";
        return $"{attackerName} → {targetName}: {DamageRolled} dmg ({AttackName} {AttackTotal} vs AC {TargetAc}){critTag} → HP {TargetHpAfter}";
    }
}
