import sys
from typing import Annotated

from typer import Exit, Option, Typer, echo

from harbor.auth.errors import AuthenticationError
from harbor.cli.utils import run_async
from harbor.constants import HARBOR_REGISTRY_WEBSITE_URL

auth_app = Typer(no_args_is_help=True)


@auth_app.command()
def login(
    no_browser: Annotated[
        bool,
        Option("--no-browser", help="Do not attempt to automatically open a browser."),
    ] = False,
    callback_url: Annotated[
        str | None,
        Option(
            "--callback-url",
            help="Paste the full OAuth callback URL after completing sign-in.",
        ),
    ] = None,
) -> None:
    """Authenticate with Harbor via GitHub OAuth."""

    async def _login():
        from harbor.auth.handler import get_auth_handler

        handler = await get_auth_handler()
        is_interactive = sys.stdin.isatty() and sys.stdout.isatty()
        try:
            user_id = await handler.login(
                callback_url=callback_url,
                open_browser=not no_browser,
                allow_manual=is_interactive and callback_url is None,
            )
        except AuthenticationError as exc:
            echo(f"Login failed: {exc}")
            raise Exit(1)
        echo(f"Logged in as {user_id}")
        echo(f"Visit {HARBOR_REGISTRY_WEBSITE_URL}/profile to create and manage orgs.")

    run_async(_login())


@auth_app.command()
def logout() -> None:
    """Sign out and clear stored credentials."""

    async def _logout():
        from harbor.auth.handler import get_auth_handler

        handler = await get_auth_handler()
        await handler.logout()
        echo("Logged out")

    run_async(_logout())


@auth_app.command()
def status() -> None:
    """Show current authentication status."""

    async def _status():
        from harbor.auth.handler import get_auth_handler

        handler = await get_auth_handler()
        if not await handler.is_authenticated():
            echo("Not authenticated. Run `harbor auth login`.")
            return

        username = await handler.get_github_username()
        label = username or "unknown user"
        echo(f"Logged in as {label}")

    run_async(_status())
