"""Shared Pydantic configuration.

The API speaks camelCase (the dashboard and the extension are TypeScript) while
the ORM stays snake_case. ``CamelModel`` bridges the two and accepts either form
on input.
"""

from __future__ import annotations

from typing import Generic, TypeVar

from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel

T = TypeVar("T")


class CamelModel(BaseModel):
    model_config = ConfigDict(
        alias_generator=to_camel,
        populate_by_name=True,
        from_attributes=True,
        str_strip_whitespace=True,
    )


class Page(CamelModel, Generic[T]):
    """Envelope returned by every list endpoint."""

    items: list[T]
    total: int
    page: int = 1
    page_size: int = 50

    @property
    def pages(self) -> int:
        return max(1, -(-self.total // self.page_size))


class Message(CamelModel):
    detail: str
    ok: bool = True
