{% set type_name = type.name | to_upper_camel_case -%}
import typing as t
from typing_extensions import Self
from pydantic import ModelWrapValidatorHandler, model_validator
from datetime import datetime
from .common import BaseModel

{% for c in referenced_components %}
from . {{ c | to_snake_case }} import {{ c | to_upper_camel_case }}
{%- endfor %}

class {{ type_name }}(BaseModel):
    {%- if type.fields | length > 0 %}
    {% include "types/struct_fields.py.jinja" %}
    {%- endif %}
    {{ type.discriminator_field }}: t.Union[
        {% for variant in type.variants -%}
            t.Literal["{{ variant.name }}"] {% if not loop.last %},{% endif %}
        {% endfor -%}
    ]
    {{ type.content_field }}: t.Union[
        {% set content_field_types = [] %}
        {{ type.variants| map(attribute="schema_ref", default="t.Dict[str,t.Any]") | unique | join(",") }}
    ]

    @model_validator(mode="wrap")
    @classmethod
    def validate_model(
        cls, data: t.Any, handler: ModelWrapValidatorHandler[Self]
    ) -> Self:
        {# `data` is a mapping on construction, but an already-built model
           instance when pydantic re-validates this nested model (e.g. when it
           is a field of another model). An instance is already correctly
           typed, so skip the mapping-only content-field massaging below. -#}
        if isinstance(data, cls):
            return handler(data)
        {# sadly this is needed because of pydantic -#}
        if "{{ type.content_field }}" not in data:
            data["{{ type.content_field }}"] = {}
        output = handler(data)
        {% for v in type.variants -%}


        {% if loop.first -%}if{% else %}elif{% endif %} output.type == "{{ v.name }}":
            {%- if v.schema_ref is defined %}
            output.{{ type.content_field | to_snake_case }} = {{ v.schema_ref | to_upper_camel_case }}.model_validate(data.get("{{ type.content_field }}", {}))
            {%- else %}
            output.{{ type.content_field | to_snake_case }} = data.get("{{ type.content_field }}", {})
            {%- endif %}
        {% endfor -%}
        else:
            raise ValueError(f"Unexpected type `{output.type}`")
        return output
