"""
Module: main
Description: Main CLI entry point for Huitzo

Implements:
    - docs/cli/reference.md
    - docs/guides/developer-environment.md#cli-interface

See Also:
    - docs/architecture/overview.md (for platform architecture)
"""

from __future__ import annotations

import sys
from typing import Literal

import typer
from rich.console import Console

from huitzo_cli.commands.add_command import add_command
from huitzo_cli.commands.auth import login, logout
from huitzo_cli.commands.build import build
from huitzo_cli.commands.config_cmd import config_app
from huitzo_cli.commands.dashboard import dashboard_app
from huitzo_cli.commands.dev import dev
from huitzo_cli.commands.exec_cmd import describe_command, exec_command, list_commands
from huitzo_cli.commands.init import init
from huitzo_cli.commands.registry import install, list_packs, publish, run
from huitzo_cli.commands.sandbox import sandbox_app
from huitzo_cli.commands.secrets import secrets_app
from huitzo_cli.commands.status import status
from huitzo_cli.commands.test import test
from huitzo_cli.commands.validate import validate
from huitzo_cli.config import ConfigManager
from huitzo_cli.output import OutputContext
from huitzo_cli.telemetry import prompt_telemetry_opt_in
from huitzo_cli.version import get_version

app = typer.Typer(help="Huitzo CLI for developing Intelligence Packs")


def _make_output(mode: Literal["human", "json"]) -> OutputContext:
    """Create an OutputContext with the appropriate console for the mode."""
    if mode == "json":
        console = Console(no_color=True, highlight=False, markup=False)
    else:
        console = Console()
    return OutputContext(mode=mode, console=console)


@app.callback(invoke_without_command=True)
def main(
    ctx: typer.Context,
    version: bool = typer.Option(False, "--version", help="Show version and exit"),
    verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose output"),
    quiet: bool = typer.Option(False, "--quiet", "-q", help="Suppress output"),
    config: str | None = typer.Option(None, "--config", help="Path to config file"),
    output: str = typer.Option("human", "--output", help="Output format: human or json"),
    non_interactive: bool = typer.Option(
        False, "--non-interactive", "-n", help="Fail instead of prompting for input"
    ),
) -> None:
    """Huitzo CLI for developing Intelligence Packs."""
    output_mode: Literal["human", "json"] = "json" if output == "json" else "human"
    out = _make_output(output_mode)

    if version:
        if out.is_json:
            out.success({"version": get_version()})
        else:
            out.console.print(f"huitzo-cli {get_version()}")
        raise typer.Exit(0)

    # Non-interactive mode is implied by JSON output
    is_non_interactive = non_interactive or out.is_json

    # Store options in context for subcommands
    ctx.obj = {
        "verbose": verbose,
        "quiet": quiet,
        "config": config,
        "output": out,
        "output_mode": output_mode,
        "non_interactive": is_non_interactive,
    }

    # Opt-in telemetry prompt on first run (skip in non-interactive mode)
    if ctx.invoked_subcommand is not None and not is_non_interactive:
        try:
            cfg = ConfigManager()
            prompt_telemetry_opt_in(cfg)
        except Exception:
            pass  # Never block CLI on telemetry issues

    if ctx.invoked_subcommand is None and not version:
        out.print(ctx.get_help())


# Top-level shortcuts
app.command("login")(login)
app.command("logout")(logout)
app.command("run")(run)
app.command("status")(status)

# Pack subcommand group
pack_app = typer.Typer(help="Pack operations")
pack_app.command("new")(init)
pack_app.command("validate")(validate)
pack_app.command("test")(test)
pack_app.command("build")(build)
pack_app.command("dev")(dev)
pack_app.command("publish")(publish)
pack_app.command("install")(install)
pack_app.command("list")(list_packs)
pack_app.command("run")(run)
pack_app.command("add-command")(add_command)
pack_app.command("exec")(exec_command)
pack_app.command("list-commands")(list_commands)
pack_app.command("describe")(describe_command)

# Register command groups
app.add_typer(pack_app, name="pack", help="Pack operations")
app.add_typer(config_app, name="config", help="Manage configuration")
app.add_typer(secrets_app, name="secrets", help="Manage secrets")
app.add_typer(dashboard_app, name="dashboard", help="Dashboard operations")
app.add_typer(sandbox_app, name="sandbox", help="Manage local sandbox")


def _safe_main() -> None:
    """Run the CLI app with global exception handling to prevent traceback leaks."""
    from huitzo_cli.errors import HuitzoCliError
    from huitzo_cli.exit_codes import GENERAL, INTERRUPT, code_for_error

    _console = Console(stderr=True)

    try:
        app()
    except KeyboardInterrupt:
        _console.print("\nInterrupted.")
        sys.exit(INTERRUPT)
    except SystemExit:
        raise
    except HuitzoCliError as exc:
        code = code_for_error(exc)
        # If JSON mode was set, emit structured error to stderr
        _console.print(f"[red]{exc.user_message}[/red]")
        sys.exit(code)
    except Exception:
        _console.print("[red]An unexpected error occurred. Please report this issue.[/red]")
        sys.exit(GENERAL)


if __name__ == "__main__":
    _safe_main()
