using LinqToDB;
using LinqToDB.Data;
using Azaion.Flights.Auth;
using Azaion.Flights.Database;
using Azaion.Flights.Middleware;
using Azaion.Flights.Services;

var builder = WebApplication.CreateBuilder(args);

var databaseUrl = builder.Configuration["DATABASE_URL"]
    ?? Environment.GetEnvironmentVariable("DATABASE_URL")
    ?? "Host=localhost;Database=azaion;Username=postgres;Password=changeme";

var connectionString = databaseUrl.StartsWith("postgresql://")
    ? ConvertPostgresUrl(databaseUrl)
    : databaseUrl;

var jwtSecret = builder.Configuration["JWT_SECRET"]
    ?? Environment.GetEnvironmentVariable("JWT_SECRET")
    ?? "development-secret-key-min-32-chars!!";

builder.Services.AddScoped(_ =>
{
    var options = new DataOptions().UsePostgreSQL(connectionString);
    return new AppDataConnection(options);
});

builder.Services.AddScoped<FlightService>();
builder.Services.AddScoped<WaypointService>();
builder.Services.AddScoped<AircraftService>();

builder.Services.AddJwtAuth(jwtSecret);
builder.Services.AddCors(options =>
    options.AddDefaultPolicy(policy =>
        policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()));

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

using (var scope = app.Services.CreateScope())
{
    var db = scope.ServiceProvider.GetRequiredService<AppDataConnection>();
    DatabaseMigrator.Migrate(db);
}

app.UseMiddleware<ErrorHandlingMiddleware>();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI();

app.MapControllers();
app.MapGet("/health", () => Results.Ok(new { status = "healthy" }));

app.Run();

static string ConvertPostgresUrl(string url)
{
    var uri = new Uri(url);
    var userInfo = uri.UserInfo.Split(':');
    var host = uri.Host;
    var port = uri.Port > 0 ? uri.Port : 5432;
    var database = uri.AbsolutePath.TrimStart('/');
    return $"Host={host};Port={port};Database={database};Username={userInfo[0]};Password={userInfo.ElementAtOrDefault(1) ?? ""}";
}
