
import math
from fastapi import Query
from fastapi_pagination.bases import  AbstractPage,AbstractParams,RawParams
from pydantic import BaseModel
from typing import Any, Generic, List, Type,TypeVar,Generic,Sequence
from fastapi_pagination import  Page,utils

T = TypeVar('T')

class ApiReturnModel(BaseModel,Generic[T]):
    code:int = 0
    msg:str ="OK"
    data:T

class ApiReturnError(BaseModel):
    code:int = -1
    msg:str =""


class Params(BaseModel, AbstractParams):
    page:int = Query(1,get=1, description="Page number")
    size:int = Query(20,get=0, le=100,description="Page size")

    def to_raw_params(self) -> RawParams:
        return RawParams(
            limit=self.size,
            offset=self.size*(self.page-1)
            )
    
class ApiReturnPage(AbstractPage[T],Generic[T]):
    code:int =0
    msg:str ="OK"
    data:Sequence[T]
    total:int
    page:int
    size:int
    # next:str
    # previous:str
    total_pages:int

    __params_type__ =Params

    @classmethod
    def create(cls,items:Sequence[T],params:Params,**kwargs: Any) -> Type[Page[T]]:
        total =  kwargs.get('total', 0)
        total_pages = math.ceil(total/params.size)
    
        return utils.create_pydantic_model(cls,data=items,total=total,page=params.page,size=params.size,total_pages=total_pages)
