using Microsoft.EntityFrameworkCore;

/// <summary>
/// One-shot bootstrap: creates the first Admin user when the ClinicalUsers
/// table is empty. Refuses to run if any user already exists so it cannot
/// be used as a backdoor after the system is in use.
///
/// Usage:
///   dotnet VigilCareClinicalAPI.dll create-admin --username &lt;u&gt; --password &lt;p&gt; --display-name "&lt;n&gt;"
/// </summary>
public static class CreateAdminCommand
{
    public static async Task<int> RunAsync(IServiceProvider services, string[] args)
    {
        var username = RequireArg(args, "--username");
        var password = RequireArg(args, "--password");
        var displayName = RequireArg(args, "--display-name");

        if (username.Length > 100)
        {
            Console.Error.WriteLine("Username must be 100 characters or fewer.");
            return 1;
        }

        if (password.Length < 8)
        {
            Console.Error.WriteLine("Password must be at least 8 characters.");
            return 1;
        }

        if (displayName.Length > 200)
        {
            Console.Error.WriteLine("Display name must be 200 characters or fewer.");
            return 1;
        }

        using var scope = services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();

        if (await db.ClinicalUsers.AnyAsync())
        {
            Console.Error.WriteLine(
                "Refusing to create admin: ClinicalUsers already contains at least one row. " +
                "create-admin is a one-shot bootstrap and cannot be used as a backdoor.");
            return 1;
        }

        var user = new ClinicalUser
        {
            Id = Guid.NewGuid(),
            Username = username.Trim(),
            PasswordHash = BCrypt.Net.BCrypt.HashPassword(password),
            DisplayName = displayName.Trim(),
            Role = ClinicalRole.Admin,
            IsActive = true,
            CreatedAt = DateTimeOffset.UtcNow,
        };

        db.ClinicalUsers.Add(user);
        await db.SaveChangesAsync();

        Console.WriteLine($"Created admin user '{user.Username}' (id={user.Id}).");
        return 0;
    }

    private static string RequireArg(string[] args, string name)
    {
        for (var i = 0; i < args.Length - 1; i++)
        {
            if (string.Equals(args[i], name, StringComparison.OrdinalIgnoreCase))
            {
                var value = args[i + 1];
                if (string.IsNullOrWhiteSpace(value) || value.StartsWith("--", StringComparison.Ordinal))
                    break;
                return value;
            }
        }

        throw new ArgumentException($"Missing required argument: {name}");
    }
}
