using Microsoft.EntityFrameworkCore;
using NLog.Web;
using OpenIddict.Validation.AspNetCore;
using RobotNet.MapManager.Data;
using RobotNet.MapManager.Hubs;
using RobotNet.MapManager.Services;
using RobotNet.OpenIddictClient;
using System.Globalization;

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseNLog();

// builder.AddServiceDefaults();

// Add services to the container.
var openIddictOption = builder.Configuration.GetSection(nameof(OpenIddictClientProviderOptions)).Get<OpenIddictClientProviderOptions>()
    ?? throw new InvalidOperationException("OpenID configuration not found or invalid format.");

builder.Services.AddControllers();
builder.Services.AddSignalR();
builder.Services.AddOpenIddict()
    .AddValidation(options =>
    {
        // Note: the validation handler uses OpenID Connect discovery
        // to retrieve the address of the introspection endpoint.
        options.SetIssuer(openIddictOption.Issuer);
        options.AddAudiences(openIddictOption.Audiences);

        // Configure the validation handler to use introspection and register the client
        // credentials used when communicating with the remote introspection endpoint.
        options.UseIntrospection()
               .SetClientId(openIddictOption.ClientId)
               .SetClientSecret(openIddictOption.ClientSecret);

        // Register the System.Net.Http integration.
        if (builder.Environment.IsDevelopment())
        {
            options.UseSystemNetHttp(httpOptions =>
            {
                httpOptions.ConfigureHttpClientHandler(context =>
                {
                    context.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => true;
                });
            });
        }
        else
        {
            options.UseSystemNetHttp();
        }

        // Register the ASP.NET Core host.
        options.UseAspNetCore();
    });

builder.Services.AddAuthentication(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
builder.Services.AddAuthorization();

builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader();
    });
});


// Add services to the container.

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
Action<DbContextOptionsBuilder> appDbOptions = options => options.UseSqlServer(connectionString, b => b.MigrationsAssembly("RobotNet.MapManager"));
builder.Services.AddDbContext<MapEditorDbContext>(appDbOptions);

builder.Services.AddSingleton<MapEditorStorageRepository>();
builder.Services.AddSingleton(typeof(LoggerController<>));

var app = builder.Build();
await app.Services.SeedMapManagerDbAsync();
// Configure the HTTP request pipeline.

app.UseHttpsRedirection();

app.UseCors();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.MapHub<MapHub>("/hubs/map/data");

app.Run();