"""Collections namespace implementation for managing collection resources.

This module provides collection management operations (CRUD) for Pinecone collections.
Collections are static copies of indexes useful for backups and cloning.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from pinecone.__interface__.collections import CollectionNamespaceProtocol
from pinecone._internal.adapters.collections_adapter import CollectionsAdapter
from pinecone._internal.constants import CONTROL_PLANE_API_VERSION
from pinecone._internal.introspection import InteractiveIntrospectionMixin


if TYPE_CHECKING:
    from pinecone._internal.http import HTTPClient
    from pinecone.collections import _create, _delete, _describe, _list


class Collections(InteractiveIntrospectionMixin, CollectionNamespaceProtocol):
    """Implementation of collection management operations.

    This class provides CRUD operations for managing Pinecone collections.
    Collections are static, non-queryable copies of pod-based indexes that only
    consume storage (no compute costs). They are useful for backups, cloning,
    and temporarily shutting down indexes.

    Note:
        - Serverless indexes do not support collections. Only pod-based indexes
          can create collections.
        - Collections cannot be moved between projects once created.
        - Collection creation is asynchronous and may take time to complete
          (typically ~10 minutes for p1/s1 pods, potentially hours for p2 pods
          with millions of vectors).

    Args:
        http_client: HTTP client for making API requests
        base_url: Base URL for the Collections API

    Example:
        >>> from pinecone import Pinecone
        >>> pc = Pinecone(api_key="...")
        >>> collections = pc.collections
        >>>
        >>> # List collections
        >>> for coll in collections.list():
        ...     print(f"{coll.name}: {coll.status}")
        >>>
        >>> # Create collection from index
        >>> collections.create(name="my-backup", source="my-index")
        >>>
        >>> # Poll until collection is ready
        >>> import time
        >>> while True:
        ...     info = collections.describe("my-backup")
        ...     if info.status == "Ready":
        ...         break
        ...     print(f"Status: {info.status}")
        ...     time.sleep(10)
        >>>
        >>> # Delete collection
        >>> collections.delete("my-backup")
    """

    def __init__(
        self,
        http_client: HTTPClient,
        base_url: str = "https://api.pinecone.io",
    ):
        """Initialize Collections namespace.

        Args:
            http_client: HTTP client for making API requests
            base_url: Base URL for the Collections API. Defaults to production endpoint.
        """
        self._http = http_client
        self._base_url = base_url
        self._adapter = CollectionsAdapter()
        self._headers = {"X-Pinecone-Api-Version": CONTROL_PLANE_API_VERSION}

        # Import and bind methods once at initialization (eager binding)
        from pinecone.collections import _create, _delete, _describe, _list  # noqa: PLC0415

        self.list = _list.list.__get__(self, type(self))  # type: ignore[method-assign]
        self.create = _create.create.__get__(self, type(self))  # type: ignore[method-assign]
        self.delete = _delete.delete.__get__(self, type(self))  # type: ignore[method-assign]
        self.describe = _describe.describe.__get__(self, type(self))  # type: ignore[method-assign]

    # Protocol method stubs (overridden in __init__)
    def list(self, *args, **kwargs):  # type: ignore[no-untyped-def]
        """Stub for list method (overridden in __init__)."""
        raise NotImplementedError  # pragma: no cover

    def create(self, *args, **kwargs):  # type: ignore[no-untyped-def]
        """Stub for create method (overridden in __init__)."""
        raise NotImplementedError  # pragma: no cover

    def delete(self, *args, **kwargs):  # type: ignore[no-untyped-def]
        """Stub for delete method (overridden in __init__)."""
        raise NotImplementedError  # pragma: no cover

    def describe(self, *args, **kwargs):  # type: ignore[no-untyped-def]
        """Stub for describe method (overridden in __init__)."""
        raise NotImplementedError  # pragma: no cover

    def __repr__(self) -> str:
        """Return string representation of collections namespace."""
        return f"Collections(base_url='{self._base_url}')"
