#nullable enable
using Baya.Application.Contracts.Payments;

namespace Baya.Infrastructure.CrossCutting.Seams;

/// <summary>
/// Deterministic mock <see cref="IPaymentProvider"/> — no external call. <see cref="InitPaymentAsync"/> returns
/// a stable fake reference derived from the request + idempotency key and a fake redirect URL;
/// <see cref="VerifyAsync"/> instantly succeeds and echoes the expected amount (the server-side re-check always
/// passes in the mock); <see cref="RefundAsync"/> always succeeds (so b11 can call it). A real
/// ZarinPal/Sadad/Vandar/Jibit adapter (acquirer-with-تسهیم, Shaparak reference, sandbox flag from the
/// gateway's encrypted config) replaces this registration only — no mock behaviour is baked into a handler.
/// </summary>
public sealed class MockPaymentProvider : IPaymentProvider
{
    public ValueTask<PaymentInitResult> InitPaymentAsync(long bookingRequestId, long amountIrr, string idempotencyKey, CancellationToken cancellationToken = default)
    {
        var reference = $"mock-ref-{bookingRequestId}-{idempotencyKey}";
        return ValueTask.FromResult(new PaymentInitResult(
            RedirectUrl: $"https://mock-psp.local/pay/{reference}",
            GatewayReferenceCode: reference));
    }

    public ValueTask<PaymentVerifyResult> VerifyAsync(string gatewayReferenceCode, long expectedAmountIrr, CancellationToken cancellationToken = default)
        => ValueTask.FromResult(new PaymentVerifyResult(PaymentProviderStatus.Succeeded, expectedAmountIrr));

    public ValueTask<PaymentRefundResult> RefundAsync(string gatewayReferenceCode, long amountIrr, string idempotencyKey, CancellationToken cancellationToken = default)
        => ValueTask.FromResult(new PaymentRefundResult(PaymentProviderStatus.Succeeded, $"mock-refund-{gatewayReferenceCode}-{idempotencyKey}"));
}
