using System.Net.Http.Headers;
using ApiOPE.Configuration;
using ApiOPE.Security;
using ApiOPE.Services;
using Microsoft.Extensions.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile(
    $"appsettings.{builder.Environment.EnvironmentName}.local.json",
    optional: true,
    reloadOnChange: false);

var allowHttpPublicBaseUrl = builder.Environment.IsDevelopment() ||
                             builder.Environment.IsEnvironment("PreproductionTest");

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton(TimeProvider.System);

builder.Services
    .AddOptions<OpeOptions>()
    .Bind(builder.Configuration.GetSection(OpeOptions.SectionName))
    .Validate(
        options => OpeOptionsValidator.IsValid(options, allowHttpPublicBaseUrl),
        "La configuracion Ope no es valida. Revisa client token, secret, URL publica, organizacion y campos de salida.")
    .ValidateOnStart();

builder.Services
    .AddOptions<InternalApiOptions>()
    .Bind(builder.Configuration.GetSection(InternalApiOptions.SectionName))
    .Validate(
        InternalApiOptionsValidator.IsValid,
        "La configuracion InternalApi no es valida. Revisa BaseUrl, ApiKey y TimeoutSeconds.")
    .ValidateOnStart();

builder.Services.AddSingleton<OpeResponseSigner>();
builder.Services.AddSingleton<OpeTokenValidator>();
builder.Services.AddSingleton<OpeFieldMapper>();

builder.Services.AddHttpClient<InternalDenunciasClient>((services, client) =>
{
    var options = services.GetRequiredService<IOptions<InternalApiOptions>>().Value;
    client.BaseAddress = new Uri(options.BaseUrl.TrimEnd('/') + "/", UriKind.Absolute);
    client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    client.DefaultRequestHeaders.TryAddWithoutValidation(options.ApiKeyHeaderName, options.ApiKey);
});

var app = builder.Build();

app.UseExceptionHandler(exceptionApp => exceptionApp.Run(OpeExceptionHandler.HandleAsync));

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

if (builder.Configuration.GetValue("ForceHttpsRedirection", false))
{
    app.UseHttpsRedirection();
}

app.UseRouting();
app.UseMiddleware<OpeAuthenticationMiddleware>();
app.MapControllers();

app.Run();

public partial class Program;
