/**
 * AgentForms WordPress Plugin — AJAX Submission Handler
 *
 * Handles form submission, multi-step navigation, conditional field visibility,
 * and client-side validation. All server-side logic remains on agentforms.io.
 *
 * Loaded by includes/shortcode.php via wp_enqueue_script().
 */

(function () {
    'use strict';

    // ── Conditional field engine ──────────────────────────────────────

    function evaluateCondition(condition, allData) {
        if (!condition) return true;

        const targetValue = allData[condition.field] || '';
        const op = condition.operator || 'eq';
        const compareValue = String(condition.value || '').trim();
        const targetStr = String(targetValue).trim();

        if (op === 'filled') return Boolean(targetStr);
        if (op === 'empty') return !Boolean(targetStr);

        if (['gt', 'lt', 'gte', 'lte'].includes(op)) {
            const t = parseFloat(targetStr);
            const c = parseFloat(compareValue);
            if (isNaN(t) || isNaN(c)) return false;
            switch (op) {
                case 'gt': return t > c;
                case 'lt': return t < c;
                case 'gte': return t >= c;
                case 'lte': return t <= c;
            }
        }

        switch (op) {
            case 'eq': return targetStr === compareValue;
            case 'neq': return targetStr !== compareValue;
            case 'contains': return targetStr.includes(compareValue);
            case 'not_contains': return !targetStr.includes(compareValue);
            case 'in': return targetStr.split(',').includes(compareValue);
            case 'not_in': return !targetStr.split(',').includes(compareValue);
            default: return true;
        }
    }

    function updateFieldVisibility(form) {
        const data = getFormData(form);

        form.querySelectorAll('[data-af-condition]').forEach(function (fieldWrapper) {
            const conditionStr = fieldWrapper.getAttribute('data-af-condition');
            if (!conditionStr) return;

            let condition;
            try {
                condition = JSON.parse(conditionStr);
            } catch (e) {
                return;
            }

            const visible = evaluateCondition(condition, data);
            fieldWrapper.style.display = visible ? '' : 'none';
        });
    }

    // ── Form data collection ──────────────────────────────────────────

    function getFormData(form) {
        const data = {};
        const formData = new FormData(form);
        for (let [key, value] of formData.entries()) {
            if (key.startsWith('_fr_')) continue; // honeypot
            // Handle radio/checkbox — only include checked values
            const input = form.querySelector('[name="' + key + '"]');
            if (input && input.type === 'checkbox' && !input.checked) continue;
            if (input && input.type === 'radio' && !input.checked) continue;
            data[key] = value;
        }
        return data;
    }

    // ── Multi-step navigation ─────────────────────────────────────────

    function initMultiStep(form) {
        const steps = form.querySelectorAll('.agentforms-step');
        if (steps.length <= 1) return;

        let currentStep = 0;
        const backBtn = form.querySelector('.agentforms-btn-back');
        const nextBtn = form.querySelector('.agentforms-btn-next');
        const submitBtn = form.querySelector('.agentforms-btn-submit');
        const progressBar = form.querySelector('.agentforms-progress-fill');
        const stepDots = form.querySelectorAll('.agentforms-step-dot');
        const stepTitle = form.querySelector('.agentforms-step-title');

        function goToStep(index) {
            steps.forEach(function (step, i) {
                step.style.display = i === index ? '' : 'none';
            });

            if (stepDots[index]) {
                stepDots.forEach(function (dot, i) {
                    dot.classList.toggle('active', i <= index);
                    if (i < index) dot.classList.add('completed');
                    else dot.classList.remove('completed');
                });
            }

            if (progressBar) {
                progressBar.style.width = ((index + 1) / steps.length * 100) + '%';
            }

            if (stepTitle) {
                stepTitle.textContent = 'Step ' + (index + 1) + ' of ' + steps.length;
            }

            backBtn.style.display = index > 0 ? '' : 'none';
            if (index === steps.length - 1) {
                nextBtn.style.display = 'none';
                submitBtn.style.display = '';
            } else {
                nextBtn.style.display = '';
                submitBtn.style.display = 'none';
            }

            currentStep = index;
        }

        if (nextBtn) {
            nextBtn.addEventListener('click', function () {
                if (currentStep < steps.length - 1) goToStep(currentStep + 1);
            });
        }

        if (backBtn) {
            backBtn.addEventListener('click', function () {
                if (currentStep > 0) goToStep(currentStep - 1);
            });
        }
    }

    // ── Client-side validation ────────────────────────────────────────

    function validateField(fieldEl) {
        const key = fieldEl.closest('.agentforms-field')?.getAttribute('data-af-field');
        if (!key) return null;

        const validationStr = fieldEl.closest('.agentforms-field')?.getAttribute('data-af-validation');
        if (!validationStr) return null;

        let validations;
        try {
            validations = JSON.parse(validationStr);
        } catch (e) {
            return null;
        }

        const value = fieldEl.value || '';

        for (const rule of validations) {
            if (rule === 'required' && !value.trim()) {
                const errorMsg = fieldEl.closest('.agentforms-field')?.getAttribute('data-af-error') || 'This field is required.';
                return errorMsg;
            }

            const parts = rule.split(':');
            const ruleName = parts[0];
            const ruleValue = parts.slice(1).join(':');

            switch (ruleName) {
                case 'minLength':
                    if (value.length < parseInt(ruleValue)) {
                        return fieldEl.closest('.agentforms-field')?.getAttribute('data-af-error') || 'Minimum ' + ruleValue + ' characters required.';
                    }
                    break;
                case 'maxLength':
                    if (value.length > parseInt(ruleValue)) {
                        return fieldEl.closest('.agentforms-field')?.getAttribute('data-af-error') || 'Maximum ' + ruleValue + ' characters allowed.';
                    }
                    break;
                case 'min':
                    if (!isNaN(parseFloat(value)) && parseFloat(value) < parseFloat(ruleValue)) {
                        return fieldEl.closest('.agentforms-field')?.getAttribute('data-af-error') || 'Must be at least ' + ruleValue + '.';
                    }
                    break;
                case 'max':
                    if (!isNaN(parseFloat(value)) && parseFloat(value) > parseFloat(ruleValue)) {
                        return fieldEl.closest('.agentforms-field')?.getAttribute('data-af-error') || 'Must be at most ' + ruleValue + '.';
                    }
                    break;
            }
        }

        return null;
    }

    function showError(fieldEl, message) {
        const wrapper = fieldEl.closest('.agentforms-field');
        if (!wrapper) return;
        const errorEl = wrapper.querySelector('.agentforms-field-error');
        if (errorEl) {
            errorEl.textContent = message;
            errorEl.style.display = '';
        }
        fieldEl.classList.add('af-input-error');
    }

    function clearError(fieldEl) {
        const wrapper = fieldEl.closest('.agentforms-field');
        if (!wrapper) return;
        const errorEl = wrapper.querySelector('.agentforms-field-error');
        if (errorEl) {
            errorEl.textContent = '';
            errorEl.style.display = 'none';
        }
        fieldEl.classList.remove('af-input-error');
    }

    // ── Main submission handler ───────────────────────────────────────

    function initForm(form) {
        const submitUrl = form.getAttribute('data-af-submit-url');
        const successMsg = form.getAttribute('data-af-success') || 'Thank you! Your response has been received.';

        if (!submitUrl) return;

        // Init multi-step if applicable
        initMultiStep(form);

        // Real-time validation on input
        form.querySelectorAll('.agentforms-input, .agentforms-textarea, .agentforms-select').forEach(function (input) {
            input.addEventListener('input', function () {
                clearError(input);
                updateFieldVisibility(form);
            });
            input.addEventListener('change', function () {
                clearError(input);
                updateFieldVisibility(form);
            });
        });

        form.addEventListener('submit', function (e) {
            e.preventDefault();

            // Client-side validation
            const inputs = form.querySelectorAll('.agentforms-input, .agentforms-textarea, .agentforms-select');
            let hasError = false;
            inputs.forEach(function (input) {
                const error = validateField(input);
                if (error) {
                    showError(input, error);
                    hasError = true;
                } else {
                    clearError(input);
                }
            });
            if (hasError) return;

            // Show loading
            const loadingEl = form.querySelector('.agentforms-loading');
            const errorMsgEl = form.querySelector('.agentforms-error-msg');
            const successEl = form.querySelector('.agentforms-success');
            const submitRow = form.querySelector('.agentforms-submit-row, .agentforms-step-actions');

            if (loadingEl) loadingEl.style.display = '';
            if (errorMsgEl) errorMsgEl.style.display = 'none';
            if (successEl) successEl.style.display = 'none';
            if (submitRow) submitRow.style.display = 'none';

            // Collect data
            const data = getFormData(form);

            // Submit via fetch
            fetch(submitUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                },
                body: JSON.stringify(data),
            })
                .then(function (response) {
                    return response.json().then(function (body) {
                        return { status: response.status, body: body };
                    });
                })
                .then(function (result) {
                    if (result.status >= 200 && result.status < 300 && result.body.success) {
                        // Success
                        if (successEl) {
                            var msgEl = successEl.querySelector('.agentforms-success-message');
                            if (msgEl) msgEl.textContent = successMsg;
                            successEl.style.display = '';
                        }
                    } else {
                        // Error
                        var errorText = result.body && result.body.error ? result.body.error : 'Submission failed. Please try again.';
                        if (errorMsgEl) {
                            var errorTextEl = errorMsgEl.querySelector('.agentforms-error-text');
                            if (errorTextEl) errorTextEl.textContent = errorText;
                            errorMsgEl.style.display = '';
                        }
                        if (submitRow) submitRow.style.display = '';
                    }
                })
                .catch(function (err) {
                    var errorText = 'Network error. Please check your connection and try again.';
                    if (errorMsgEl) {
                        var errorTextEl = errorMsgEl.querySelector('.agentforms-error-text');
                        if (errorTextEl) errorTextEl.textContent = errorText;
                        errorMsgEl.style.display = '';
                    }
                    if (submitRow) submitRow.style.display = '';
                })
                .finally(function () {
                    if (loadingEl) loadingEl.style.display = 'none';
                });
        });

        // Initial visibility check
        updateFieldVisibility(form);
    }

    // ── Init on DOM ready ─────────────────────────────────────────────

    document.addEventListener('DOMContentLoaded', function () {
        document.querySelectorAll('.agentforms-form').forEach(initForm);
    });

    // Expose for programmatic use (e.g., after AJAX content loads)
    window.AgentForms = {
        initForm: initForm,
        init: function () {
            document.querySelectorAll('.agentforms-form').forEach(initForm);
        },
    };

})();