using System.ComponentModel.DataAnnotations;
using System.Linq;
using Asp.Versioning;
using Baya.Application.Features.Payments.Commands.InitiatePayment;
using Baya.Application.Models.Payments;
using Baya.WebFramework.Attributes;
using Baya.WebFramework.BaseController;
using Baya.WebFramework.ServiceConfiguration;
using Mediator;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;

namespace Baya.Web.Api.Controllers.V1;

/// <summary>
/// The customer-facing card-payment start. A booking exists only on capture, so a payment is initiated against
/// the accepted <c>booking_requests</c> id; the money charged is the request's frozen gross. Rate-limited as a
/// money endpoint and idempotency-keyed (the <c>Idempotency-Key</c> header) so a retried start reuses the same
/// attempt. Internal account types are never exposed here — the response is just the redirect + the attempt id.
/// </summary>
[ApiVersion("1")]
[ApiController]
[Route("api/v{version:apiVersion}/bookings")]
[Authorize]
[Display(Description = "Card payment initiation against an accepted booking request")]
public sealed class PaymentsController(ISender sender) : BaseController
{
    [HttpPost("{bookingRequestId}/payments")]
    [EnableRateLimiting(RateLimitingServiceExtension.SensitivePolicy)]
    [ProducesOkApiResponseType<InitiatePaymentResult>]
    public async Task<IActionResult> Initiate(long bookingRequestId, CancellationToken cancellationToken)
    {
        var idempotencyKey = Request.Headers["Idempotency-Key"].FirstOrDefault();
        return OperationResult(await sender.Send(new InitiatePaymentCommand(bookingRequestId, idempotencyKey), cancellationToken));
    }
}
