namespace Baya.Domain.Entities.Booking;

/// <summary>
/// The forward-only status machine for <see cref="BookingRequest"/>. Every accept/reject/cancel/expire/
/// convert edge is validated here, so an illegal transition is a clean conflict (never a silent overwrite),
/// and the terminal states have no outgoing edge. b9 reuses this pattern for the <c>bookings</c> machine.
/// </summary>
public static class BookingRequestTransitions
{
    private static readonly IReadOnlyDictionary<string, IReadOnlyCollection<string>> Allowed =
        new Dictionary<string, IReadOnlyCollection<string>>
        {
            [BookingRequestStatus.PendingNurseResponse] =
            [
                BookingRequestStatus.AcceptedAwaitingPayment,
                BookingRequestStatus.RejectedByNurse,
                BookingRequestStatus.ExpiredNoResponse,
                BookingRequestStatus.CancelledByCustomer
            ],
            [BookingRequestStatus.AcceptedAwaitingPayment] =
            [
                BookingRequestStatus.Converted,
                BookingRequestStatus.PaymentDeadlineExpired,
                BookingRequestStatus.CancelledByCustomer
            ],
            // Terminal states — no outgoing edges.
            [BookingRequestStatus.Converted] = [],
            [BookingRequestStatus.RejectedByNurse] = [],
            [BookingRequestStatus.ExpiredNoResponse] = [],
            [BookingRequestStatus.PaymentDeadlineExpired] = [],
            [BookingRequestStatus.CancelledByCustomer] = []
        };

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