using Backend.Common;
using Backend.Data;
using Backend.Endpoints;
using Backend.Security;
using Microsoft.EntityFrameworkCore;

namespace Backend.Extensions;

public static class WebApplicationExtensions
{
    public static void UseApplicationPipeline(this WebApplication app)
    {
        app.UseExceptionHandler();

        if (!app.Environment.IsDevelopment())
        {
            app.UseHsts();
        }

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

        app.UseCors(ApplicationDefaults.FrontendCorsPolicy);
        app.UseMiddleware<SecurityHeadersMiddleware>();
        app.UseRateLimiter();

        if (!app.Environment.IsDevelopment())
        {
            app.UseHttpsRedirection();
        }
    }

    public static async Task InitializeDatabaseAsync(this WebApplication app)
    {
        using var scope = app.Services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AwardsDbContext>();
        var logger = scope.ServiceProvider.GetRequiredService<ILoggerFactory>()
            .CreateLogger("DatabaseInitialization");

        try
        {
            if (app.Environment.IsDevelopment())
            {
                await db.Database.MigrateAsync();
            }

            await TeamAccountBootstrapper.EnsureAsync(db, app.Configuration);
        }
        catch (Exception error)
        {
            logger.LogError(error, "Database initialization failed. Check the PostgreSQL connection, migrations, and startup configuration.");
            throw;
        }
    }

    public static void MapApplicationEndpoints(this WebApplication app)
    {
        app.MapSystemEndpoints();
        app.MapAuthEndpoints();
        app.MapPublicEndpoints();
        app.MapAdminEndpoints();
    }
}
