"""Main Typer application entry point for Paracord CLI."""

from typing import Annotated

import typer

from paracord import __version__, __app_name__
from paracord.auth.config import (
    get_current_environment,
    get_authenticated_orgs,
    clear_all_credentials,
    get_user_email,
)
from paracord.auth.flow import perform_login
from paracord.commands.auth import auth_app
from paracord.commands.bug import bug
from paracord.commands.console import console_app
from paracord.commands.init import init
from paracord.commands.run import run
from paracord.commands.sync import sync_app
from paracord.commands.update import update
from paracord.commands.upload import upload_app
from paracord.commands.check import check
from paracord.commands.component import component_app
from paracord.commands.org import org_app
from paracord.utils.console import console, print_warning, print_header, print_success, print_error, print_info
from paracord.utils.version_check import check_for_updates


app = typer.Typer(
    name=__app_name__,
    help="A modern CLI tool for Paracord projects.",
    no_args_is_help=True,
    rich_markup_mode="rich",
)


def version_callback(value: bool) -> None:
    """Print version and exit."""
    if value:
        env = get_current_environment()
        version_str = f"{__app_name__} version {__version__}"
        if env == "development":
            version_str += " (development)"
        console.print(version_str)
        raise typer.Exit()


@app.callback()
def main(
    version: bool = typer.Option(
        None,
        "--version", "-v",
        help="Show version and exit.",
        callback=version_callback,
        is_eager=True,
    ),
) -> None:
    """Paracord CLI - A unified developer experience for Paracord projects.

    Wraps copier, uv, and rav into a single, modern CLI tool.
    """
    latest = check_for_updates()
    if latest:
        print_warning(
            f"A new version of paracord is available: {latest} (current: {__version__})\n"
            f"  Update with: [command]uv tool upgrade paracord[/command]"
        )


# --- Top-level login/logout commands ---


@app.command(name="login")
def login(
    environment: Annotated[
        str | None,
        typer.Option("--env", "-e", help="Environment: development or production"),
    ] = None,
) -> None:
    """Log in to Paracord via browser."""
    env = environment or get_current_environment()
    if env == "development":
        print_header("Paracord Login", f"Environment: {env}")
    else:
        print_header("Paracord Login")

    console.print("\n[info]Opening browser for authentication...[/info]")
    console.print("[dim]Waiting for you to complete login in browser...[/dim]\n")

    credentials = perform_login(env)

    if credentials:
        print_success(f"Logged in as {credentials['user_email']}")
        print_info(f"Organization: {credentials['organization_name']}")

        # Show tip about per-directory org selection
        orgs = get_authenticated_orgs(env)
        if len(orgs) > 1:
            console.print(
                "\n[dim]Tip: You have multiple organizations. "
                "Use [command]paracord org[/command] to select one for this directory.[/dim]"
            )
    else:
        print_error("Login failed or was cancelled")
        raise typer.Exit(1)


@app.command(name="logout")
def logout() -> None:
    """Log out from Paracord (clears all credentials)."""
    env = get_current_environment()
    orgs = get_authenticated_orgs(env)
    user_email = get_user_email()

    if not orgs:
        print_warning("Not logged in")
        return

    clear_all_credentials()

    if user_email:
        print_success(f"Logged out {user_email}")
    else:
        print_success("Logged out from all organizations")


# --- Register commands ---

app.command(name="bug", help="Report a bug to GitHub.")(bug)
app.command(name="init", help="Create a new Paracord project from the template.")(init)
app.command(name="run", help="Run a rav task in the current project.")(run)
app.command(name="update", help="Update the project from the upstream template.")(update)
app.command(name="check", help="Check for template updates without applying them.")(check)

# Register component command group with alias
app.add_typer(component_app, name="component")
app.add_typer(component_app, name="comp", hidden=True)  # shorthand alias

# Register org, sync, upload, console, and auth command groups
app.add_typer(org_app, name="org")
app.add_typer(sync_app, name="sync")
app.add_typer(upload_app, name="upload")
app.add_typer(console_app, name="console")
app.add_typer(auth_app, name="auth")  # Hidden, for env switching and status


if __name__ == "__main__":
    app()
