"""ابزارهای صفحه‌بندی مشترک (offset/limit).

از این مدل‌ها در همه سرویس‌ها برای پاسخ‌های لیستی استفاده می‌شود.
"""
from __future__ import annotations

from typing import Generic, Sequence, TypeVar

from pydantic import BaseModel, Field

T = TypeVar("T")

DEFAULT_PAGE_SIZE = 20
MAX_PAGE_SIZE = 500


class PaginationParams(BaseModel):
    """پارامترهای صفحه‌بندی ورودی."""

    page: int = Field(default=1, ge=1, description="شماره صفحه از ۱")
    page_size: int = Field(
        default=DEFAULT_PAGE_SIZE,
        ge=1,
        le=MAX_PAGE_SIZE,
        description="تعداد آیتم در هر صفحه",
    )

    @property
    def offset(self) -> int:
        return (self.page - 1) * self.page_size

    @property
    def limit(self) -> int:
        return self.page_size


class PageMeta(BaseModel):
    page: int
    page_size: int
    total_items: int
    total_pages: int


class Page(BaseModel, Generic[T]):
    """پاسخ لیستی صفحه‌بندی‌شده."""

    items: Sequence[T]
    meta: PageMeta

    @classmethod
    def create(
        cls,
        items: Sequence[T],
        total_items: int,
        params: PaginationParams,
    ) -> "Page[T]":
        total_pages = (total_items + params.page_size - 1) // params.page_size if params.page_size else 0
        return cls(
            items=items,
            meta=PageMeta(
                page=params.page,
                page_size=params.page_size,
                total_items=total_items,
                total_pages=total_pages,
            ),
        )
