class PagedQueryResult:
    """
    defines results of a paged query.
    :ivar str direction: 'asc' or 'desc' direction.
    :ivar int page: page number return on current result.
    :ivar list results: list of results records return by the query.
    :ivar int size: number of records per page.
    :ivar str sort: column name used in sorting.
    :ivar int total: total number of results on all pages.
    """

    def __init__(self,
                 total: int = None,
                 page: int = None,
                 size: int = None,
                 sort: str = None,
                 direction: str = None):
        self.total = total
        self.page = page
        if page < 0:
            raise ValueError("page must be a positive number")
        self.size = size
        if size < 0 or size > 200:
            raise ValueError("size is limited to 200")
        self.sort = sort
        if sort is None:
            raise ValueError("sort is mandatory")
        self.direction = direction
        if direction != 'asc' and direction != 'desc':
            raise ValueError("direction must be asc or desc")
        self.results = None

    @classmethod
    def from_dict(cls, data: dict, dto_class=None) -> "PagedQueryResult":
        """
        build a PagedQueryResult from a JSON response dictionary.
        :param data: dictionary from the API response.
        :param dto_class: class with a from_dict classmethod used to deserialize each result item.
        :return: PagedQueryResult with deserialized results.
        """
        result = cls(
            total=int(data.get("total", 0)),
            page=data.get("page", 1),
            size=data.get("size", 50),
            sort=data.get("sort", "id"),
            direction=data.get("direction", "desc"),
        )
        result.results = []
        for obj in data.get("results", []):
            if dto_class is not None and hasattr(dto_class, 'from_dict'):
                result.results.append(dto_class.from_dict(obj))
            else:
                result.results.append(obj)
        return result

    def to_json(self):
        """
        format the results
        """

        if self.direction == "asc":
            sort_dir = "asc"
        else:
            sort_dir = "desc"

        formatted_results = []
        if self.results:
            for obj in self.results:
                if hasattr(obj, 'to_json'):
                    formatted_results.append(obj.to_json())
                elif hasattr(obj, 'to_dict'):
                    formatted_results.append(obj.to_dict())
                else:
                    formatted_results.append(obj)
        return {
            "page": self.page,
            "size": self.size,
            "sort": self.sort,
            "direction": sort_dir,
            "total": self.total,
            "results": formatted_results
        }