from __future__ import annotations

from dataclasses import asdict, dataclass, fields
from typing import Any, ClassVar, Mapping


@dataclass
class DatasetSchema:
    """Base dataclass for all dataset row schemas."""

    DATASET_NAME: ClassVar[str]
    CONFIG_NAME: ClassVar[str | None] = None

    @classmethod
    def dataset_name(cls) -> str:
        return cls.DATASET_NAME

    @classmethod
    def config_name(cls) -> str | None:
        return cls.CONFIG_NAME

    @classmethod
    def from_example(cls, example: Mapping[str, Any]) -> "DatasetSchema":
        """Instantiate the dataclass from a raw HF example mapping."""
        field_names = [f.name for f in fields(cls) if f.init]
        missing = [name for name in field_names if name not in example]
        if missing:
            raise KeyError(f"Missing fields for {cls.__name__}: {', '.join(missing)}")
        values = {name: example[name] for name in field_names}
        return cls(**values)  # type: ignore[arg-type]

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)
