"""Backup metadata model."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from pinecone.models._base import BaseModel
from pinecone.models._display import render_table


if TYPE_CHECKING:
    from pinecone.__interface__ import BackupStatus


class BackupModel(BaseModel, kw_only=True, omit_defaults=True):  # pyright: ignore[reportCallIssue]
    """Backup metadata from API.

    This model represents the complete backup information returned by the Pinecone API.
    All fields map directly to the API response schema.

    Attributes:
        backup_id: Unique identifier for the backup.
        source_index_name: Name of the index from which the backup was taken.
        source_index_id: ID of the source index.
        name: Optional user-defined name for the backup.
        description: Optional description providing context for the backup.
        status: Current status of the backup (Initializing, Ready, Failed).
        cloud: Cloud provider where the backup is stored.
        region: Cloud region where the backup is stored.
        dimension: Vector dimensionality (None for sparse indexes).
        metric: Distance metric used (cosine, euclidean, dotproduct).
        record_count: Total number of records in the backup.
        namespace_count: Number of namespaces in the backup.
        size_bytes: Size of the backup in bytes.
        tags: Custom user tags added to the backup.
        schema: Metadata schema configuration.
        created_at: ISO 8601 timestamp when the backup was created.
    """

    backup_id: str
    source_index_name: str
    source_index_id: str
    status: BackupStatus
    cloud: str
    region: str
    created_at: str
    name: str | None = None
    description: str | None = None
    dimension: int | None = None
    metric: str | None = None
    record_count: int | None = None
    namespace_count: int | None = None
    size_bytes: int | None = None
    tags: dict[str, str] | None = None
    schema: dict[str, Any] | None = None

    def __repr__(self) -> str:
        """Return developer-friendly representation.

        Shows key metadata without overwhelming with all fields.
        """
        status_str = f"status={self.status!r}"
        size_str = (
            f"size={self.size_bytes} bytes" if self.size_bytes is not None else "size=unknown"
        )
        records_str = (
            f"records={self.record_count}" if self.record_count is not None else "records=unknown"
        )

        return (
            f"BackupModel(backup_id={self.backup_id!r}, "
            f"source={self.source_index_name!r}, {status_str}, {size_str}, {records_str})"
        )

    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("BackupModel(...)")
            return

        p.text("BackupModel(")
        with p.group(2, "", ")"):
            p.breakable()
            p.text(f"backup_id={self.backup_id!r},")
            p.breakable()
            p.text(f"source_index_name={self.source_index_name!r},")
            p.breakable()
            p.text(f"source_index_id={self.source_index_id!r},")
            p.breakable()
            p.text(f"status={self.status!r},")
            p.breakable()
            p.text(f"cloud={self.cloud!r},")
            p.breakable()
            p.text(f"region={self.region!r},")
            p.breakable()
            p.text(f"created_at={self.created_at!r}")

            if self.name is not None:
                p.breakable()
                p.text(f"name={self.name!r}")
            if self.description is not None:
                p.breakable()
                p.text(f"description={self.description!r}")
            if self.dimension is not None:
                p.breakable()
                p.text(f"dimension={self.dimension}")
            if self.metric is not None:
                p.breakable()
                p.text(f"metric={self.metric!r}")
            if self.record_count is not None:
                p.breakable()
                p.text(f"record_count={self.record_count}")
            if self.namespace_count is not None:
                p.breakable()
                p.text(f"namespace_count={self.namespace_count}")
            if self.size_bytes is not None:
                p.breakable()
                p.text(f"size_bytes={self.size_bytes}")
            if self.tags:
                p.breakable()
                p.text(f"tags={self.tags!r}")
            if self.schema:
                p.breakable()
                p.text(f"schema={self.schema!r}")

    def _repr_html_(self) -> str:
        """Jupyter notebook HTML representation."""
        rows: list[tuple[str, str | int]] = [
            ("Backup ID:", self.backup_id),
            ("Source Index:", self.source_index_name),
            ("Source Index ID:", self.source_index_id),
            ("Status:", self.status),
            ("Cloud:", self.cloud),
            ("Region:", self.region),
            ("Created:", self.created_at),
        ]

        if self.name is not None:
            rows.append(("Name:", self.name))
        if self.description is not None:
            rows.append(("Description:", self.description))
        if self.dimension is not None:
            rows.append(("Dimension:", self.dimension))
        if self.metric is not None:
            rows.append(("Metric:", self.metric))
        if self.record_count is not None:
            rows.append(("Records:", self.record_count))
        if self.namespace_count is not None:
            rows.append(("Namespaces:", self.namespace_count))
        if self.size_bytes is not None:
            rows.append(("Size:", f"{self.size_bytes} bytes"))
        if self.tags:
            tags_str = ", ".join(f"{k}={v}" for k, v in self.tags.items())
            rows.append(("Tags:", tags_str))

        return render_table("BackupModel", rows)
