"""Cursor pagination models for the public /v1 surface."""

from __future__ import annotations

from typing import Any, Callable, Generic, Iterator, TypeVar

from ..base import SDKModel

T = TypeVar("T")
_P = TypeVar("_P")


class Pagination(SDKModel):
    next_cursor: str | None = None
    has_more: bool = False
    page_size: int | None = None
    total_estimate: int | None = None


class Page(SDKModel, Generic[T]):
    data: list[T]
    pagination: Pagination
    request_id: str | None = None

    def __iter__(self) -> Iterator[T]:  # type: ignore[override]
        return iter(self.data)

    def __len__(self) -> int:
        return len(self.data)

    def __getitem__(self, index: int) -> T:
        return self.data[index]


def auto_paginate(fetch: Callable[..., Page[_P]], **kwargs: Any) -> Iterator[_P]:
    """Lazy auto-paginating iterator.

    Usage::

        for clip in auto_paginate(client.clips.list, factory_id="abc"):
            print(clip.clip_id)
    """
    cursor = kwargs.pop("cursor", None)
    while True:
        page = fetch(**kwargs, cursor=cursor)
        yield from page.data
        if not page.pagination.has_more or not page.pagination.next_cursor:
            break
        cursor = page.pagination.next_cursor
