using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WishNinja.Data;

namespace WishNinja.Services;

/// <summary>
/// Runs once at startup: applies EF migrations and seeds the Admin/User roles plus a bootstrap
/// admin account from SEED_ADMIN_EMAIL / SEED_ADMIN_PASSWORD so there is always a way in.
/// </summary>
public static class StartupInitializer
{
    public const string AdminRole = "Admin";
    public const string UserRole = "User";

    public static async Task InitializeAsync(IServiceProvider services, IConfiguration config, ILogger logger)
    {
        using var scope = services.CreateScope();
        var sp = scope.ServiceProvider;

        var db = sp.GetRequiredService<ApplicationDbContext>();
        await db.Database.MigrateAsync();

        var roleManager = sp.GetRequiredService<RoleManager<IdentityRole>>();
        foreach (var role in new[] { AdminRole, UserRole })
        {
            if (!await roleManager.RoleExistsAsync(role))
                await roleManager.CreateAsync(new IdentityRole(role));
        }

        var adminEmail = config["SEED_ADMIN_EMAIL"];
        var adminPassword = config["SEED_ADMIN_PASSWORD"];
        if (string.IsNullOrWhiteSpace(adminEmail) || string.IsNullOrWhiteSpace(adminPassword))
        {
            logger.LogWarning("SEED_ADMIN_EMAIL / SEED_ADMIN_PASSWORD not set — no bootstrap admin created.");
            return;
        }

        var userManager = sp.GetRequiredService<UserManager<ApplicationUser>>();
        var existing = await userManager.FindByEmailAsync(adminEmail);
        if (existing is null)
        {
            var admin = new ApplicationUser
            {
                UserName = adminEmail,
                Email = adminEmail,
                EmailConfirmed = true,
                DisplayName = "Administrator",
            };
            var result = await userManager.CreateAsync(admin, adminPassword);
            if (result.Succeeded)
            {
                await userManager.AddToRoleAsync(admin, AdminRole);
                logger.LogInformation("Created bootstrap admin {Email}", adminEmail);
            }
            else
            {
                logger.LogError("Failed to create bootstrap admin: {Errors}",
                    string.Join("; ", result.Errors.Select(e => e.Description)));
            }
        }
        else if (!await userManager.IsInRoleAsync(existing, AdminRole))
        {
            await userManager.AddToRoleAsync(existing, AdminRole);
            logger.LogInformation("Granted Admin role to existing user {Email}", adminEmail);
        }
    }
}
