namespace Baya.Domain.Entities.Payouts;

/// <summary>
/// The forward-only allowed-edge table for the <see cref="PayoutStatus"/> machine (mirrors
/// <c>BnplTransitions</c>/<c>RefundTransitions</c>). Every write goes through <see cref="NursePayout"/>'s
/// cohesive mark-* methods, which assert the edge here — so a replayed execute that would re-drive an
/// already-<see cref="PayoutStatus.Paid"/> row is rejected before it can re-send an irreversible transfer or
/// re-post the ledger. <see cref="PayoutStatus.Failed"/> is the only re-enterable state (a retry re-submits).
/// </summary>
public static class PayoutStatusTransitions
{
    private static readonly IReadOnlyDictionary<string, IReadOnlyCollection<string>> Allowed =
        new Dictionary<string, IReadOnlyCollection<string>>
        {
            [PayoutStatus.Pending] = [PayoutStatus.Submitted, PayoutStatus.Failed],
            [PayoutStatus.Submitted] = [PayoutStatus.Paid, PayoutStatus.Failed],
            // A rejected transfer can be re-submitted.
            [PayoutStatus.Failed] = [PayoutStatus.Submitted],
            // Terminal on success — no outgoing edge (paid is an irreversible transfer).
            [PayoutStatus.Paid] = []
        };

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