#nullable enable
using System;
using System.Threading;
using System.Threading.Tasks;
using Baya.Application.Features.Booking.Commands.ExpireBookingRequests;
using Mediator;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Baya.Infrastructure.Persistence.Services.Scheduling.Jobs;

/// <summary>
/// Auto-expires stale <c>booking_requests</c> (re-homed from the b8 <c>BookingRequestExpiryHostedService</c>).
/// Each run sends <see cref="ExpireBookingRequestsCommand"/>, which transitions stale rows
/// (<c>expired_no_response</c> / <c>payment_deadline_expired</c>) in bounded, idempotent batches. The interval
/// is a short constant because the payment window is only 30 minutes; there is no cadence config key for it.
/// Also reachable via the admin manual trigger.
/// </summary>
internal sealed class BookingRequestExpiryJob(ILogger<BookingRequestExpiryJob> logger) : IRecurringJob
{
    public string Name => "booking_request_expiry";

    public ValueTask<TimeSpan> GetIntervalAsync(IServiceProvider services, CancellationToken cancellationToken)
        => ValueTask.FromResult(TimeSpan.FromMinutes(1));

    public async ValueTask RunAsync(IServiceProvider services, CancellationToken cancellationToken)
    {
        var sender = services.GetRequiredService<ISender>();
        var result = await sender.Send(new ExpireBookingRequestsCommand(), cancellationToken);

        if (result.IsSuccess && result.Result is { } counts && (counts.ExpiredNoResponse > 0 || counts.PaymentDeadlineExpired > 0))
            logger.LogInformation(
                "Booking-request expiry swept {NoResponse} expired-no-response and {PaymentExpired} payment-window-expired requests",
                counts.ExpiredNoResponse, counts.PaymentDeadlineExpired);
    }
}
