from __future__ import annotations

import logging
from collections.abc import Mapping
from typing import Any, TypeVar, cast

from pydantic import BaseModel, ConfigDict, model_validator

logger = logging.getLogger(__name__)

ModelT = TypeVar("ModelT", bound="APIDataModel")


class APIDataModel(BaseModel):
    """Frozen Pydantic base for all API response models.

    Extra fields from the server are silently ignored and logged at
    ``DEBUG`` level, so new API fields never cause validation errors.
    """

    model_config = ConfigDict(extra="ignore", frozen=True)

    @model_validator(mode="before")
    @classmethod
    def _warn_extra(cls: type[ModelT], data: Any) -> Any:
        if not isinstance(data, Mapping):
            return data

        data = cast("Mapping[str, Any]", data)
        known = set(cls.model_fields.keys()) | {
            f.alias for f in cls.model_fields.values() if f.alias
        }
        incoming_keys: set[str] = set(data.keys())
        extra: set[str] = incoming_keys - known

        if extra:
            logger.debug(
                "%s: extra fields ignored: %s",
                cls.__name__,
                sorted(extra),
            )

        return data
