"""List method for async_backups namespace."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

import orjson

from pinecone._internal.logging import get_logger
from pinecone._internal.validation import require_non_empty
from pinecone.models.pagination import AsyncPaginator, Page


if TYPE_CHECKING:
    from pinecone.__interface__.backups import BackupInfoProtocol

logger = get_logger(__name__)


def list(  # noqa: A001
    self: Any,
    *,
    index_name: str | None = None,
    limit: int | None = None,
    pagination_token: str | None = None,
) -> AsyncPaginator[BackupInfoProtocol]:
    """List backups for a project or specific index asynchronously.

    Args:
        index_name: Optional index name to filter backups. If None, lists all
            backups in the project.
        limit: Maximum number of items to return (across all pages).
        pagination_token: Token to resume pagination from a previous call.

    Returns:
        AsyncPaginator[BackupInfoProtocol]: Iterator over BackupInfo objects.
        Iterate directly for items, or use .pages() for page-level access.

    Raises:
        ValueError: If index_name is an empty string or limit is not positive.
        APIError: If listing fails.

    Example:
        >>> # List all backups in project
        >>> async for backup in pc.backups.list():
        ...     print(f"{backup.backup_id}: {backup.status}")

    Example filtering by index:
        >>> # List backups for specific index
        >>> async for backup in pc.backups.list(index_name="my-index"):
        ...     print(f"{backup.name}: {backup.status}")

    Example with page-level access:
        >>> async for page in pc.backups.list().pages():
        ...     print(f"Got {len(page.items)} backups")
    """
    # Validate inputs
    if index_name is not None:
        require_non_empty("index_name", index_name)
    if limit is not None and limit <= 0:
        raise ValueError(f"limit must be a positive integer, received: {limit}")

    logger.info(
        "Listing backups",
        index_name=index_name,
        limit=limit,
        has_pagination_token=pagination_token is not None,
    )

    async def fetch_page(token: str | None) -> Page[BackupInfoProtocol]:
        """Fetch a page of backups asynchronously."""
        logger.debug("Fetching backups page", pagination_token=token, index_name=index_name)

        try:
            # Build URL - different endpoints for project-wide vs index-specific
            if index_name is not None:
                url = f"{self._base_url}/indexes/{index_name}/backups"
            else:
                url = f"{self._base_url}/backups"

            # Build query params
            params = {}
            if token:
                params["paginationToken"] = token

            response = await self._http.get(
                url,
                headers=self._headers,
                params=params,
            )

            data = orjson.loads(response.content)
            backups = self._adapter.to_backup_list(data)

            logger.debug(
                "Successfully fetched backups",
                backup_count=len(backups),
                index_name=index_name,
            )

            # Extract next token from response
            pagination = data.get("pagination")
            next_token = pagination.get("next") if pagination else None
            return Page(items=backups, pagination_token=next_token)

        except Exception:
            logger.exception("Failed to list backups", index_name=index_name)
            raise

    return AsyncPaginator(
        fetch_page=fetch_page,
        initial_token=pagination_token,
        limit=limit,
        item_type="BackupModel",
    )
