"""Core API pagination classes.

Two classes are provided:

``StandardPagination``
    Page-number based.  ``page_size=25``, ``max_page_size=200``.
    Response envelope::

        {
            "count": 142,
            "next": "https://example.com/api/v1/...?page=3",
            "previous": "https://example.com/api/v1/...?page=1",
            "page": 2,
            "page_size": 25,
            "results": [...]
        }

``StandardCursorPagination``
    Cursor-based for real-time / infinite-scroll lists.  Stable against
    concurrent inserts.  ``page_size=25``, ``max_page_size=100``,
    ordered by ``-created_at`` by default.
    Response envelope::

        {
            "next": "<opaque cursor>",
            "previous": "<opaque cursor>",
            "results": [...]
        }

Usage::

    from simorgh.core.api.pagination import StandardPagination, StandardCursorPagination

    class MyView(TenantListCreateView):
        pagination_class = StandardCursorPagination
"""
from __future__ import annotations

from rest_framework.pagination import CursorPagination, PageNumberPagination
from rest_framework.response import Response

__all__ = [
    "StandardPagination",
    "StandardCursorPagination",
]


class StandardPagination(PageNumberPagination):
    """Page-number pagination with a consistent response envelope.

    Query parameters:
        ``page``      — 1-based page number (default: 1)
        ``page_size`` — items per page (default: 25, max: 200)
    """

    page_size = 25
    max_page_size = 200
    page_size_query_param = "page_size"
    page_query_param = "page"

    def get_paginated_response(self, data: list) -> Response:
        return Response(
            {
                "count": self.page.paginator.count,
                "next": self.get_next_link(),
                "previous": self.get_previous_link(),
                "page": self.page.number,
                "page_size": self.get_page_size(self.request),
                "results": data,
            }
        )

    def get_paginated_response_schema(self, schema: dict) -> dict:
        return {
            "type": "object",
            "required": ["count", "results"],
            "properties": {
                "count": {"type": "integer"},
                "next": {"type": "string", "nullable": True, "format": "uri"},
                "previous": {"type": "string", "nullable": True, "format": "uri"},
                "page": {"type": "integer"},
                "page_size": {"type": "integer"},
                "results": schema,
            },
        }


class StandardCursorPagination(CursorPagination):
    """Cursor-based pagination for real-time and infinite-scroll endpoints.

    * Ordered by ``-created_at`` (newest first) by default.
    * Override ``ordering`` on the view or subclass for different orderings.

    Query parameters:
        ``cursor``    — opaque cursor from a previous response
        ``page_size`` — items per page (default: 25, max: 100)
    """

    page_size = 25
    max_page_size = 100
    page_size_query_param = "page_size"
    ordering = "-created_at"
    cursor_query_param = "cursor"

    def get_paginated_response(self, data: list) -> Response:
        return Response(
            {
                "next": self.get_next_link(),
                "previous": self.get_previous_link(),
                "results": data,
            }
        )

    def get_paginated_response_schema(self, schema: dict) -> dict:
        return {
            "type": "object",
            "properties": {
                "next": {"type": "string", "nullable": True, "format": "uri"},
                "previous": {"type": "string", "nullable": True, "format": "uri"},
                "results": schema,
            },
        }
