using Autofac;
using Autofac.Extensions.DependencyInjection;
using e_suite.Database.SqlServer;
using e_suite.Nuget.PasswordHasher;
using eSuite.API.DependencyInjection;
using eSuite.API.HealthChecks;
using eSuite.API.Middleware;
using eSuite.API.Swagger;
using eSuite.API.Translation;
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerUI;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureContainer<ContainerBuilder>(builder =>
    {
        builder.RegisterModule(new CoreRegistrationModule());
    });

// Add services to the container.

//builder.Services.AddCors(options =>
//{
//    options.AddDefaultPolicy(
//        builder =>
//        {
//            //todo lock this down
//            //builder.WithOrigins("https://localhost")
//            //.WithMethods("PUT", "DELETE", "GET", "POST");
//            builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); // allow any origin;
//        });
//});

builder.AddDatabaseContext();
builder.AddTokenAuthentication();
builder.Services.AddCustomPasswordHasher(builder.Configuration);
builder.Services.AddControllersWithViews()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        //todo add support for OneOf
        //Add the OneOf nuget package, before uncommenting this, to allow properties to be mapped to     public Oneof<string,int> test {get;set;}
        //options.JsonSerializerOptions.Converters.Add(new OneOf.OneOfJsonConverter());//todo add support for OneOf
        //Add the OneOf nuget package, before uncommenting this, to allow properties to be mapped to     public Oneof<string,int> test {get;set;}
        //options.JsonSerializerOptions.Converters.Add(new OneOf.OneOfJsonConverter());
        options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
    });
builder.AddSwagger();
builder.Services.AddHealthChecks()
    .AddSqlServer(ESuiteDatabaseExtension.BuildConnectionString(builder.Configuration), name:"Database Server")
    .AddDbContextCheck<SqlEsuiteDatabaseDbContext>("Database Context")
    .AddCheck("Mail Server", () => SmtpHealthCheck.Healthy(builder.Configuration, new SocketFactory()));
builder.Services.AddAntiforgery(options => options.HeaderName = "XSRF-TOKEN");

//builder.Services.Configure<FrontendSettings>(builder.Configuration);
//builder.Services.AddHttpClient<IJsonLocalizationService, JsonLocalizationService>()
//    .ConfigureHttpClient((sp, client) =>
//    {
//        var settings = sp.GetRequiredService<IOptions<FrontendSettings>>().Value;

//        // Ensure trailing slash
//        var baseUrl = settings.BaseUrl.EndsWith("/")
//            ? settings.BaseUrl
//            : settings.BaseUrl + "/";

//        client.BaseAddress = new Uri(baseUrl);
//    });


var app = builder.Build();

using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
}

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseStaticFiles();
    app.UseSwagger();
    app.UseSwaggerUI(o =>
    {
        o.DocExpansion(DocExpansion.None);
        o.InjectStylesheet("/swagger-ui/SwaggerDark.css");
        o.SwaggerEndpoint("/swagger/v1/swagger.json", "e-suite API");
    });
}

//app.UseCors();
//app.UseMiddleware<OptionsMiddleware>();
//app.UseHttpsRedirection();
app.MapHealthChecks("/healthz", new HealthCheckOptions //note: name healthz is intentional. https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-7.0
{
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
app.UseMiddleware<ExceptionCapture>();

app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<SecurityAccessMiddleWare>();

app.MapControllers().RequireAuthorization(); //This ensures that ALL API calls need a Bearer token, unless marked [AllowAnonymous] DO NOT REMOVE!

app.Run();


public class FrontendSettings
{
    public string BaseUrl { get; set; }
}
