{# ---------- Type Mapping for Mapped[] annotations ---------- #}
{# Map datetime types to their aliased versions to avoid name conflicts with column names #}
{%- macro mapped_type(type_name) -%}
    {%- if type_name == 'time' -%}dt_time
    {%- elif type_name == 'date' -%}dt_date
    {%- elif type_name == 'datetime' -%}dt_datetime
    {%- else -%}{{ type_name }}
    {%- endif -%}
{%- endmacro %}

{# ---------- Attribute Renderer ---------- #}
{%- macro render_attributes(class, enumerations, types, ids, sort) %}
    {%- for attribute in sort(class.attributes) %}
    {%- set is_pk = attribute.is_id or (attribute.name == ids.get(class.name)) %}
    {%- set nullable = attribute.is_optional and not is_pk %}
    {{ attribute.name }}: Mapped[{% if nullable %}Optional[{{ mapped_type(attribute.type.name) }}]{% else %}{{ mapped_type(attribute.type.name) }}{% endif %}] = mapped_column({% if attribute.type.name in enumerations|map(attribute='name') %}Enum({{ attribute.type.name }}){% else %}{{types[attribute.type.name]}}{% endif %}
    {%- if is_pk %}, primary_key=True{% endif %}
    {%- if nullable %}, nullable=True{% endif %}
    {%- if attribute.default_value is not none %}, default={% if attribute.type.name == 'str' or attribute.type.name == 'string' %}"{{ attribute.default_value }}"{% elif attribute.type.name == 'bool' %}{{ attribute.default_value | capitalize }}{% elif attribute.type.__class__.__name__ == 'Enumeration' %}{{ attribute.type.name }}.{{ attribute.default_value }}{% else %}{{ attribute.default_value }}{% endif %}{% endif %})
    {%- endfor %}
{%- endmacro %}

{# ---------- Relationship Renderer ---------- #}
{%- macro render_relationship(class, end, ns, ids, fkeys) %}
    {%- set other_end = (end.owner.ends | reject('equalto', end) | list)[0] %}
    {%- set is_many = end.multiplicity.max > 1 %}
    {%- set is_secondary = other_end.multiplicity.max > 1 %}
    {%- set fk_needed = end.owner.name in fkeys %}
    {%- set secondary = end.owner.name.lower() if is_secondary else None %}
    {%- if fk_needed %}
        {%- set fk_expr = fkeys[end.owner.name][0] + "." + fkeys[end.owner.name][1] + "_id" %}
    {%- else %}
        {%- set fk_expr = None %}
    {%- endif %}
    {%- if is_many -%}
{{class.name}}.{{end.name}}: Mapped[List["{{end.type.name}}"]] = relationship("{{end.type.name}}"
        {%- if secondary %}, secondary={{ secondary }}{% endif %}, back_populates="{{other_end.name}}"
        {%- if fk_needed %}{% if fk_needed %}, foreign_keys=[{{ fk_expr }}]{% endif %}{% endif %})
    {%- else -%}
{{class.name}}.{{end.name}}: Mapped["{{end.type.name}}"] = relationship("{{end.type.name}}", back_populates="{{other_end.name}}"{% if fk_needed %}, foreign_keys=[{{ fk_expr }}]{% endif %})
    {%- endif -%}
{%- endmacro %}