namespace Baya.Domain.Entities.Bnpl;

/// <summary>
/// The forward-only allowed-edge table for the <see cref="BnplStatus"/> machine (mirrors
/// <c>BookingRequestTransitions</c>/<c>RefundTransitions</c>). Every write goes through
/// <see cref="BnplTransaction"/>'s cohesive mark-* methods, which assert the edge here — an illegal transition
/// throws, and a replayed callback that would re-drive a completed transition is rejected before it can
/// re-post the ledger. Terminal states have no outgoing edge.
/// </summary>
public static class BnplTransitions
{
    private static readonly IReadOnlyDictionary<string, IReadOnlyCollection<string>> Allowed =
        new Dictionary<string, IReadOnlyCollection<string>>
        {
            [BnplStatus.Eligible] = [BnplStatus.TokenIssued, BnplStatus.Failed, BnplStatus.Cancelled],
            [BnplStatus.TokenIssued] = [BnplStatus.Verified, BnplStatus.Failed, BnplStatus.Cancelled],
            [BnplStatus.Verified] = [BnplStatus.Settled, BnplStatus.Failed, BnplStatus.Reverted, BnplStatus.Cancelled],
            [BnplStatus.Settled] = [BnplStatus.Reverted],
            // Terminal states — no outgoing edges.
            [BnplStatus.Reverted] = [],
            [BnplStatus.Cancelled] = [],
            [BnplStatus.Failed] = []
        };

    public static bool CanTransition(string from, string to)
        => Allowed.TryGetValue(from, out var targets) && targets.Contains(to);
}
