"""Apps CLI commands."""

from __future__ import annotations

from typing import Annotated

import typer
from rich.console import Console

apps_app = typer.Typer(help="Manage applications")


@apps_app.command("list")
def apps_list(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    output: str = typer.Option("table", "--output", "-o", help="Output format: table or json"),
) -> None:
    """List all applications in a team."""
    from appliku.cli import get_client, render_output

    client = get_client()
    apps = client.apps.list(team)
    rows = [
        {"id": a.id, "name": a.name, "branch": a.branch, "status": a.status} for a in apps
    ]
    render_output(rows, ["id", "name", "branch", "status"], output, title="Applications")


@apps_app.command("get")
def apps_get(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    app_id: int = typer.Argument(..., help="App ID"),
    output: str = typer.Option("table", "--output", "-o", help="Output format"),
) -> None:
    """Get details of an application."""
    from appliku.cli import get_client, render_output

    client = get_client()
    a = client.apps.get(team, app_id)
    rows = [{"id": a.id, "name": a.name, "branch": a.branch, "status": a.status}]
    render_output(rows, ["id", "name", "branch", "status"], output, title=f"App: {a.name}")


@apps_app.command("create")
def apps_create(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    name: str = typer.Option(..., "--name", "-n", help="App name"),
    branch: str = typer.Option("main", "--branch", "-b", help="Git branch"),
    repo_provider: str | None = typer.Option(
        None, "--provider", help="Repo provider: github|gitlab|other"
    ),
    git_url: str | None = typer.Option(None, "--git-url", help="Git URL"),
    build_pack: str | None = typer.Option(
        None, "--build-pack", help="Build pack: dockerfile|buildpack|compose"
    ),
) -> None:
    """Create a new application."""
    from appliku.cli import get_client

    client = get_client()
    kwargs: dict[str, object] = {}
    if repo_provider:
        kwargs["repo_provider"] = repo_provider
    if git_url:
        kwargs["git_url"] = git_url
    if build_pack:
        kwargs["build_pack"] = build_pack
    a = client.apps.create(team, name=name, branch=branch, **kwargs)
    typer.echo(f"Created app '{a.name}' (ID: {a.id})")


@apps_app.command("update")
def apps_update(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    app_id: int = typer.Argument(..., help="App ID"),
    name: str | None = typer.Option(None, "--name", "-n"),
    branch: str | None = typer.Option(None, "--branch", "-b"),
) -> None:
    """Update an application."""
    from appliku.cli import get_client

    client = get_client()
    kwargs: dict[str, object] = {}
    if name is not None:
        kwargs["name"] = name
    if branch is not None:
        kwargs["branch"] = branch
    a = client.apps.update(team, app_id, **kwargs)
    typer.echo(f"Updated app '{a.name}'")


@apps_app.command("delete")
def apps_delete(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    app_id: int = typer.Argument(..., help="App ID"),
) -> None:
    """Delete an application."""
    from appliku.cli import get_client

    client = get_client()
    client.apps.delete(team, app_id)
    typer.echo(f"Deleted app {app_id}")


@apps_app.command("deploy")
def apps_deploy(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    app_id: int = typer.Option(..., "--app", "-a", help="App ID"),
) -> None:
    """Trigger a deployment."""
    from appliku.cli import get_client

    client = get_client()
    with Console().status("Triggering deployment..."):
        dep = client.apps.deploy(team, app_id)
    typer.echo(f"Deployment {dep.id} triggered (status: {dep.status})")


@apps_app.command("config")
def apps_config(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    app_id: int = typer.Option(..., "--app", "-a", help="App ID"),
    output: str = typer.Option("table", "--output", "-o", help="Output format"),
) -> None:
    """Show config vars for an app."""
    from appliku.cli import get_client, render_output

    client = get_client()
    vars_dict = client.apps.get_config_vars(team, app_id)
    rows = [{"key": k, "value": v} for k, v in vars_dict.items()]
    render_output(rows, ["key", "value"], output, title="Config Vars")


@apps_app.command("set-config")
def apps_set_config(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    app_id: int = typer.Option(..., "--app", "-a", help="App ID"),
    var: list[str] = typer.Option(..., "--var", help="KEY=VALUE pairs"),  # noqa: B008
) -> None:
    """Set config vars. Example: --var FOO=bar --var BAZ=qux"""
    from appliku.cli import get_client

    client = get_client()
    vars_dict: dict[str, str] = {}
    for item in var:
        if "=" not in item:
            typer.echo(f"Error: Invalid var format '{item}', expected KEY=VALUE", err=True)
            raise typer.Exit(1)
        key, value = item.split("=", 1)
        vars_dict[key] = value
    client.apps.set_config_vars(team, app_id, vars_dict)
    typer.echo(f"Set {len(vars_dict)} config var(s)")


@apps_app.command("logs")
def apps_logs(
    team: str = typer.Option(..., "--team", "-t", help="Team path"),
    app_id: int = typer.Option(..., "--app", "-a", help="App ID"),
    log_type: Annotated[
        str,
        typer.Option("--type", help="Log type: service | app | nginx | lb"),
    ] = "service",
    process: str | None = typer.Option(None, "--process", "-p", help="Process/service name"),
    domain: str | None = typer.Option(None, "--domain", "-d", help="Domain (for nginx or lb logs)"),
    tail: int = typer.Option(100, "--tail", help="Number of log lines"),
) -> None:
    """View application logs.

    Log types:
      service  — Direct process logs (requires --process).
      app      — Advanced app logs via async request/retrieve (requires --process).
      nginx    — Nginx logs via async request/retrieve (requires --domain).
      lb       — Load balancer logs (requires --domain).
    """
    from appliku.cli import get_client

    client = get_client()

    if log_type == "service":
        if not process:
            typer.echo("Error: --process is required for service logs", err=True)
            raise typer.Exit(1)
        with Console().status(f"Fetching service logs for '{process}'..."):
            result = client.apps.service_logs(team, app_id, process, tail)
        typer.echo(result.logs)

    elif log_type == "app":
        if not process:
            typer.echo("Error: --process is required for app logs", err=True)
            raise typer.Exit(1)
        with Console().status(f"Requesting app logs for '{process}' (polling)..."):
            result = client.apps.app_logs(team, app_id, process, tail)
        if result.status == "pending":
            typer.echo("Warning: Logs still pending after timeout", err=True)
        typer.echo(result.logs or "")

    elif log_type == "nginx":
        if not domain:
            typer.echo("Error: --domain is required for nginx logs", err=True)
            raise typer.Exit(1)
        with Console().status(f"Requesting nginx logs for '{domain}' (polling)..."):
            result = client.apps.nginx_logs(team, app_id, domain, tail)
        typer.echo(result.logs or "(no logs returned)")

    elif log_type == "lb":
        if not domain:
            typer.echo("Error: --domain is required for load balancer logs", err=True)
            raise typer.Exit(1)
        with Console().status(f"Fetching load balancer logs for '{domain}'..."):
            result = client.apps.load_balancer_logs(team, app_id, domain, tail)
        typer.echo(result.logs)

    else:
        typer.echo(
            f"Error: Unknown log type '{log_type}'. Use service, app, nginx, or lb", err=True
        )
        raise typer.Exit(1)
