"""Main CLI entrypoint for MangoDesk."""

import subprocess
import sys
from pathlib import Path

import click
from rich.console import Console
from rich.table import Table

from mangodesk.config import (
    load_config,
    set_config,
    get_api_key,
    get_api_url,
    get_tau_bench_path,
    is_tau_bench_installed,
    get_openai_api_key,
    get_anthropic_api_key,
    TAU_BENCH_DIR,
)

console = Console()


@click.group()
@click.version_option()
def cli():
    """MangoDesk - tau-bench evaluation wrapper with cloud dashboard."""
    pass


@click.command()
@click.argument("key_value")
def set_cmd(key_value: str):
    """Set a configuration value.

    Usage: mangodesk set KEY=value

    Examples:
        mangodesk set MANGO_API_KEY=sk-mango-xxx
        mangodesk set OPENAI_API_KEY=sk-xxx
        mangodesk set ANTHROPIC_API_KEY=sk-xxx
        mangodesk set TAU_BENCH_PATH=/path/to/tau-bench
    """
    if "=" not in key_value:
        console.print("[red]Error:[/red] Use format KEY=value")
        raise SystemExit(1)

    key, value = key_value.split("=", 1)
    key = key.strip().upper()
    value = value.strip()

    # Handle empty values as None
    if value == "":
        value = None

    set_config(key, value)
    console.print(f"[green]Set[/green] {key} = {value or '(empty)'}")


cli.add_command(set_cmd, name="set")


@cli.command()
def config():
    """Show current configuration."""
    cfg = load_config()

    table = Table(title="MangoDesk Configuration")
    table.add_column("Key", style="cyan")
    table.add_column("Value", style="green")

    for key, value in sorted(cfg.items()):
        display_value = value
        # Mask sensitive values
        if key.endswith("_KEY") and value:
            display_value = value[:10] + "..." + value[-4:] if len(value) > 14 else "***"
        table.add_row(key, str(display_value) if display_value else "(not set)")

    console.print(table)

    # Show tau-bench status
    console.print()
    if is_tau_bench_installed():
        console.print(f"[green]✓[/green] tau-bench installed at: {get_tau_bench_path()}")
    else:
        console.print("[yellow]⚠[/yellow] tau-bench not installed. Run: mangodesk init")


@cli.command()
@click.argument("path", required=False, type=click.Path())
def init(path: str | None):
    """Initialize tau-bench by cloning the repository.

    Clones the tau-bench repository and installs it.

    Usage:
        mangodesk init              # Clones to ~/.mangodesk/tau-bench
        mangodesk init /custom/path # Clones to specified path

    Examples:
        mangodesk init
        mangodesk init ~/projects/tau-bench
    """
    target_path = Path(path) if path else TAU_BENCH_DIR

    if target_path.exists() and (target_path / "tau_bench").exists():
        console.print(f"[yellow]tau-bench already exists at:[/yellow] {target_path}")
        console.print()
        console.print("To reinstall, remove the directory first:")
        console.print(f"  rm -rf {target_path}")
        return

    console.print("[bold]Initializing tau-bench...[/bold]")
    console.print()

    # Clone the repository
    console.print(f"Cloning to: {target_path}")
    try:
        # Ensure parent directory exists
        target_path.parent.mkdir(parents=True, exist_ok=True)

        result = subprocess.run(
            ["git", "clone", "https://github.com/sierra-research/tau-bench", str(target_path)],
            capture_output=True,
            text=True,
        )

        if result.returncode != 0:
            console.print(f"[red]Error cloning repository:[/red]")
            console.print(result.stderr)
            raise SystemExit(1)

        console.print("[green]✓[/green] Repository cloned")

    except FileNotFoundError:
        console.print("[red]Error:[/red] git is not installed. Please install git first.")
        raise SystemExit(1)

    # Install the package
    console.print()
    console.print("Installing tau-bench...")

    result = subprocess.run(
        [sys.executable, "-m", "pip", "install", "-e", str(target_path)],
        capture_output=True,
        text=True,
    )

    if result.returncode != 0:
        console.print(f"[red]Error installing tau-bench:[/red]")
        console.print(result.stderr)
        raise SystemExit(1)

    console.print("[green]✓[/green] tau-bench installed")

    # Save the path to config
    set_config("TAU_BENCH_PATH", str(target_path))

    console.print()
    console.print("[green bold]tau-bench initialized successfully![/green bold]")
    console.print()
    console.print("[cyan]Next steps:[/cyan]")
    console.print("  1. Set your API keys:")
    console.print("     mangodesk set MANGO_API_KEY=sk-mango-xxx")
    console.print("     mangodesk set OPENAI_API_KEY=sk-xxx")
    console.print()
    console.print("  2. Run an evaluation:")
    console.print("     mangodesk eval --env retail --model gpt-4o --model-provider openai")


@cli.command()
@click.option("--env", "-e", required=True, help="Environment name (retail, airline, telecom)")
@click.option("--model", "-m", required=True, help="Model name (e.g., gpt-4o, claude-3-5-sonnet)")
@click.option("--model-provider", "-p", default=None, help="Model provider (openai, anthropic, google, mistral)")
@click.option("--agent-strategy", default="tool-calling", type=click.Choice(["tool-calling", "react", "act"]), help="Agent strategy")
@click.option("--user-model", default=None, help="User simulator model (defaults to same as --model)")
@click.option("--user-model-provider", default=None, help="User simulator provider (defaults to same as --model-provider)")
@click.option("--user-strategy", default="llm", type=click.Choice(["llm", "react", "verify", "reflection"]), help="User strategy")
@click.option("--max-concurrency", default=1, type=int, help="Maximum concurrent task executions (local mode only)")
@click.option("--task-ids", "-t", default=None, help="Comma-separated list of task IDs to run")
@click.option("--trials", default=1, type=int, help="Number of trials per task (for pass^k metrics)")
@click.option("--no-upload", is_flag=True, help="Skip uploading results to MangoDesk cloud")
@click.option("--tau-bench-path", default=None, type=click.Path(exists=True), help="Path to tau-bench installation")
@click.option("--remote", is_flag=True, help="Run tasks in parallel on remote workers")
def eval(
    env: str,
    model: str,
    model_provider: str | None,
    agent_strategy: str,
    user_model: str | None,
    user_model_provider: str | None,
    user_strategy: str,
    max_concurrency: int,
    task_ids: str | None,
    trials: int,
    no_upload: bool,
    tau_bench_path: str | None,
    remote: bool,
):
    """Run tau-bench evaluation with MangoDesk tracking.

    Executes tau-bench evaluations and uploads results to MangoDesk cloud
    for visualization and analysis.

    Examples:
        mangodesk eval --env retail --model gpt-4o --model-provider openai

        mangodesk eval --env airline --model claude-3-5-sonnet --model-provider anthropic

        mangodesk eval --env retail --model gpt-4o --model-provider openai \\
            --user-model gpt-4o --user-strategy llm --max-concurrency 10

        mangodesk eval --env retail --model gpt-4o -p openai --task-ids 1,2,3

        mangodesk eval --env retail --model gpt-4o -p openai --trials 3

        # Run all tasks in parallel on remote workers
        mangodesk eval --env retail --model gpt-4o -p openai --remote
    """
    from mangodesk.core.runner import run_tau_bench_evaluation, run_remote_evaluation

    # Determine tau-bench path
    tb_path = Path(tau_bench_path) if tau_bench_path else get_tau_bench_path()

    if not is_tau_bench_installed() and not tau_bench_path:
        console.print("[red]Error:[/red] tau-bench is not installed.")
        console.print("Run: mangodesk init")
        raise SystemExit(1)

    # Infer model provider if not specified
    if model_provider is None:
        if "gpt" in model.lower() or "o1" in model.lower():
            model_provider = "openai"
        elif "claude" in model.lower():
            model_provider = "anthropic"
        elif "gemini" in model.lower():
            model_provider = "google"
        elif "mistral" in model.lower():
            model_provider = "mistral"
        else:
            console.print("[red]Error:[/red] Could not infer model provider. Please specify --model-provider")
            raise SystemExit(1)

    # For local execution, check API keys
    if not remote:
        if model_provider == "openai" and not get_openai_api_key():
            console.print("[red]Error:[/red] OPENAI_API_KEY not set.")
            console.print("Run: mangodesk set OPENAI_API_KEY=sk-xxx")
            raise SystemExit(1)

        if model_provider == "anthropic" and not get_anthropic_api_key():
            console.print("[red]Error:[/red] ANTHROPIC_API_KEY not set.")
            console.print("Run: mangodesk set ANTHROPIC_API_KEY=sk-xxx")
            raise SystemExit(1)

    # Check for MangoDesk API key
    api_key = get_api_key()
    api_url = get_api_url()

    # Remote mode requires API key
    if remote and not api_key:
        console.print("[red]Error:[/red] MANGO_API_KEY is required for remote execution.")
        console.print("Run: mangodesk set MANGO_API_KEY=<your-key>")
        raise SystemExit(1)

    if not api_key and not no_upload:
        console.print("[yellow]Warning:[/yellow] MANGO_API_KEY not set. Results won't be uploaded.")
        console.print("Run: mangodesk set MANGO_API_KEY=<your-key>")
        console.print()

    # Set user model defaults
    if user_model is None:
        user_model = model
    if user_model_provider is None:
        user_model_provider = model_provider

    # Parse task IDs
    task_id_list = None
    if task_ids:
        task_id_list = [int(t.strip()) for t in task_ids.split(",")]

    if remote:
        # Run remote evaluation
        run_remote_evaluation(
            tau_bench_path=tb_path,
            env=env,
            model=model,
            model_provider=model_provider,
            agent_strategy=agent_strategy,
            user_model=user_model,
            user_model_provider=user_model_provider,
            user_strategy=user_strategy,
            task_ids=task_id_list,
            trials=trials,
            upload_results=not no_upload,
            api_url=api_url,
            api_key=api_key,
        )
    else:
        # Run local evaluation
        run_tau_bench_evaluation(
            tau_bench_path=tb_path,
            env=env,
            model=model,
            model_provider=model_provider,
            agent_strategy=agent_strategy,
            user_model=user_model,
            user_model_provider=user_model_provider,
            user_strategy=user_strategy,
            max_concurrency=max_concurrency,
            task_ids=task_id_list,
            trials=trials,
            upload_results=not no_upload,
            api_url=api_url,
            api_key=api_key,
        )


if __name__ == "__main__":
    cli()
