"""Shared data models for data plane operations."""

from typing import Any

from pinecone.models._base import BaseModel


class SparseValues(BaseModel, kw_only=True, rename="camel"):
    """Sparse vector representation with indices and values.

    Attributes:
        indices: Sparse vector indices.
        values: Sparse vector values (same length as indices).
    """

    indices: list[int]
    values: list[float]


class Vector(BaseModel, kw_only=True, rename="camel"):
    """Dense vector with optional sparse values and metadata.

    Attributes:
        id: Unique vector identifier.
        values: Dense vector values.
        sparse_values: Optional sparse vector component.
        metadata: Optional metadata dictionary.
    """

    id: str
    values: list[float]
    sparse_values: SparseValues | None = None
    metadata: dict[str, Any] | None = None

    def __repr__(self) -> str:
        if len(self.values) <= 3:
            values_repr = repr(self.values)
        else:
            values_repr = f"[{self.values[0]}, {self.values[1]}, ...]"
        return f"Vector(id={self.id!r}, values={values_repr})"

    def _repr_pretty_(self, p: Any, cycle: bool) -> None:
        """IPython pretty-printer support."""
        if cycle:
            p.text("Vector(...)")
            return

        if len(self.values) <= 3:
            values_repr = repr(self.values)
        else:
            values_repr = f"[{self.values[0]}, {self.values[1]}, ...]"

        p.text("Vector(")
        with p.group(2, "", ")"):
            p.breakable()
            p.text(f"id={self.id!r},")
            p.breakable()
            p.text(f"values={values_repr}")
            if self.sparse_values is not None:
                p.breakable()
                p.text(f"sparse_values={self.sparse_values!r}")
            if self.metadata is not None:
                p.breakable()
                p.text(f"metadata={self.metadata!r}")


class ScoredVector(BaseModel, kw_only=True, rename="camel"):
    """Query result vector with similarity score.

    Attributes:
        id: Vector identifier.
        score: Similarity score.
        values: Dense values (only if include_values=True).
        sparse_values: Sparse values (only if include_values=True).
        metadata: Metadata (only if include_metadata=True).
    """

    id: str
    score: float
    values: list[float] | None = None
    sparse_values: SparseValues | None = None
    metadata: dict[str, Any] | None = None

    def __repr__(self) -> str:
        return f"ScoredVector(id={self.id!r}, score={self.score})"

    def _repr_pretty_(self, p: Any, cycle: bool) -> None:
        """IPython pretty-printer support."""
        if cycle:
            p.text("ScoredVector(...)")
            return

        p.text("ScoredVector(")
        with p.group(2, "", ")"):
            p.breakable()
            p.text(f"id={self.id!r},")
            p.breakable()
            p.text(f"score={self.score}")
            if self.values is not None:
                p.breakable()
                if len(self.values) <= 3:
                    values_repr = repr(self.values)
                else:
                    values_repr = f"[{self.values[0]}, {self.values[1]}, ...]"
                p.text(f"values={values_repr}")
            if self.sparse_values is not None:
                p.breakable()
                p.text(f"sparse_values={self.sparse_values!r}")
            if self.metadata is not None:
                p.breakable()
                p.text(f"metadata={self.metadata!r}")


class NamespaceSummary(BaseModel, kw_only=True, rename="camel"):
    """Statistics for a single namespace.

    Attributes:
        vector_count: Number of vectors in the namespace.
    """

    vector_count: int


class ListItem(BaseModel, kw_only=True):
    """Item in a list vectors response.

    Attributes:
        id: Vector identifier.
    """

    id: str


class DataPlaneUsage(BaseModel, kw_only=True, rename="camel"):
    """Usage information for data plane operations.

    Attributes:
        read_units: Number of read units consumed.
    """

    read_units: int


class _Pagination(BaseModel, kw_only=True):
    """Internal model for the API pagination envelope.

    Maps the ``{"pagination": {"next": "..."}}`` shape from API responses.
    """

    next: str | None = None
