"""Data models for describe-index-stats operations."""

from typing import Any

from pinecone.models._base import BaseModel
from pinecone.models._display import render_table
from pinecone.models.index._common import NamespaceSummary


class DescribeIndexStatsRequest(BaseModel, kw_only=True):
    """Request model for describe index stats.

    Attributes:
        filter: Optional metadata filter for filtered stats.
    """

    filter: dict[str, Any] | None = None


class DescribeIndexStatsResponse(BaseModel, kw_only=True, rename="camel"):
    """Response model for describe index stats.

    Attributes:
        namespaces: Per-namespace statistics.
        dimension: Vector dimensionality.
        index_fullness: Capacity utilization (0.0 to 1.0).
        total_vector_count: Total vectors across all namespaces.
        metric: Distance metric used by the index.
        vector_type: Type of vectors stored (e.g., 'dense').
    """

    namespaces: dict[str, NamespaceSummary]
    dimension: int | None = None
    index_fullness: float | None = None
    total_vector_count: int = 0
    metric: str | None = None
    vector_type: str | None = None

    def __repr__(self) -> str:
        parts = [
            f"total_vector_count={self.total_vector_count}",
            f"dimension={self.dimension}",
            f"namespaces={len(self.namespaces)}",
        ]
        if self.metric is not None:
            parts.append(f"metric={self.metric!r}")
        if self.vector_type is not None:
            parts.append(f"vector_type={self.vector_type!r}")
        return f"DescribeIndexStatsResponse({', '.join(parts)})"

    def __dir__(self) -> list[str]:
        """Return public API, hiding internal attributes."""
        attrs = set(super().__dir__())
        public = {name for name in attrs if not name.startswith("_")}
        return sorted(public)

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

        p.text("DescribeIndexStatsResponse(")
        with p.group(2, "", ")"):
            p.breakable()
            p.text(f"total_vector_count={self.total_vector_count},")
            p.breakable()
            p.text(f"dimension={self.dimension},")
            p.breakable()
            p.text(f"namespaces={len(self.namespaces)}")
            if self.index_fullness is not None:
                p.breakable()
                p.text(f"index_fullness={self.index_fullness}")
            if self.metric is not None:
                p.breakable()
                p.text(f"metric={self.metric!r}")
            if self.vector_type is not None:
                p.breakable()
                p.text(f"vector_type={self.vector_type!r}")

    def _repr_html_(self) -> str:
        """Jupyter notebook HTML representation."""
        rows: list[tuple[str, str | int | float]] = [
            ("Total Vectors:", self.total_vector_count),
            ("Dimension:", self.dimension if self.dimension is not None else "N/A"),
            ("Namespaces:", len(self.namespaces)),
        ]

        if self.index_fullness is not None:
            rows.append(("Index Fullness:", f"{self.index_fullness:.2%}"))
        if self.metric is not None:
            rows.append(("Metric:", self.metric))
        if self.vector_type is not None:
            rows.append(("Vector Type:", self.vector_type))

        return render_table("DescribeIndexStatsResponse", rows)
