#nullable enable
using Baya.Application.Contracts.Configuration;
using Baya.Application.Contracts.Payments;
using Baya.Domain.Entities.Payouts;
using Microsoft.EntityFrameworkCore;

namespace Baya.Infrastructure.Persistence.Services.Payments;

/// <summary>
/// The <b>authoritative</b> b13 implementation of <see cref="INursePayoutStatus"/> — it answers "was the nurse
/// already paid for this booking?" from the real payout ledger: a booking is paid iff a
/// <c>nurse_payout_booking_links</c> row ties it to a <c>nurse_payouts</c> row in status <c>paid</c> (a
/// confirmed, irreversible transfer). This supersedes the b11 interim <c>NursePayoutStatusService</c> that
/// derived it from the dispute-window close. The refund pre-payout/clawback fork is unchanged — it just now
/// forks on the true paid-state. The <c>refund_assume_nurse_paid</c> config switch still forces the paid answer
/// for ops/testing.
/// </summary>
internal sealed class NursePayoutLinkStatusService(
    ApplicationDbContext dbContext,
    IPlatformConfig platformConfig) : INursePayoutStatus
{
    public async ValueTask<bool> IsNursePaidForBookingAsync(long bookingId, CancellationToken cancellationToken = default)
    {
        if (await platformConfig.GetConfig<bool>("refund_assume_nurse_paid", cancellationToken))
            return true;

        return await (from l in dbContext.Set<NursePayoutBookingLink>().AsNoTracking()
                      where l.BookingId == bookingId
                      join p in dbContext.Set<NursePayout>() on l.PayoutId equals p.Id
                      where p.Status == PayoutStatus.Paid
                      select l.Id)
            .AnyAsync(cancellationToken);
    }
}
