import os
import sys
import warnings
from typing import Optional

# Suppress Pydantic V1 compatibility warning on Python 3.14+
warnings.filterwarnings("ignore", message="Core Pydantic V1 functionality isn't compatible with Python 3.14")

import typer

from terminaluse.version import __version__


def version_callback(value: bool) -> None:
    """Print version and exit."""
    if value:
        typer.echo(f"tu {__version__}")
        raise typer.Exit()


def is_debug_mode() -> bool:
    """Check if debug mode is enabled via flag or environment variable."""
    return os.getenv("TU_DEBUG") == "1"


def is_json_mode() -> bool:
    """Check if JSON output mode is enabled via environment variable.

    Set TU_OUTPUT=json to get machine-parseable JSON error output.
    """
    return os.getenv("TU_OUTPUT", "").lower() == "json"


# Track flag states globally (set by callback, used by error handler)
_debug_flag = False
_json_flag = False


class CLIApp(typer.Typer):
    """Custom Typer app with global error handling.

    Wraps the standard Typer app to catch and format all errors consistently.
    This ensures both humans and agents get clean, parseable error output.
    """

    def __call__(self, *args, **kwargs):
        """Run the CLI with error handling wrapper."""
        from terminaluse.core.api_error import ApiError
        from terminaluse.lib.cli.utils.errors import CLIError, print_error

        try:
            return super().__call__(*args, **kwargs)
        except SystemExit:
            # Typer raises SystemExit for normal exits and typer.Exit()
            raise
        except CLIError as e:
            # CLI errors are properly formatted
            debug = _debug_flag or is_debug_mode()
            json_mode = _json_flag or is_json_mode()
            print_error(e, __version__, debug=debug, json_mode=json_mode)
            sys.exit(e.exit_code)
        except ApiError as e:
            # API errors that weren't caught by commands
            cli_error = CLIError.from_api_error(e)
            debug = _debug_flag or is_debug_mode()
            json_mode = _json_flag or is_json_mode()
            print_error(cli_error, __version__, debug=debug, json_mode=json_mode)
            sys.exit(cli_error.exit_code)
        except KeyboardInterrupt:
            # User pressed Ctrl+C
            sys.exit(130)
        except Exception as e:
            # Unexpected errors
            cli_error = CLIError.from_unexpected(e)
            debug = _debug_flag or is_debug_mode()
            json_mode = _json_flag or is_json_mode()
            print_error(cli_error, __version__, debug=debug, json_mode=json_mode)
            sys.exit(cli_error.exit_code)


# Create the main Typer application with error handling
# Note: pretty_exceptions_enable=False so our handler can format errors
app = CLIApp(
    context_settings={"help_option_names": ["-h", "--help"], "max_content_width": 800},
    pretty_exceptions_show_locals=False,
    pretty_exceptions_enable=False,
    add_completion=False,
    no_args_is_help=True,
)


@app.callback()
def main(
    ctx: typer.Context,
    version: Optional[bool] = typer.Option(
        None,
        "--version",
        "-v",
        callback=version_callback,
        is_eager=True,
        help="Show version and exit",
    ),
    debug: bool = typer.Option(
        False,
        "--debug",
        "-d",
        help="Enable debug output for troubleshooting",
    ),
    json_output: bool = typer.Option(
        False,
        "--json",
        "-j",
        help="Output errors as JSON for machine parsing",
    ),
) -> None:
    """Terminal Use CLI - Deploy and manage AI agents."""
    global _debug_flag, _json_flag
    _debug_flag = debug
    _json_flag = json_output

    # Store flags in context for access by commands
    ctx.ensure_object(dict)
    ctx.obj["debug"] = debug or is_debug_mode()
    ctx.obj["json"] = json_output or is_json_mode()


# Import commands after app is created to avoid circular imports
from terminaluse.lib.cli.commands.agents import agents
from terminaluse.lib.cli.commands.auth import login, logout, whoami
from terminaluse.lib.cli.commands.deploy import deploy
from terminaluse.lib.cli.commands.env import env
from terminaluse.lib.cli.commands.filesystem import filesystems
from terminaluse.lib.cli.commands.init import init
from terminaluse.lib.cli.commands.keys import keys
from terminaluse.lib.cli.commands.logs import logs
from terminaluse.lib.cli.commands.ls import ls
from terminaluse.lib.cli.commands.namespaces import namespaces
from terminaluse.lib.cli.commands.projects import projects
from terminaluse.lib.cli.commands.rollback import rollback
from terminaluse.lib.cli.commands.tasks import tasks
from terminaluse.lib.cli.telemetry import init_cli_telemetry

# Initialize CLI telemetry (no-op if OTEL endpoint not configured)
init_cli_telemetry()


# Authentication commands
app.command(
    help="Authenticate with the tu platform",
    rich_help_panel="Authentication",
)(login)
app.command(
    help="Log out and clear stored credentials",
    rich_help_panel="Authentication",
)(logout)
app.command(
    help="Show current authentication status",
    rich_help_panel="Authentication",
)(whoami)

# Core workflow commands
app.command(
    help="Initialize a new agent project with a template",
    rich_help_panel="Workflow",
)(init)
app.command(
    help="Deploy an agent to the tu platform",
    rich_help_panel="Workflow",
)(deploy)
app.command(
    help="List recent versions, or events for a branch",
    rich_help_panel="Workflow",
)(ls)
app.command(
    help="Rollback a branch to a previous version",
    rich_help_panel="Workflow",
)(rollback)
app.command(
    help="View logs for an agent",
    rich_help_panel="Workflow",
)(logs)

# Resource management subcommands
app.add_typer(agents, name="agents", help="Manage agents", rich_help_panel="Resources")
app.add_typer(tasks, name="tasks", help="Manage tasks", rich_help_panel="Resources")
app.add_typer(projects, name="projects", help="Manage projects", rich_help_panel="Resources")
app.add_typer(namespaces, name="namespaces", help="Manage namespaces", rich_help_panel="Resources")
app.add_typer(namespaces, name="ns", help="Manage namespaces", hidden=True)  # Alias
app.add_typer(env, name="env", help="Manage environment variables", rich_help_panel="Resources")
app.add_typer(filesystems, name="fs", help="Manage filesystems", rich_help_panel="Resources")
app.add_typer(filesystems, name="filesystems", help="Manage filesystems", hidden=True)  # Alias
app.add_typer(keys, name="keys", help="Manage webhook keys", rich_help_panel="Resources")


if __name__ == "__main__":
    app()
