"""
Standard RAG Context Engine: Vector-only top-K retrieval.

This is the **control** engine. It queries Qdrant directly for the top-K
most similar chunks without any graph expansion. This simulates a typical
RAG pipeline where the only signal is embedding cosine similarity.
"""

from __future__ import annotations

import logging

import httpx

from .base import ContextResult, estimate_tokens

logger = logging.getLogger("clew.bench.engines.standard_rag")


class StandardRAGEngine:
    """Vector-only context retrieval via Qdrant REST API."""

    def __init__(
        self,
        qdrant_url: str,
        embedding_url: str,
        api_key: str | None = None,
        collection_name: str = "codebase",
        limit: int = 10,
    ):
        self.qdrant_url = qdrant_url.rstrip("/")
        self.embedding_url = embedding_url.rstrip("/")
        self.api_key = api_key
        self.collection_name = collection_name
        self.limit = limit
        self._client = httpx.AsyncClient(timeout=30.0)

    async def _get_embedding(self, text: str) -> list[float]:
        """Get embedding vector from the embedding service."""
        headers = {}
        if self.api_key and "openai.com" in self.embedding_url:
            headers["Authorization"] = f"Bearer {self.api_key}"

        response = await self._client.post(
            f"{self.embedding_url}/v1/embeddings",
            headers=headers,
            json={"input": text, "model": "text-embedding-3-small"},
        )
        response.raise_for_status()
        data = response.json()
        return data["data"][0]["embedding"]

    async def query(self, instruction: str) -> ContextResult:
        """
        Query Qdrant directly for top-K similar chunks.

        No graph expansion, no relationship awareness -- pure vector search.
        This is what most RAG systems do.
        """
        try:
            query_vector = await self._get_embedding(instruction)
        except httpx.HTTPError as e:
            logger.error("Embedding request failed: %s", e)
            return ContextResult(context="", token_count=0, sources=[])

        # Query Qdrant REST API directly
        try:
            response = await self._client.post(
                f"{self.qdrant_url}/collections/{self.collection_name}/points/query",
                json={
                    "query": query_vector,
                    "limit": self.limit,
                    "with_payload": True,
                },
            )
            response.raise_for_status()
            data = response.json()
        except httpx.HTTPError as e:
            logger.error("Qdrant query failed: %s", e)
            return ContextResult(context="", token_count=0, sources=[])

        points = data.get("result", {}).get("points", [])

        # Format results -- deliberately naive (no dedup, no graph expansion)
        sections = []
        sources = []
        for point in points:
            payload = point.get("payload", {})
            path = payload.get("path", payload.get("id", "unknown"))
            content = payload.get("text", "")
            sources.append(path)
            sections.append(f"### {path}\n```\n{content}\n```")

        context = "\n\n".join(sections)
        token_count = estimate_tokens(context)

        logger.info("Standard RAG returned %d results, ~%d tokens", len(points), token_count)
        return ContextResult(context=context, token_count=token_count, sources=sources)

    async def close(self) -> None:
        await self._client.aclose()
