#nullable enable
using Baya.Application.Contracts.Payments;
using Baya.Domain.Entities.Bnpl;

namespace Baya.Infrastructure.CrossCutting.Seams.Real;

/// <summary>
/// Real <see cref="IBnplProviderResolver"/> (refinement-phase-8, 6.2) — maps each <c>provider_code</c> to its
/// concrete adapter, config-selected, <b>never an <c>if (mock)</c> in a handler</b>. Selected by
/// <c>Seams:Bnpl:Provider = real</c>.
///
/// <list type="bullet">
///   <item><c>snapppay</c> → <see cref="SnappPayBnplProvider"/>.</item>
///   <item><c>digipay</c> → <see cref="DigipayBnplProvider"/>.</item>
///   <item><c>balinyaar</c> → the <b>in-house</b> plan (<see cref="Seams.MockBnplProvider"/>). <b>REQ-022 decision:</b>
///     Balinyaar's own installment plan has no external provider API — it is financed in-house and modelled
///     identically to the external rails (a card payment landing net-of-fee, provider-financed). So it resolves
///     to the deterministic net-of-fee adapter, not an HTTP call. The distinction is the financing entity, not
///     the money mechanics.</item>
///   <item><c>tara</c> / <c>torobpay</c> → <c>null</c> (no adapter built yet) so the handler rejects them cleanly
///     rather than silently financing through the wrong provider.</item>
/// </list>
/// </summary>
public sealed class ConfiguredBnplProviderResolver(
    SnappPayBnplProvider snappPay,
    DigipayBnplProvider digipay,
    Seams.MockBnplProvider inHouse) : IBnplProviderResolver
{
    public IBnplProvider? Resolve(string providerCode) => providerCode switch
    {
        BnplProviderCodes.SnappPay => snappPay,
        BnplProviderCodes.Digipay => digipay,
        BnplProviderCodes.Balinyaar => inHouse,
        _ => null,
    };
}
