(function () {
    function boot() {
        console.log('Booting Formatrica frontend...');
        const wrappers = document.querySelectorAll('.formatrica');
        if (!wrappers.length) {
            return;
        }
        const settings = window.formatricaFrontend || {};
        const apiRoot = (
            window.wpApiSettings && window.wpApiSettings.root
                ? window.wpApiSettings.root
                : window.location.origin + '/wp-json/'
        ).replace(/\/$/, '');
        const restUrl = settings.restUrl || apiRoot + '/formatrica/v1';
        wrappers.forEach((wrapper) => {
            if (wrapper.dataset.fmtBooted === '1') {
                return;
            }
            const form = wrapper.querySelector('.formatrica__form');
            const formId = Number(wrapper.dataset.formId || 0);
            if (!form || !restUrl || !formId) {
                return;
            }
            wrapper.dataset.fmtBooted = '1';
            const messageEl = form.querySelector('.formatrica__messages');
            const submitButton = form.querySelector('.formatrica__submit');
            const successMessage =
                form.dataset.successMessage ||
                settings.successMessage ||
                'Thanks!';
            const errorMessage =
                form.dataset.errorMessage ||
                settings.errorMessage ||
                'Submission failed. Please try again.';
            form.addEventListener('submit', async (event) => {
                event.preventDefault();
                clearMessages();
                clearErrors(form);
                setSubmitting(true);
                try {
                    const payload = buildPayload(form);
                    const response = await fetch(
                        `${restUrl}/forms/${formId}/submissions`,
                        {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify(payload),
                        }
                    );
                    const result = await response.json().catch(() => ({}));
                    if (!response.ok || !result.success) {
                        if (result && result.errors && result.errors.fields) {
                            applyErrors(form, result.errors.fields);
                        }
                        showMessage(
                            'error',
                            result && result.message
                                ? result.message
                                : errorMessage
                        );
                        requestAnimationFrame(() => focusFirstInvalid(form));
                        return;
                    }
                    showMessage('success', result.message || successMessage);
                    form.reset();
                } catch (error) {
                    showMessage('error', errorMessage);
                } finally {
                    setSubmitting(false);
                }
            });

            function showMessage(type, text) {
                if (!messageEl) {
                    return;
                }
                messageEl.innerHTML = '';
                const notice = document.createElement('div');
                notice.className = `formatrica__notice formatrica__notice--${type}`;
                notice.id = `fmt-message-${formId}`;
                notice.setAttribute('role', 'status');
                notice.setAttribute('tabindex', '-1');
                notice.textContent = text;
                messageEl.appendChild(notice);
                requestAnimationFrame(() => {
                    notice.focus({ preventScroll: true });
                });
            }

            function clearMessages() {
                if (messageEl) {
                    messageEl.innerHTML = '';
                }
            }

            function setSubmitting(isSubmitting) {
                if (submitButton) {
                    submitButton.disabled = isSubmitting;
                }
                wrapper.classList.toggle(
                    'formatrica--submitting',
                    isSubmitting
                );
            }
        });

        function buildPayload(form) {
            const formData = new FormData(form);
            const payload = Object.fromEntries(formData.entries());
            const checkboxState = {};
            form.querySelectorAll('input[type="checkbox"][name]').forEach(
                (checkbox) => {
                    const name = checkbox.name;
                    if (!checkboxState[name]) {
                        checkboxState[name] = { total: 0, values: [] };
                    }
                    checkboxState[name].total += 1;
                    if (checkbox.checked) {
                        const value = checkbox.value || 'on';
                        checkboxState[name].values.push(value);
                    }
                }
            );
            Object.entries(checkboxState).forEach(([name, state]) => {
                if (state.total > 1) {
                    payload[name] = state.values;
                } else {
                    payload[name] = state.values.length > 0;
                }
            });
            form.querySelectorAll('select[multiple][name]').forEach(
                (select) => {
                    payload[select.name] = Array.from(
                        select.selectedOptions
                    ).map((option) => option.value);
                }
            );
            return payload;
        }

        function applyErrors(form, errors) {
            let hasErrors = false;
            Object.entries(errors).forEach(([name, message]) => {
                const errorHolder =
                    form.querySelector(
                        `[data-error-for="${escapeSelector(name)}"]`
                    ) || ensureErrorHolder(form, name);
                if (!errorHolder) {
                    return;
                }
                hasErrors = true;
                const control = form.querySelector(getFieldSelector(name));
                if (control) {
                    control.setAttribute('aria-invalid', 'true');
                    const errorId = ensureErrorId(errorHolder, control);
                    control.setAttribute('aria-describedby', errorId);
                }
                errorHolder.textContent = message;
                const group = errorHolder.closest('.formatrica__group');
                if (group) {
                    group.classList.add('formatrica__group--error');
                }
            });
            if (hasErrors) {
                requestAnimationFrame(() => focusFirstInvalid(form));
            }
        }

        function clearErrors(form) {
            form.querySelectorAll('.formatrica__group--error').forEach(
                (group) => {
                    group.classList.remove('formatrica__group--error');
                }
            );
            form.querySelectorAll('.formatrica__error').forEach((error) => {
                const control = form.querySelector(
                    getFieldSelector(error.dataset.errorFor)
                );
                if (control) {
                    control.removeAttribute('aria-invalid');
                    if (control.getAttribute('aria-describedby') === error.id) {
                        control.removeAttribute('aria-describedby');
                    }
                }
                error.textContent = '';
            });
        }
    }

    function escapeSelector(value) {
        if (window.CSS && typeof window.CSS.escape === 'function') {
            return window.CSS.escape(String(value));
        }

        return String(value).replace(
            /([ #;?%&,.+*~':"!^$\\[\\]\\(){}|<>@])/g,
            '\\$1'
        );
    }

    function ensureErrorHolder(form, fieldName) {
        const field = form.querySelector(getFieldSelector(fieldName));
        const group =
            field && field.closest
                ? field.closest('.formatrica__group')
                : null;
        if (!group) {
            return null;
        }
        const errorHolder = document.createElement('p');
        errorHolder.className = 'formatrica__error';
        errorHolder.dataset.errorFor = fieldName;
        errorHolder.setAttribute('role', 'alert');
        group.appendChild(errorHolder);
        return errorHolder;
    }

    function ensureErrorId(errorHolder, control) {
        if (errorHolder.id) {
            return errorHolder.id;
        }
        const baseId = (control.id || control.name || 'fmt-field').replace(
            /[^a-z0-9_-]/gi,
            ''
        );
        const errorId = `${baseId || 'fmt-field'}-error`;
        errorHolder.id = errorId;
        return errorId;
    }

    function focusFirstInvalid(form) {
        const invalid = form.querySelector('[aria-invalid="true"]');
        if (invalid) {
            invalid.focus({ preventScroll: false });
        }
    }

    function getFieldSelector(name) {
        const escaped = escapeSelector(name);
        return `[name="${escaped}"], [id="${escaped}"]`;
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', boot);
    } else {
        boot();
    }
})();
