"""Async query method for AsyncIndex."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

import msgspec

from pinecone.models.index.query import QueryResponse


_DECODER = msgspec.json.Decoder(QueryResponse)


if TYPE_CHECKING:
    from pinecone.__interface__.index import SparseValues


async def query(
    self: Any,
    *,
    vector: list[float] | None = None,
    id: str | None = None,
    top_k: int = 10,
    namespace: str = "",
    filter: dict[str, Any] | None = None,
    include_values: bool = False,
    include_metadata: bool = True,
    sparse_vector: SparseValues | None = None,
) -> QueryResponse:
    """Query vectors by similarity.

    Args:
        vector: Dense query vector.
        id: Query by existing vector ID.
        top_k: Number of results to return.
        namespace: Target namespace.
        filter: Metadata filter expression.
        include_values: Include vector values in results.
        include_metadata: Include metadata in results.
        sparse_vector: Optional sparse query vector.

    Returns:
        QueryResponse with matching vectors and scores.

    Example:
        >>> results = await index.query(vector=[0.1, 0.2, 0.3], top_k=10)
    """
    body: dict[str, Any] = {
        "topK": top_k,
        "includeValues": include_values,
        "includeMetadata": include_metadata,
    }
    if vector is not None:
        body["vector"] = vector
    if id is not None:
        body["id"] = id
    if namespace:
        body["namespace"] = namespace
    if filter is not None:
        body["filter"] = filter
    if sparse_vector is not None:
        body["sparseVector"] = sparse_vector

    data = await self._make_data_plane_request("POST", "/query", body=body)
    return _DECODER.decode(data)
