import os
from pathlib import Path
from typing import Annotated

import sentry_sdk
import typer
from rich.console import Console

from repo_sync_kitty import __version__
from repo_sync_kitty.commands import (
    add,
    change_url,
    check,
    enroll,
    find_orphans,
    fix_detached,
    import_manifest,
    init,
    move,
    scan,
    scrub,
    status,
    sync,
)
from repo_sync_kitty.commands import (
    open as open_cmd,
)
from repo_sync_kitty.exitcodes import ExitCode
from repo_sync_kitty.monitoring import setup_sentry

console = Console()
error_console = Console(stderr=True)

app = typer.Typer(
    name="repo-sync-kitty",
    help="Git repository synchronization tool for teams.",
    add_completion=True,
    no_args_is_help=True,
)


def version_callback(value: bool) -> None:
    if value:
        console.print(f"repo-sync-kitty {__version__}")
        raise typer.Exit(code=ExitCode.SUCCESS)


@app.callback()
def main(
    ctx: typer.Context,
    version: Annotated[  # noqa: ARG001
        bool,
        typer.Option(
            "--version",
            "-V",
            callback=version_callback,
            is_eager=True,
            help="Show version and exit.",
        ),
    ] = False,
    manifest: Annotated[
        Path | None,
        typer.Option(
            "--manifest",
            "-m",
            help="Path to manifest.toml file.",
            envvar="REPO_SYNC_KITTY_MANIFEST",
        ),
    ] = None,
    root: Annotated[
        Path | None,
        typer.Option(
            "--root",
            "-r",
            help="Root directory for repositories.",
            envvar="REPO_SYNC_KITTY_ROOT",
        ),
    ] = None,
    no_color: Annotated[
        bool,
        typer.Option("--no-color", help="Disable colored output."),
    ] = False,
    verbose: Annotated[
        bool,
        typer.Option("--verbose", "-v", help="Enable verbose output."),
    ] = False,
) -> None:
    setup_sentry(os.getenv("ENVIRONMENT", "local"))
    ctx.ensure_object(dict)
    ctx.obj["manifest"] = manifest
    ctx.obj["root"] = root
    ctx.obj["verbose"] = verbose
    if no_color:
        console.no_color = True


app.command(name="change-url")(change_url.change_url)
app.command(name="sync")(sync.sync)
app.command(name="status")(status.status)
app.command(name="init")(init.init)
app.command(name="add")(add.add)
app.command(name="check")(check.check)
app.command(name="scan")(scan.scan)
app.command(name="import-repo")(import_manifest.import_manifest)
app.command(name="fix-detached")(fix_detached.fix_detached)
app.command(name="find-orphans")(find_orphans.find_orphans)
app.command(name="move")(move.move)
app.command(name="open")(open_cmd.open_repo)
app.command(name="enroll")(enroll.enroll)
app.command(name="scrub")(scrub.scrub)


@app.command(name="test-sentry")
def test_sentry_cmd() -> None:
    """Send a test error and performance span to Sentry, then flush."""
    console.print("Sending test exception to Sentry...")
    try:
        raise RuntimeError("repo-sync-kitty test-sentry: error tracking test")
    except RuntimeError as e:
        sentry_sdk.capture_exception(e)

    console.print("Sending test performance transaction...")
    with sentry_sdk.start_transaction(op="test", name="test-sentry") as txn:
        txn.set_tag("triggered_by", "test-sentry command")
        with (
            sentry_sdk.start_span(op="parent", description="Parent span"),
            sentry_sdk.start_span(op="child", description="Child span"),
        ):
            pass

    console.print("Flushing to Sentry...")
    sentry_sdk.flush(timeout=5)
    console.print("[green]✓[/green] Done. Verify events in the Sentry console.")


if __name__ == "__main__":
    app()
