using Indotalent.ConfigBackEnd;
using Indotalent.ConfigBackEnd.Middleware;
using Indotalent.ConfigFrontEnd;
using Indotalent.ConfigFrontEnd.Filter;
using Indotalent.Data.Entities;
using Indotalent.Features;
using Indotalent.Features.Account;
using Indotalent.Features.Root;
using Indotalent.Infrastructure;
using Indotalent.Infrastructure.Database;
using Indotalent.Infrastructure.Logging.Serilog;
using Microsoft.OpenApi;
using MudBlazor.Services;
using QuestPDF.Infrastructure;
using Serilog;



//private and non profit. commercial less than 1 million USD
//ref: https://www.questpdf.com/license/
QuestPDF.Settings.License = LicenseType.Community;

var builder = WebApplication.CreateBuilder(args);

builder.AddSerilogBuilder();

builder.Services.AddHttpContextAccessor();

builder.Services.AddConfigBackEndDI();

builder.Services.AddInfrastructureDI(builder.Configuration);

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddHubOptions(options =>
    {
        options.MaximumReceiveMessageSize = null; //null => for unlimited
    });

builder.Services.AddMudServices();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo { Title = "API", Version = "v1" });
    options.CustomSchemaIds(type => type.FullName);
});

builder.Services.AddConfigFrontEndDI();
builder.Services.AddFeaturesDI();

builder.Services.AddRazorPages(options =>
{
    options.RootDirectory = "/Features";
});

var app = builder.Build();

app.MapRazorPages();

app.UseMiddleware<ExceptionHandlingMiddleware>();

app.MapGroup("/api/account").WithTags("Account").MapIdentityApi<ApplicationUser>();

using (var scope = app.Services.CreateScope())
{
    var settings = app.Configuration.GetSection("DatabaseSettings").Get<DatabaseSettingsModel>();
    if (settings?.MsSQL?.IsUsed == true ||
        settings?.PostgreSQL?.IsUsed == true ||
        settings?.MySQL?.IsUsed == true)
    {
        var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        context.Database.EnsureCreated();

        await DatabaseSeeder.SeedAsync(scope.ServiceProvider);
    }
}

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

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    app.UseHsts();
}

app.MapSwagger().RequireAuthorization();

app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

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

app.MapStaticAssets();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.MapControllers();

var apiGroup = app.MapGroup("/api").AddEndpointFilter<CurrentUserFilter>();

apiGroup.MapAccountEndpoints();
apiGroup.MapFeaturesEndpoint();

try
{
    Log.Information("Starting Web Application...");
    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();
}