from typing import Any, Generic, List, Optional, TypeVar

from pydantic import BaseModel, Field
from pydantic.generics import GenericModel

T = TypeVar("T")


class PaginationMeta(BaseModel):
    """
    Pagination metadata schema with navigation links and counts
    """
    total: int = Field(description="Total number of records")
    page: int = Field(description="Current page number")
    per_page: int = Field(description="Number of records per page")
    next: Optional[str] = Field(None, description="URL for next page")
    previous: Optional[str] = Field(None, description="URL for previous page")
    first: str = Field(description="URL for first page")
    last: str = Field(description="URL for last page")


class PaginatedResponse(GenericModel, Generic[T]):
    """
    Generic paginated response model that can be used with any data type
    """
    meta: PaginationMeta
    result: List[T]
    
    @classmethod
    def from_paginator_dict(cls, paginator_dict: dict[str, Any]) -> "PaginatedResponse":
        """
        Create a PaginatedResponse from a paginator's dictionary output
        """
        meta = PaginationMeta(
            total=paginator_dict["total"],
            page=paginator_dict["page"],
            per_page=paginator_dict["per_page"],
            next=paginator_dict["next"],
            previous=paginator_dict["previous"],
            first=paginator_dict["first"],
            last=paginator_dict["last"],
        )
        
        return cls(meta=meta, result=paginator_dict["result"])