import typer
from requests.exceptions import RequestException
from rich import print
from rich.table import Table
from .client import YuroClient

from yurolabs.api import deploy_model, list_models, run_inference_from_path
from yurolabs.config import save_base_url, save_key


app = typer.Typer(help="Yuro model management CLI.")


@app.command()
def login(key: str):
    save_key(key)
    print("[green]API key saved![/green]")


@app.command()
def set_url(url: str):
    save_base_url(url)
    print(f"[green]Base URL set to {url}[/green]")

@app.command(name="models")
def list_available_models():
    """Display models discovered in the configured S3 bucket."""
    try:
        data = list_models()
    except RequestException as exc:
        print(f"[red]Failed to fetch models: {exc}[/red]")
        raise typer.Exit(code=1) from exc

    if not data:
        print("[yellow]No models found in the configured bucket.[/yellow]")
        raise typer.Exit()

    table = Table(title="Available Models")
    table.add_column("Index", justify="right")
    table.add_column("Name")
    table.add_column("Key")
    table.add_column("Size (bytes)", justify="right")
    table.add_column("Last Modified")

    for idx, item in enumerate(data):
        name = item.get("name", "")
        key = item.get("key", "")

        size = item.get("size")
        if isinstance(size, (int, float)):
            size_display = f"{int(size):,}"
        else:
            size_display = str(size) if size is not None else "-"

        last_modified = item.get("last_modified", "")

        table.add_row(str(idx), name, key, size_display, last_modified)

    print(table)


@app.command()
def infer_batch(folder: str):
    client = YuroClient()
    from .batch import batch_infer
    results = batch_infer(folder, client)
    print(results)



@app.command()
def deploy(index: int = typer.Argument(None), s3_key: str = typer.Option(None, "--key")):
    try:
        models = list_models()
    except RequestException as exc:
        print(f"[red]Failed to fetch models: {exc}[/red]")
        raise typer.Exit(code=1) from exc

    if not models:
        print("[yellow]No models available for deployment.[/yellow]")
        raise typer.Exit(code=1)

    target = None
    if s3_key:
        target = next((item for item in models if item.get("key") == s3_key), None)
    elif index is not None:
        if 0 <= index < len(models):
            target = models[index]
    else:
        table = Table(title="Select model")
        table.add_column("Index", justify="right")
        table.add_column("Name")
        table.add_column("Key")
        for idx, item in enumerate(models):
            table.add_row(str(idx), item.get("name", ""), item.get("key", ""))
        print(table)
        selection = typer.prompt("Enter model index", type=int)
        if 0 <= selection < len(models):
            target = models[selection]

    if not target:
        print("[red]Unable to resolve the requested model selection.[/red]")
        raise typer.Exit(code=1)

    print(f"[cyan]Deploying {target.get('name')}...[/cyan]")
    try:
        response = deploy_model(target.get("key"), target.get("name"))
    except RequestException as exc:
        print(f"[red]Deployment failed: {exc}[/red]")
        raise typer.Exit(code=1) from exc

    deployment_id = response.get("deployment_id", "-")
    model_name = response.get("model_name") or target.get("name", "")
    status = response.get("status", "deployed")
    print(
        f"[green]Deployment {status} for {model_name} (deployment ID: {deployment_id}).[/green]"
    )


@app.command()
def infer(image: str):
    print("[cyan]Running inference...[/cyan]")
    try:
        result = run_inference_from_path(image)
    except RequestException as exc:
        print(f"[red]Inference failed: {exc}[/red]")
        raise typer.Exit(code=1) from exc
    print(result)
