"""Retrieval CLI commands."""

import time
from typing import Optional

import click

from centris_sdk.action.api import ActionRetrievalSearchRequest
from centris_sdk.cli.result_envelope import build_result_envelope, emit_result_envelope

from .common import create_api_client, parse_json_object


@click.group("retrieval")
def retrieval_group() -> None:
    """Run retrieval operations via Action API."""


@retrieval_group.command("search")
@click.option("--query", required=True, help="Search query")
@click.option("--provider", type=click.Choice(["airweave"]), default="airweave", show_default=True)
@click.option("--readable-id", help="Collection readable ID")
@click.option("--collection", help="Collection readable ID (alias)")
@click.option("--collection-id", help="Collection readable ID (alias)")
@click.option(
    "--retrieval-strategy",
    type=click.Choice(["hybrid", "neural", "keyword"]),
    help="Retrieval strategy",
)
@click.option("--expand-query", is_flag=True, help="Enable query expansion")
@click.option(
    "--interpret-filters",
    is_flag=True,
    help="Enable natural-language filter interpretation",
)
@click.option("--rerank/--no-rerank", default=None, help="Enable or disable reranking")
@click.option(
    "--generate-answer/--no-generate-answer",
    default=None,
    help="Enable or disable answer generation",
)
@click.option("--filter", "filter_json", help="Filter JSON object")
@click.option("--limit", type=int, help="Maximum number of results")
@click.option("--offset", type=int, help="Pagination offset")
@click.option("--key", "key", help="API key override")
@click.option("--base-url", help="API base URL override")
@click.option("--timeout", default=120, type=int, show_default=True)
@click.option("--json", "json_output", is_flag=True, help="Output raw JSON")
@click.pass_context
def retrieval_search_command(
    ctx: click.Context,
    query: str,
    provider: str,
    readable_id: Optional[str],
    collection: Optional[str],
    collection_id: Optional[str],
    retrieval_strategy: Optional[str],
    expand_query: bool,
    interpret_filters: bool,
    rerank: Optional[bool],
    generate_answer: Optional[bool],
    filter_json: Optional[str],
    limit: Optional[int],
    offset: Optional[int],
    key: Optional[str],
    base_url: Optional[str],
    timeout: int,
    json_output: bool,
) -> None:
    """Search retrieval provider collections."""
    started_at = time.time()
    client = create_api_client(ctx, key, base_url, timeout)
    result = client.retrieval.search(
        ActionRetrievalSearchRequest(
            query=query,
            provider=provider,  # type: ignore[arg-type]
            readable_id=readable_id,
            collection=collection,
            collection_id=collection_id,
            retrieval_strategy=retrieval_strategy,  # type: ignore[arg-type]
            expand_query=True if expand_query else None,
            interpret_filters=True if interpret_filters else None,
            rerank=rerank,
            generate_answer=generate_answer,
            filter=parse_json_object(filter_json, "filter"),
            limit=limit,
            offset=offset,
        )
    )

    if json_output:
        emit_result_envelope(
            build_result_envelope(
                ok=result.ok,
                operation="retrieval.search",
                summary=f"Retrieved {result.result_count} result(s) from {result.provider}",
                data={
                    "ok": result.ok,
                    "provider": result.provider,
                    "readableId": result.readable_id,
                    "query": result.query,
                    "resultCount": result.result_count,
                    "completion": result.completion,
                    "results": [
                        {
                            "name": item.name,
                            "sourceName": item.source_name,
                            "score": item.score,
                            "snippet": item.snippet,
                        }
                        for item in result.results
                    ],
                },
                duration_ms=int((time.time() - started_at) * 1000),
                safety_level="read",
            )
        )
        return

    if not result.ok:
        raise click.ClickException("Retrieval search failed")

    click.echo(
        f"Retrieved {result.result_count} result(s) from {result.provider} ({result.readable_id})"
    )
    for index, item in enumerate(result.results, start=1):
        score = f"{item.score:.3f}" if isinstance(item.score, (int, float)) else "n/a"
        click.echo(f"{index}. {item.name} [{item.source_name}] score={score}")
        if item.snippet:
            click.echo(f"   {item.snippet}")
