"""Vector backend protocol for Sulci."""

from typing import Protocol, runtime_checkable


@runtime_checkable
class VectorBackend(Protocol):
    """Abstract interface for vector storage backends.

    Implementations: SqliteVecBackend, PgVectorBackend, ChromaVectorBackend (transitional).
    """

    async def initialize(self) -> None:
        """Create tables/extensions needed for vector storage."""
        ...

    async def upsert(self, atom_id: str, embedding: list[float], metadata: dict, document: str) -> None:
        """Insert or replace a single vector."""
        ...

    async def upsert_batch(self, items: list[tuple[str, list[float], dict, str]]) -> None:
        """Bulk insert vectors. Each item is (atom_id, embedding, metadata, document)."""
        ...

    async def delete(self, atom_id: str) -> None:
        """Remove a vector by atom ID."""
        ...

    async def delete_batch(self, atom_ids: list[str]) -> None:
        """Remove multiple vectors by atom IDs."""
        ...

    async def update_metadata(self, atom_id: str, metadata: dict) -> None:
        """Update metadata for a vector. No-op for backends that store metadata relationally."""
        ...

    async def search(
        self, query_embedding: list[float], limit: int = 10, where: dict | None = None
    ) -> list[tuple[str, float]]:
        """KNN cosine search. Returns list of (atom_id, distance)."""
        ...

    async def get_all_with_embeddings(self, where: dict | None = None, limit: int = 500) -> dict:
        """Get all vectors with embeddings for duplicate detection.

        Returns dict with keys: 'ids', 'embeddings'.
        """
        ...

    def distance_to_similarity(self, distance: float) -> float:
        """Convert backend-specific distance to 0-1 similarity score."""
        ...

    async def purge(self) -> None:
        """Delete all vectors."""
        ...
