"""Bootstrap admin command implementation."""

import typer

from cli.infrastructure.auth_storage import save_credentials
from cli.infrastructure.command import async_command
from cli.infrastructure.config import get_api_url
from cli.infrastructure.console import Prompt
from cli.infrastructure.error_display import display_usage_error
from cli.infrastructure.output import OutputService
from cli.infrastructure.spinner import spinner
from alloy_runtime_sdk.api_client.client import ApiClient
from alloy_runtime_types.dtos.auth import BootstrapAdminRequest


def bootstrap_admin_command(
    email: str | None = typer.Option(None, "--email", "-e", help="Admin email address"),
    password: str | None = typer.Option(
        None, "--password", "-p", help="Password (not recommended for security)"
    ),
    name: str | None = typer.Option(None, "--name", "-n", help="Admin display name"),
    org_name: str = typer.Option(
        "Platform Team",
        "--org",
        "-o",
        help="Organization name for system admin",
    ),
    token: str | None = typer.Option(
        None,
        "--token",
        "-t",
        envvar="BOOTSTRAP_TOKEN",
        help="Bootstrap security token (required, can use BOOTSTRAP_TOKEN env var)",
    ),
) -> None:
    """Bootstrap the first system administrator.

    This command creates the initial system admin user when setting up
    a new instance. It can only be run ONCE - if any users already exist,
    it will fail with a safety error.

    Examples:

        # Interactive (recommended for security)
        alloy admin bootstrap

        # Non-interactive (for automation)
        alloy admin bootstrap -e admin@example.com -p SecurePass123 -n "Admin User"

    Security Notes:
        - Only works on a fresh database with no users
        - Creates a system_admin user with full privileges
        - Stores credentials securely with bcrypt
    """
    _execute_bootstrap(email, password, name, org_name, token)


@async_command
async def _execute_bootstrap(
    email: str | None,
    password: str | None,
    name: str | None,
    org_name: str,
    token: str | None,
) -> None:
    """Execute the bootstrap operation."""
    api_url = get_api_url()
    output = OutputService.get()

    # Prompt for required fields if not provided
    if not email:
        email = Prompt.ask("Admin email address")

    if not name:
        name = Prompt.ask("Admin name")

    if not token:
        token = Prompt.ask(
            "Bootstrap token (from server's BOOTSTRAP_TOKEN env var)",
            password=True,
        )

    if not password:
        while True:
            password = Prompt.ask("Password (min 8 chars)", password=True)
            confirm = Prompt.ask("Confirm password", password=True)

            if password != confirm:
                display_usage_error(
                    "Passwords don't match. Please try again.",
                    command_path="alloy admin bootstrap",
                )
                continue

            if len(password) < 8:
                display_usage_error(
                    "Password must be at least 8 characters.",
                    command_path="alloy admin bootstrap",
                )
                continue

            break

    # Create the bootstrap request
    request = BootstrapAdminRequest(
        email=email,
        password=password,
        name=name,
        organization_name=org_name,
        bootstrap_token=token,
    )

    async with spinner("Creating system administrator..."):
        async with ApiClient(base_url=api_url, api_key="") as client:
            response = await client.bootstrap_admin(request)

    # Save credentials
    save_credentials(api_url, response.api_key)

    output.result(
        action="bootstrap",
        resource="system_admin",
        identifier=str(response.user_id),
        name=response.email,
        extra_fields={
            "Name": response.name,
            "Organization": response.organization_name,
            "Organization ID": str(response.organization_id),
            "Credentials Saved": "~/.alloy-runtime/config",
            "Next Step": "alloy admin sync models",
        },
    )
