"""Paginated response model."""

from __future__ import annotations

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

from pydantic import model_validator

from rulebook._models import BaseModel

__all__ = ["PaginatedResponse"]

_T = TypeVar("_T")


class PaginatedResponse(BaseModel, Generic[_T]):
    """Paginated list response with metadata.

    The ``data`` field contains the list of results for the current page.
    """

    data: List[_T]
    """List of results for the current page."""

    total_records: int
    """Total number of records matching the query."""

    page_size: int
    """Number of records per page."""

    total_pages: int
    """Total number of pages."""

    current_page: int
    """Current page number (zero-based)."""

    query_time_ms: Optional[int] = None
    """Server-side query execution time in milliseconds."""

    @model_validator(mode="before")
    @classmethod
    def _flatten_meta(cls, values: Any) -> Any:
        """Flatten the API ``meta`` envelope into root-level fields.

        The API returns ``{"data": [...], "meta": {"record_count": ..., ...}}``.
        This validator maps ``meta`` fields to the model's flat fields so the
        public SDK interface stays stable.
        """
        if not isinstance(values, dict):
            return values

        meta: Dict[str, Any] | None = values.get("meta")
        if meta is None or not isinstance(meta, dict):
            return values

        if "total_records" not in values and "record_count" in meta:
            values["total_records"] = meta["record_count"]
        if "page_size" not in values and "page_size" in meta:
            values["page_size"] = meta["page_size"]
        if "total_pages" not in values and "total_pages" in meta:
            values["total_pages"] = meta["total_pages"]
        if "current_page" not in values and "current_page" in meta:
            values["current_page"] = meta["current_page"]
        if "query_time_ms" not in values and "query_time_ms" in meta:
            values["query_time_ms"] = meta["query_time_ms"]

        return values
