"""BilgeAI CLI application."""

import typer
from dotenv import load_dotenv
from rich.console import Console

from bilgeai import __version__

# Load .env from current working directory only (don't walk up to parent dirs)
load_dotenv(dotenv_path=".env")

app = typer.Typer(
    name="bilge",
    help="BilgeAI - Smart LLM Training Orchestrator",
    no_args_is_help=True,
    rich_markup_mode="rich",
    context_settings={"help_option_names": ["-h", "--help"]},
    epilog=(
        "Run [bold]bilge <command> -h[/bold] for command-specific options.\n\n"
        "[dim]Workflow: init >> profile >> analyze >> doctor >> run[/dim]"
    ),
)
console = Console()


def _check_llm_status() -> str:
    """Check LLM provider availability and return a status line."""
    try:
        from bilgeai.core.config import BilgeConfig

        cfg = BilgeConfig.load()
        llm_cfg = cfg.llm
    except Exception:
        return "[yellow]Not configured[/yellow] (run 'bilge init')"

    import os

    provider = llm_cfg.provider
    model = llm_cfg.model

    if provider == "local":
        if _is_local_reachable(llm_cfg.base_url):
            return f"[green bold][ON][/green bold] Local ({model} @ {llm_cfg.base_url})"
        return f"[red bold][OFF][/red bold] Local ({model} @ {llm_cfg.base_url}) - unreachable"

    # Cloud provider: check API key
    api_key = os.environ.get(llm_cfg.api_key_env, "")
    if api_key:
        label = provider.capitalize()
        return f"[green bold][ON][/green bold] {label} ({model})"

    return f"[red bold][OFF][/red bold] {llm_cfg.api_key_env} not set"


def _is_local_reachable(base_url: str | None) -> bool:
    """Quick check if a local LLM endpoint is reachable (500ms timeout)."""
    if not base_url:
        return False
    try:
        import urllib.request

        # Strip /v1 suffix to hit the root endpoint
        url = base_url.rstrip("/")
        if url.endswith("/v1"):
            url = url[:-3]
        req = urllib.request.Request(url, method="GET")
        urllib.request.urlopen(req, timeout=0.5)
        return True
    except Exception:
        return False


def version_callback(value: bool) -> None:
    if value:
        status = _check_llm_status()
        console.print(f"BilgeAI v{__version__}  {status}")
        raise typer.Exit()


@app.callback()
def main(
    version: bool = typer.Option(
        False,
        "--version",
        "-v",
        help="Show version and exit.",
        callback=version_callback,
        is_eager=True,
    ),
) -> None:
    """BilgeAI - Read your hardware. Understand your data. Decide. Explain. Train."""
    status = _check_llm_status()
    console.print(f"[dim]BilgeAI v{__version__}[/dim]  {status}\n")


# Register command modules
from bilgeai.cli.commands import (  # noqa: E402
    analyze,
    chart,
    diff,
    doctor,
    explain,
    export,
    history,
    init,
    profile,
    replay,
    run,
    update,
)

app.command(
    name="init",
    help="Create bilge.yaml config via interactive setup",
    rich_help_panel="Setup",
)(init.init_command)
app.command(
    name="profile",
    help="Detect CPU, RAM, GPU/VRAM and save hardware profile",
    rich_help_panel="Analysis",
)(profile.profile_command)
app.command(
    name="analyze",
    help="Analyze dataset structure, token lengths, and PII (--data)",
    rich_help_panel="Analysis",
)(analyze.analyze_command)
app.command(
    name="doctor",
    help="Validate config, hardware, and data readiness",
    rich_help_panel="Analysis",
)(doctor.doctor_command)
app.command(
    name="explain",
    help="Show why each training parameter was chosen",
    rich_help_panel="Analysis",
)(explain.explain_command)
app.command(
    name="run",
    help="Generate training script (dry-run default, --start to train)",
    rich_help_panel="Training",
)(run.run_command)
app.command(
    name="history",
    help="List past runs with status and metrics (--json)",
    rich_help_panel="History",
)(history.history_command)
app.command(
    name="diff",
    help="Compare two runs side-by-side",
    rich_help_panel="History",
)(diff.diff_command)
app.command(
    name="export",
    help="Export run report as Markdown, JSON, or LaTeX",
    rich_help_panel="History",
)(export.export_command)
app.command(
    name="replay",
    help="Re-run a previous experiment with identical config",
    rich_help_panel="History",
)(replay.replay_command)
app.command(
    name="chart",
    help="Plot training metric curves from logs (--metric)",
    rich_help_panel="History",
)(chart.chart_command)
app.command(
    name="update",
    help="Check PyPI for new versions and self-upgrade",
    rich_help_panel="Setup",
)(update.update_command)


@app.command(name="donate", help="Support BilgeAI development", rich_help_panel="Setup")
def donate_command() -> None:
    """Show donation links."""
    console.print("\n[bold]Support BilgeAI Development[/bold]\n")
    console.print("  BilgeAI is free and open-source.")
    console.print("  Your support helps cover API costs and fund new features.\n")
    console.print("  [yellow bold]Buy Me a Coffee[/yellow bold]  https://buymeacoffee.com/bilgeai")
    console.print("\n  [dim]Thank you![/dim]\n")
