"""Qdrant-backed vector store (production).

The ``qdrant_client`` import is local so the dependency is only needed when this
backend is actually selected.
"""

from __future__ import annotations

from legate.rag.vectorstore.base import SearchHit, VectorRecord


class QdrantVectorStore:
    def __init__(self, *, url: str) -> None:
        from qdrant_client import QdrantClient

        self._client = QdrantClient(url=url)
        self._ensured: set[str] = set()

    def _ensure_collection(self, collection: str, dim: int) -> None:
        if collection in self._ensured:
            return
        from qdrant_client.models import Distance, VectorParams

        if not self._client.collection_exists(collection):
            self._client.create_collection(
                collection_name=collection,
                vectors_config=VectorParams(size=dim, distance=Distance.COSINE),
            )
        self._ensured.add(collection)

    def upsert(self, collection: str, records: list[VectorRecord]) -> None:
        if not records:
            return
        from qdrant_client.models import PointStruct

        self._ensure_collection(collection, len(records[0].vector))
        points = [PointStruct(id=rec.id, vector=rec.vector, payload=rec.payload) for rec in records]
        self._client.upsert(collection_name=collection, points=points)

    def search(self, collection: str, vector: list[float], top_k: int = 5) -> list[SearchHit]:
        if not self._client.collection_exists(collection):
            return []
        results = self._client.query_points(
            collection_name=collection, query=vector, limit=top_k, with_payload=True
        ).points
        return [
            SearchHit(id=str(r.id), score=float(r.score), payload=r.payload or {}) for r in results
        ]

    def delete_by_document(self, collection: str, document_id: str) -> int:
        if not self._client.collection_exists(collection):
            return 0
        from qdrant_client.models import FieldCondition, Filter, FilterSelector, MatchValue

        flt = Filter(must=[FieldCondition(key="document_id", match=MatchValue(value=document_id))])
        self._client.delete(collection_name=collection, points_selector=FilterSelector(filter=flt))
        return -1  # Qdrant does not return a precise deleted count here

    def delete_collection(self, collection: str) -> None:
        if self._client.collection_exists(collection):
            self._client.delete_collection(collection)
        self._ensured.discard(collection)
