{% load django_glue %}

<div x-data="{
        value: null
    }"
        {% if glue_model_field %}
            x-modelable="value"
            x-model="{{ glue_model_field }}"
        {% endif %}

        {% if glue_field %}
            x-modelable="value"
            x-model="{{ glue_field }}.value"
        {% endif %}
>
    <div
        x-data="{
            glue_field: undefined,
            init() {
                    let glue_model_field_name = '{{ glue_model_field }}'
                    let glue_field_name = '{{ glue_field }}'

                    if (glue_model_field_name) {
                        this.init_glue_model_field(glue_model_field_name)
                    } else if (glue_field_name) {
                        this.init_glue_field(glue_field_name)
                    }

                    if (this.is_valid_glue_field()) {
                        this.set_field_attrs()
                        this.add_error_event_listener()
                    }

                    this.$watch('glue_field', value => {
                        if (this.is_valid_glue_field()) {
                            this.set_field_attrs()
                        }

                    })
            },
            init_glue_model_field(glue_model_field_name) {
                let path = glue_model_field_name.split('.')
                this.glue_field = this[`${path[0]}`]['glue_fields'][`${path[1]}`]
            },
            init_glue_field(glue_field_name) {
                this.glue_field = glue_field_name.split('.').reduce((acc, part) => acc && acc[part], this)
            },
            set_field_attrs() {
                let form_field = this.$refs.glue_field

                // Remove attrs that no longer exist
                let attr_names = this.glue_field._attr_names
                for (const attr_name of this.glue_field._historic_attr_names) {
                        if (!attr_names.includes(attr_name)) {
                            form_field.removeAttribute(attr_name)
                        }
                    }

                // Set attrs on field
                for (let attr of this.glue_field.attrs) {
                    form_field.setAttribute(attr.name, attr.value)
                }
            },
            add_error_event_listener() {                
                this.$refs.glue_field.addEventListener('invalid', (e) => {
                    e.preventDefault();
                    this.glue_field.error = e.target.validationMessage
                    this.$refs.glue_field.scrollIntoView({ behavior: 'smooth', block: 'center' })
                })
            },
            is_valid_glue_field() {
                return this.glue_field && this.$refs.glue_field
            }
        }"
    >
        {% block field_label %}
            <label
                x-cloak
                x-show="!glue_field._hide_label"
                x-ref="label"
                class="form-label"
                :for="glue_field.id"
            >
                <span x-text="glue_field.label"></span><span x-cloak x-show="glue_field.required">*</span>
            </label>
        {% endblock %}
        {% block field_content %}
        {% endblock %}
        <div x-show="glue_field.error">
            <span class="text-danger glue-fs--1" x-text="glue_field.error"></span>
        </div>
    </div>
</div>
