using Microsoft.EntityFrameworkCore;
using Nexus.Api.Data;
using Nexus.Api.Helpers;
using Nexus.Api.Middleware;
using Nexus.Api.Services;

namespace Nexus.Api.Extensions;

/// <summary>
/// Extension methods for configuring the Nexus application pipeline and startup.
/// </summary>
public static class ApplicationBuilderExtensions
{
    /// <summary>
    /// Applies pending EF Core migrations and seeds the initial owner account if none exist.
    /// </summary>
    public static async Task EnsureDatabaseAsync(this WebApplication app)
    {
        var configuration = app.Configuration;

        await using (var scope = app.Services.CreateAsyncScope())
        {
            var db = scope.ServiceProvider.GetRequiredService<NexusDbContext>();
            await db.Database.MigrateAsync();

            var ownerEmail = configuration["Owner:Email"]?.Trim().ToLowerInvariant();
            var ownerPassword = configuration["Owner:Password"];
            var ownerDisplayName = configuration["Owner:DisplayName"]?.Trim();
            var hasUsers = await db.Users.AnyAsync();

            if (!hasUsers)
            {
                if (string.IsNullOrWhiteSpace(ownerEmail))
                    throw new InvalidOperationException("Owner:Email is required for initial setup.");

                var initialDisplayName = string.IsNullOrWhiteSpace(ownerDisplayName)
                    ? PasswordHelper.BuildOwnerDisplayName(ownerEmail)
                    : ownerDisplayName;
                var initialPassword = string.IsNullOrWhiteSpace(ownerPassword)
                    ? PasswordHelper.GenerateTemporaryPassword()
                    : ownerPassword;

                if (!string.IsNullOrWhiteSpace(ownerPassword) && ownerPassword.Length < 10)
                    throw new InvalidOperationException("Owner:Password must be at least 10 characters when provided explicitly.");

                db.Users.Add(new NexusUser
                {
                    Email = ownerEmail,
                    NormalizedEmail = AuthService.NormalizeEmail(ownerEmail),
                    DisplayName = initialDisplayName,
                    PasswordHash = PasswordSecurity.Hash(initialPassword),
                    Role = "owner"
                });
                await db.SaveChangesAsync();

                if (string.IsNullOrWhiteSpace(ownerPassword))
                {
                    Console.Error.WriteLine($"[nexus] Initial owner credentials generated: displayName={initialDisplayName}, password={initialPassword}");
                }
            }
        }
    }

    /// <summary>
    /// Configures the HTTP middleware pipeline: forwarded headers, rate limiting, auth, security headers, and Swagger in development.
    /// </summary>
    public static IApplicationBuilder UseNexusPipeline(this IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseForwardedHeaders();
        app.UseRateLimiter();
        app.UseApiKeyAuthentication();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseSecurityHeaders();

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

        return app;
    }
}
