"""
Generated class for {{structure_definition.type}}. 
Time: {{time}}
"""
{% for dependency in structure_definition.dependencies -%}
from fhirmodels.{{dir_name}}.{{dependency}} import *
{% endfor %}
{%- if structure_definition.base_class %}
{%- if structure_definition.base_import_string -%}
from {{structure_definition.base_import_string}} import {{structure_definition.base_class}}
{%- else -%}
from fhirmodels.{{dir_name}}.{{structure_definition.base_class}} import *
{% endif %}
{% endif %}

{%- macro render_contained_element(element) %}

class {{ element.type }}({{ element.base_class }}):
    """ {{ element.description }}
    {%- for child in element.defined_children -%}
    :param {{ child.type_string }} {{ child.name }}: {{ child.short }}
    {% endfor -%}
    """
    # needed for complex properties where the element name is different from the class name
    property_class_info = {
        {% for child in element.defined_children -%}
        {% if not child.is_primitive %}
        "{{ child.name }}": {"class_name": "{{ child.type_string }}", "is_contained": {{ child.is_contained }}},
        {% endif %}
        {% endfor -%}
    }
    def __init__(self, {% for child in element.defined_children %} {{ child.name }}: {% if child.is_array %} list['{{ child.type_string }}'] {% else %} '{{child.type_string}}' {%endif%} = None, {% endfor %}):
        {% for child in element.defined_children %}
        {%- if child.is_array -%}
        self.{{child.name}} = {{child.name}} or []
        {%- else -%}
        self.{{child.name}} = {{child.name}} {% endif %}
        {% endfor %}

    @classmethod
    def from_dict(cls, data: dict) -> "{{structure_definition.type}}":
        return super().from_dict(data)
    
    @classmethod
    def from_obj(self, obj: object) -> "{{structure_definition.type}}":
        return super().from_obj(obj)

    def as_dict(self) -> dict:
        return super().as_dict()
{% endmacro -%}


{%- macro render_contained_elements(elements) %}
{%- for element in elements %}
    {% if element.contained_children %}
        {{ render_contained_elements(element.contained_children) }}  {# Recursively call render_contained_elements for contained_children #}
    {% endif %}
    {{ render_contained_element(element) }}
{% endfor %}
{% endmacro -%}

{{ render_contained_elements(structure_definition.contained_elements) -}}

class {{structure_definition.type}}{% if structure_definition.base_class %}({{structure_definition.base_class}}){% endif %}:
    """ {{structure_definition.description}}
    {% for element in structure_definition.defined_elements -%}
    :param {{element.type_string}} {{element.name}}: {{element.short}}
    {% endfor -%}
    """
    # needed for complex properties where the element name is different from the class name
    property_class_info = {
        {% for element in structure_definition.defined_elements -%}
        {% if not element.is_primitive %}
        "{{ element.name }}": {"class_name": "{{ element.type_string }}", "is_contained": {{ element.is_contained }}},
        {% endif %}
        {% endfor -%}
    }
    def __init__(self, {% for element in structure_definition.defined_elements %} {{ element.name }}: {% if element.is_array %} list['{{ element.type_string }}'] {% else %} '{{element.type_string}}' {%endif%} = None, {% endfor %}):
        {% if structure_definition.is_resource %}
        self.resourceType = "{{structure_definition.type}}"
        {% endif %}
        {% for element in structure_definition.defined_elements %}
        {%- if element.is_array -%}
        self.{{element.name}} = {{element.name}} or []
        {%- else -%}
        self.{{element.name}} = {{element.name}} {% endif %}
        {% endfor %}

    @classmethod
    def from_dict(cls, data: dict) -> "{{structure_definition.type}}":
        return super().from_dict(data)
    
    @classmethod
    def from_obj(self, obj: object) -> "{{structure_definition.type}}":
        return super().from_obj(obj)

    def as_dict(self) -> dict:
        return super().as_dict()