from datetime import UTC, datetime

from home_agent.contracts.types import (
    Item,
    ItemKind,
    RetrievalQuery,
    UrgencyLabel,
    VectorDocument,
    VectorQuery,
    VectorSearchResult,
)
from home_agent.retrieval.retriever import VectorBackendRetriever
from home_agent.retrieval.text_renderer import DefaultItemTextRenderer


class StubEmbeddingProvider:
    @property
    def provider_name(self) -> str:
        return "local_sentence_transformers"

    @property
    def model_name(self) -> str:
        return "all-MiniLM-L6-v2"

    def embed_texts(self, texts: list[str]) -> list[list[float]]:
        return [[1.0, 0.0] for _ in texts]


class StubBackend:
    def __init__(self) -> None:
        self.queries: list[object] = []

    @property
    def backend_name(self) -> str:
        return "sqlite_vec"

    def upsert_documents(self, documents: list[VectorDocument]) -> None:
        _ = documents

    def query_similar(self, query: VectorQuery) -> list[VectorSearchResult]:
        self.queries.append(query)
        return [
            VectorSearchResult(
                provider="gmail",
                external_id="match-1",
                kind=ItemKind.EMAIL,
                summary_text="urgent reminder",
                received_at=datetime.now(tz=UTC),
                urgency_label=UrgencyLabel.HIGH,
                similarity=0.91,
            )
        ]

    def healthcheck(self) -> None:
        return None

    def indexed_count(self) -> int:
        return 0

    def rebuild(self, documents: list[VectorDocument]) -> None:
        _ = documents

    def has_document(self, key: object) -> bool:
        _ = key
        return False


def test_vector_backend_retriever_maps_backend_results_to_retrieved_matches() -> None:
    backend = StubBackend()
    retriever = VectorBackendRetriever(
        embedding_provider=StubEmbeddingProvider(),
        item_text_renderer=DefaultItemTextRenderer(),
        vector_backend=backend,
        include_item_kinds={"email"},
        prioritize_labels={UrgencyLabel.HIGH},
    )

    matches = retriever.find_similar(
        query_item(
            provider="gmail",
            external_id="query",
            subject="urgent task",
        )
    )

    assert [match.external_id for match in matches] == ["match-1"]
    assert matches[0].similarity == 0.91


def query_item(provider: str, external_id: str, subject: str) -> RetrievalQuery:
    return RetrievalQuery(
        item=Item(
            provider=provider,
            external_id=external_id,
            kind=ItemKind.EMAIL,
            received_at=datetime.now(tz=UTC),
            subject=subject,
            sender="staff@example.com",
            metadata={"snippet": "hello"},
        ),
        top_k=3,
        min_similarity=0.5,
    )
