"""Signup 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 Confirm, Prompt, Text
from cli.infrastructure.error_display import display_usage_error
from cli.infrastructure.output import OutputService
from cli.infrastructure.provider_setup import prompt_provider_credentials
from cli.infrastructure.spinner import spinner
from alloy_runtime_sdk.api_client.client import ApiClient
from alloy_runtime_types.dtos.auth import SignupRequest


def signup_command(
    email: str | None = typer.Option(None, "-e", "--email", help="Email address"),
    password: str | None = typer.Option(
        None, "--password", help="Password (avoid: exposes in shell history)"
    ),
    name: str | None = typer.Option(None, "-n", "--name", help="Display name"),
    org_name: str | None = typer.Option(
        None,
        "--org",
        help="Organization name",
    ),
) -> None:
    """Create a new Alloy Runtime account.

    You'll be prompted to set up provider credentials after signup.

    Examples:

        alloy signup
        alloy signup -e user@example.com -n "John Doe" --org "My Company"
    """
    _execute_signup(email, password, name, org_name)


@async_command
async def _execute_signup(
    email: str | None,
    password: str | None,
    name: str | None,
    org_name: str | None,
) -> None:
    """Execute the signup operation.

    Args:
        email: Optional email (will prompt if not provided)
        password: Optional password (will prompt if not provided)
        name: Optional name (will prompt if not provided)
        org_name: Optional organization name
    """
    output = OutputService.get()
    api_url = get_api_url()

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

    if not name:
        name = Prompt.ask(Text("Your name"))

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

            if password != confirm:
                display_usage_error(
                    "Passwords do not match. Please try again.",
                    command_path="alloy signup",
                )
                continue

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

            break

    async with spinner("Creating your account..."):
        async with ApiClient(base_url=api_url, api_key="") as client:
            response = await client.signup(
                SignupRequest(
                    email=email,
                    password=password,
                    name=name,
                    organization_name=org_name,
                )
            )

    # Save credentials
    save_credentials(api_url, response.api_key)

    output.result(
        action="create",
        resource="account",
        identifier=str(response.user_id),
        name=response.email,
        extra_fields={
            "Name": response.name,
            "Organization ID": str(response.organization_id),
            "Credentials Saved": "~/.alloy-runtime/config",
        },
    )

    if Confirm.ask(Text("Set up provider credentials now?"), default=True):
        await prompt_provider_credentials(api_url, response.api_key)
    else:
        output.result(
            action="setup",
            resource="provider_credentials",
            status="pending",
            identifier=None,
            name=None,
            extra_fields={
                "Next Step": "alloy credentials update <credential-id> --value <api-key>"
            },
        )
