using Baya.Application.Contracts.Common;
using Baya.Infrastructure.CrossCutting.Seams;
using Microsoft.Extensions.DependencyInjection;

namespace Baya.Infrastructure.CrossCutting.ServiceConfiguration;

public static class DevelopmentSeamExtensions
{
    /// <summary>
    /// Development-only wiring for the OTP bring-up bridge. Registers <see cref="DevOtpStore"/> and decorates
    /// the <see cref="ISmsSender"/> registered by <c>AddCrossCuttingSeams</c> (the log-only
    /// <see cref="LoggingSmsSender"/>) with <see cref="DevCapturingSmsSender"/>, so each OTP is also captured
    /// in memory for <c>/api/v1/dev/last_otp/{phone}</c> to serve. MUST be called only inside
    /// <c>builder.Environment.IsDevelopment()</c>: nothing here is wired in any other environment, which —
    /// together with the endpoint's own <c>IsDevelopment()</c> guard — makes the OTP echo impossible to enable
    /// outside Development. Superseded by the real SMS gateway in refinement Phase 8.
    /// </summary>
    public static IServiceCollection AddDevelopmentOtpCapture(this IServiceCollection services)
    {
        services.AddSingleton<DevOtpStore>();

        // Re-register ISmsSender as the capturing decorator over a fresh LoggingSmsSender (built through DI so
        // it still gets its ILogger). The last registration wins for a single resolve, so callers transparently
        // get the decorator; the code is still logged exactly as before, just also captured for the dev endpoint.
        services.AddSingleton<ISmsSender>(sp => new DevCapturingSmsSender(
            ActivatorUtilities.CreateInstance<LoggingSmsSender>(sp),
            sp.GetRequiredService<DevOtpStore>()));

        return services;
    }

    /// <summary>
    /// Development/Testing-only re-registration of the real <see cref="MockPaymentCaptureSimulator"/> over the
    /// production <see cref="DisabledPaymentCaptureSimulator"/> (refinement-phase-8, 6.4). The <c>bookings/convert</c>
    /// simulator path is a dev/test affordance — production converts via the real b10 webhook confirm, not this
    /// command. Last registration wins, so callers transparently get the succeeding mock in Dev/Testing.
    /// </summary>
    public static IServiceCollection AddDevelopmentPaymentCapture(this IServiceCollection services)
    {
        services.AddSingleton<IPaymentCaptureSimulator, MockPaymentCaptureSimulator>();
        return services;
    }
}
