"""Part — tipo suma de las partes posibles de un mensaje multipart."""

from typing import Union

from context_part import ContextPart
from text_part import TextPart
from tool_part import ToolPart

Part = Union[TextPart, ContextPart, ToolPart]

_PART_TYPES: dict[str, type] = {
    "text": TextPart,
    "context": ContextPart,
    "tool": ToolPart,
}


def part_from_dict(data: dict) -> Part:
    """Deserializa un Part desde un dict usando el campo 'type' como discriminador.

    Args:
        data: Dict con al menos el campo 'type' y los campos del Part correspondiente.

    Returns:
        La instancia del Part concreto (TextPart, ContextPart o ToolPart).

    Raises:
        ValueError: Si el campo 'type' no esta presente o es desconocido.
    """
    kind = data.get("type")
    if kind is None:
        raise ValueError("El dict no contiene el campo 'type' requerido para deserializar Part")
    cls = _PART_TYPES.get(kind)
    if cls is None:
        raise ValueError(f"Tipo de Part desconocido: '{kind}'. Valores validos: {list(_PART_TYPES)}")
    fields = {k: v for k, v in data.items() if k != "type"}
    return cls(**fields)
