"""Model-alias CLI commands."""

from __future__ import annotations

from typing import Annotated

from cyclopts import Parameter

from kitaru._interface_errors import run_with_cli_error_boundary
from kitaru.cli_output import CLIOutputFormat
from kitaru.config import ModelAliasEntry
from kitaru.inspection import serialize_model_alias

from . import model_app
from ._dependencies import cli_dependencies
from ._helpers import (
    DEFAULT_LIST_PAGE,
    DEFAULT_LIST_SIZE,
    OutputFormatOption,
    PaginationPageOption,
    PaginationSizeOption,
    _emit_json_item,
    _emit_json_items,
    _emit_pagination_note,
    _emit_snapshot,
    _exit_with_error,
    _paginate_items,
    _print_success,
    _resolve_output_format,
    _validate_pagination,
)


def _model_rows(entries: list[ModelAliasEntry]) -> list[tuple[str, str]]:
    """Build label/value rows for `kitaru model list`."""
    if not entries:
        return [("Models", "none found")]

    rows: list[tuple[str, str]] = []
    for entry in entries:
        detail = entry.model
        if entry.secret:
            detail += f" (secret={entry.secret})"
        if entry.is_default:
            detail += " [default]"
        rows.append((entry.alias, detail))

    return rows


@model_app.command
def register(
    alias: Annotated[
        str,
        Parameter(help="Model alias name (for example `fast`)."),
    ],
    *,
    model: Annotated[
        str,
        Parameter(
            help="Provider/model identifier (e.g. openai/gpt-5-nano, ollama/qwen3.5)."
        ),
    ],
    secret: Annotated[
        str | None,
        Parameter(help="Optional secret name/ID containing provider credentials."),
    ] = None,
    output: OutputFormatOption = "text",
) -> None:
    """Register or update a model alias used by `kitaru.llm()`.

    Aliases are stored locally and automatically transported to submitted and
    replayed executions.
    """
    command = "model.register"
    output_format = _resolve_output_format(output)
    deps = cli_dependencies()

    def _register_alias() -> ModelAliasEntry:
        if secret is not None:
            deps.resolve_secret_exact(deps.zenml_client(), secret)
        return deps.register_model_alias(alias, model=model, secret=secret)

    alias_entry = run_with_cli_error_boundary(
        _register_alias,
        command=command,
        output=output_format,
        exit_with_error=_exit_with_error,
    )

    if output_format == CLIOutputFormat.JSON:
        _emit_json_item(
            command,
            serialize_model_alias(alias_entry),
            output=output_format,
        )
        return

    detail = f"Model: {alias_entry.model}"
    if alias_entry.secret:
        detail += f" | Secret: {alias_entry.secret}"
    if alias_entry.is_default:
        detail += " | Default alias"

    _print_success(
        f"Saved model alias: {alias_entry.alias}",
        detail=detail,
    )


@model_app.command
def list___(
    *,
    page: PaginationPageOption = DEFAULT_LIST_PAGE,
    size: PaginationSizeOption = DEFAULT_LIST_SIZE,
    output: OutputFormatOption = "text",
) -> None:
    """List model aliases available to `kitaru.llm()` in this environment."""
    command = "model.list"
    output_format = _resolve_output_format(output)
    page, size = _validate_pagination(
        page=page,
        size=size,
        command=command,
        output=output_format,
    )
    aliases = run_with_cli_error_boundary(
        cli_dependencies().list_model_aliases,
        command=command,
        output=output_format,
        exit_with_error=_exit_with_error,
    )

    visible_aliases = _paginate_items(aliases, page=page, size=size)

    if output_format == CLIOutputFormat.JSON:
        _emit_json_items(
            command,
            [serialize_model_alias(entry) for entry in visible_aliases],
            output=output_format,
        )
        return

    if aliases and not visible_aliases:
        rows: list[tuple[str, str]] = [("Models", f"no items on page {page}")]
    else:
        rows = _model_rows(visible_aliases)
    _emit_snapshot("Kitaru models", rows)
    _emit_pagination_note(
        page=page,
        size=size,
        returned_count=len(visible_aliases),
        total_count=len(aliases),
        output=output_format,
    )
