document.addEventListener('DOMContentLoaded', () => {
    initConditionalFields();
    initDependents();
    initMasks();
    initDataTable();
    initFilePreviews();
    initUpdateModal();
    initFormWizard();
    initUploadGuard();
    scrollToFirstError();
});



function initFormWizard() {
    const form = document.querySelector('form[data-mobile-wizard="true"]');
    if (!form) return;

    const sections = Array.from(form.querySelectorAll('.form-section'));
    if (sections.length < 2) return;

    const finalActions = form.querySelector('.wizard-final-actions');
    const mobileQuery = window.matchMedia('(max-width: 991.98px)');
    let wizard = null;
    let currentStep = 0;

    const getSectionTitle = (section, index) => {
        const heading = section.querySelector('.section-header h2');
        if (!heading) return `Etapa ${index + 1}`;
        return heading.textContent.replace(/^\s*\d+[\.-]?\s*/, '').trim();
    };

    const sectionHasError = (section) => Boolean(section.querySelector('.is-invalid, .field-error'));

    const getInitialStep = () => {
        const invalidIndex = sections.findIndex(sectionHasError);
        return invalidIndex >= 0 ? invalidIndex : 0;
    };

    const focusActiveStep = () => {
        const activeSection = sections[currentStep];
        if (!activeSection) return;

        window.requestAnimationFrame(() => {
            activeSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
        });
    };

    const updateWizardUi = (shouldScroll = false) => {
        if (!wizard) return;

        sections.forEach((section, index) => {
            section.classList.add('wizard-step');
            section.classList.toggle('is-active', index === currentStep);
            if (index === currentStep) {
                section.removeAttribute('aria-hidden');
            } else {
                section.setAttribute('aria-hidden', 'true');
            }
        });

        const title = getSectionTitle(sections[currentStep], currentStep);
        const progress = ((currentStep + 1) / sections.length) * 100;
        const isLastStep = currentStep === sections.length - 1;

        wizard.stepCounter.textContent = `Etapa ${currentStep + 1} de ${sections.length}`;
        wizard.stepTitle.textContent = title;
        wizard.progressFill.style.width = `${progress}%`;
        wizard.prevButton.disabled = currentStep === 0;
        wizard.nav.hidden = isLastStep;

        if (finalActions) {
            finalActions.hidden = !isLastStep;
            finalActions.classList.toggle('is-active', isLastStep);
        }

        if (shouldScroll) {
            focusActiveStep();
        }
    };

    const setStep = (index, shouldScroll = true) => {
        currentStep = Math.max(0, Math.min(index, sections.length - 1));
        updateWizardUi(shouldScroll);
    };

    const enableWizard = () => {
        if (wizard) {
            updateWizardUi(false);
            return;
        }

        form.classList.add('mobile-wizard-enabled');

        const header = document.createElement('div');
        header.className = 'mobile-wizard-header';
        header.innerHTML = `
            <div class="mobile-wizard-header__meta">
                <span class="mobile-wizard-counter"></span>
                <strong class="mobile-wizard-title"></strong>
            </div>
            <div class="mobile-wizard-progress" aria-hidden="true">
                <span class="mobile-wizard-progress__fill"></span>
            </div>
        `;

        const nav = document.createElement('div');
        nav.className = 'mobile-wizard-nav';
        nav.innerHTML = `
            <button type="button" class="btn btn-outline-secondary mobile-wizard-prev">Voltar</button>
            <button type="button" class="btn btn-primary mobile-wizard-next">Próxima etapa</button>
        `;

        form.insertBefore(header, sections[0]);
        if (finalActions && finalActions.parentNode === form) {
            form.insertBefore(nav, finalActions);
        } else {
            form.appendChild(nav);
        }

        wizard = {
            header,
            nav,
            stepCounter: header.querySelector('.mobile-wizard-counter'),
            stepTitle: header.querySelector('.mobile-wizard-title'),
            progressFill: header.querySelector('.mobile-wizard-progress__fill'),
            prevButton: nav.querySelector('.mobile-wizard-prev'),
            nextButton: nav.querySelector('.mobile-wizard-next')
        };

        wizard.prevButton.addEventListener('click', () => setStep(currentStep - 1));
        wizard.nextButton.addEventListener('click', () => setStep(currentStep + 1));

        currentStep = getInitialStep();
        updateWizardUi(false);
    };

    const disableWizard = () => {
        form.classList.remove('mobile-wizard-enabled');
        sections.forEach((section) => {
            section.classList.remove('wizard-step', 'is-active');
            section.removeAttribute('aria-hidden');
        });

        if (finalActions) {
            finalActions.hidden = false;
            finalActions.classList.remove('is-active');
        }

        if (wizard) {
            wizard.header.remove();
            wizard.nav.remove();
            wizard = null;
        }
    };

    const syncWizardMode = () => {
        if (mobileQuery.matches) {
            enableWizard();
        } else {
            disableWizard();
        }
    };

    syncWizardMode();

    if (typeof mobileQuery.addEventListener === 'function') {
        mobileQuery.addEventListener('change', syncWizardMode);
    } else if (typeof mobileQuery.addListener === 'function') {
        mobileQuery.addListener(syncWizardMode);
    }
}


function initUploadGuard() {
    const form = document.querySelector('form[data-upload-guard="true"]');
    if (!form) return;

    const maxFileSizeMb = parseFloat(form.dataset.maxFileSizeMb || '5');
    const maxFileSizeBytes = Number.isFinite(maxFileSizeMb) ? maxFileSizeMb * 1024 * 1024 : 5 * 1024 * 1024;
    const postMaxBytes = parseInt(form.dataset.postMaxBytes || '0', 10);

    const renderError = (message) => {
        let alert = form.querySelector('.js-upload-error');
        if (!alert) {
            alert = document.createElement('div');
            alert.className = 'alert alert-danger shadow-sm form-alert js-upload-error';
            form.insertBefore(alert, form.firstChild);
        }

        alert.innerHTML = `
            <strong>${escapeHtml(message)}</strong>
            <div class="small mt-2">Dica: no celular, envie imagens em JPG ou PDF e evite fotos gigantes direto da câmera.</div>
        `;

        window.requestAnimationFrame(() => {
            alert.scrollIntoView({ behavior: 'smooth', block: 'start' });
        });
    };

    form.addEventListener('submit', (event) => {
        const previousError = form.querySelector('.js-upload-error');
        if (previousError) previousError.remove();

        const fileInputs = Array.from(form.querySelectorAll('input[type="file"]'));
        let totalSize = 0;
        let oversizedFile = null;

        fileInputs.forEach((input) => {
            Array.from(input.files || []).forEach((file) => {
                totalSize += file.size || 0;
                if (!oversizedFile && (file.size || 0) > maxFileSizeBytes) {
                    oversizedFile = file;
                }
            });
        });

        if (oversizedFile) {
            event.preventDefault();
            renderError(`O arquivo "${oversizedFile.name}" excede ${maxFileSizeMb} MB. Reduza o tamanho e tente novamente.`);
            return;
        }

        if (postMaxBytes > 0 && totalSize > postMaxBytes) {
            event.preventDefault();
            renderError('A soma dos anexos passou do limite aceito pelo servidor. Reduza o tamanho das imagens ou envie PDFs menores.');
        }
    });
}

function initUpdateModal() {
    const modalElement = document.getElementById('updateNoteModal');
    if (!modalElement || typeof window.bootstrap === 'undefined') return;

    const version = modalElement.dataset.updateVersion || '0';
    const storageKey = `update-note-dismissed-${version}`;
    const modal = new window.bootstrap.Modal(modalElement);
    const dismissButton = modalElement.querySelector('[data-update-dismiss]');

    const markDismissed = () => {
        try {
            localStorage.setItem(storageKey, '1');
        } catch (e) {
            // ignore storage issues
        }
        modal.hide();
    };

    if (dismissButton) {
        dismissButton.addEventListener('click', markDismissed);
    }

    modalElement.addEventListener('hidden.bs.modal', () => {
        try {
            localStorage.setItem(storageKey, '1');
        } catch (e) {
            // ignore storage issues
        }
    });

    let dismissed = false;
    try {
        dismissed = localStorage.getItem(storageKey) === '1';
    } catch (e) {
        dismissed = false;
    }

    if (!dismissed) {
        modal.show();
    }
}

function initConditionalFields() {
    document.querySelectorAll('.toggle-field').forEach((field) => {
        const updateState = () => {
            const target = document.querySelector(field.dataset.target);
            if (!target) return;
            target.classList.toggle('is-hidden', String(field.value) !== '1');
        };

        field.addEventListener('change', updateState);
        updateState();
    });

    const jobTitle = document.getElementById('job_title');
    const studentField = document.querySelector('[name="is_student"]');
    const maritalStatusField = document.getElementById('marital_status');
    const dependentsField = document.getElementById('has_dependents');
    const academicSection = document.getElementById('academic-section');
    const crefSection = document.getElementById('cref-section');
    const crefDocumentSection = document.getElementById('cref-document-section');
    const meiCertificateSection = document.getElementById('mei-certificate-section');
    const marriageCertificateSection = document.getElementById('marriage-certificate-section');
    const divorceAnnotationSection = document.getElementById('divorce-annotation-section');

    const normalize = (value) => {
        return String(value || '')
            .normalize('NFD')
            .replace(/[̀-ͯ]/g, '')
            .trim()
            .toLowerCase();
    };

    const syncJobSections = () => {
        const selectedJob = normalize(jobTitle ? jobTitle.value : '');
        const isStudent = studentField ? String(studentField.value || '0') === '1' : false;
        const isInternEdu = selectedJob === normalize('Estagiário Ed. Física');
        const isProfessorEdu =
            selectedJob === normalize('Professor de Musculação') ||
            selectedJob === normalize('Professor de natação') ||
            selectedJob.includes('professor');

        if (academicSection) {
            academicSection.classList.toggle('is-hidden', !(isStudent || isInternEdu));
        }

        if (crefSection) {
            crefSection.classList.toggle('is-hidden', !isProfessorEdu);
        }

        if (crefDocumentSection) {
            crefDocumentSection.classList.toggle('is-hidden', !isProfessorEdu);
        }

        if (meiCertificateSection) {
            meiCertificateSection.classList.toggle('is-hidden', !isProfessorEdu);
        }

        const maritalStatus = String(maritalStatusField ? maritalStatusField.value : '').trim().toLowerCase();
        const hasDependents = String(dependentsField ? dependentsField.value : '0') === '1';

        if (marriageCertificateSection) {
            marriageCertificateSection.classList.toggle('is-hidden', maritalStatus !== 'casado');
        }

        if (divorceAnnotationSection) {
            divorceAnnotationSection.classList.toggle('is-hidden', maritalStatus !== 'divorciado');
        }

    };

    if (jobTitle) {
        jobTitle.addEventListener('change', syncJobSections);
        jobTitle.addEventListener('input', syncJobSections);
    }

    if (studentField) {
        studentField.addEventListener('change', syncJobSections);
    }

    if (maritalStatusField) {
        maritalStatusField.addEventListener('change', syncJobSections);
    }

    if (dependentsField) {
        dependentsField.addEventListener('change', syncJobSections);
    }

    const bankPaymentMethodField = document.getElementById('bank_payment_method');
    const bankDetailsSection = document.getElementById('bank-details-section');
    const pixSection = document.getElementById('pix-section');

    const syncPaymentMethod = () => {
        const method = String(bankPaymentMethodField ? bankPaymentMethodField.value : 'bank');

        if (bankDetailsSection) {
            bankDetailsSection.classList.toggle('is-hidden', method !== 'bank');
        }

        if (pixSection) {
            pixSection.classList.toggle('is-hidden', method !== 'pix');
        }
    };

    if (bankPaymentMethodField) {
        bankPaymentMethodField.addEventListener('change', syncPaymentMethod);
        syncPaymentMethod();
    }

    syncJobSections();
}

function initDependents() {
    const wrapper = document.getElementById('dependents-wrapper');
    const addButton = document.getElementById('add-dependent');

    if (!wrapper || !addButton) return;

    const reindex = () => {
        [...wrapper.querySelectorAll('.dependent-card')].forEach((card, index) => {
            const title = card.querySelector('h3');
            if (title) title.textContent = `Dependente ${index + 1}`;

            card.querySelectorAll('input, select').forEach((input) => {
                const name = input.getAttribute('name');
                if (!name) return;

                let updatedName = name.replace(/dependents\[\d+\]/, `dependents[${index}]`);
                updatedName = updatedName.replace(/dependent_birth_certificates\[\d+\]/, `dependent_birth_certificates[${index}]`);
                input.setAttribute('name', updatedName);
            });
        });
    };

    addButton.addEventListener('click', () => {
        const newIndex = wrapper.querySelectorAll('.dependent-card').length;
        const card = document.createElement('div');

        card.className = 'dependent-card border rounded-4 p-3';
        card.innerHTML = `
            <div class="d-flex justify-content-between align-items-center mb-3">
                <h3 class="h6 mb-0">Dependente ${newIndex + 1}</h3>
                <button type="button" class="btn btn-sm btn-outline-danger remove-dependent">Remover</button>
            </div>
            <div class="row g-3">
                <div class="col-md-4">
                    <label class="form-label">Nome completo</label>
                    <input type="text" class="form-control" name="dependents[${newIndex}][full_name]">
                </div>
                <div class="col-md-3">
                    <label class="form-label">Data de nascimento</label>
                    <input type="date" class="form-control" name="dependents[${newIndex}][birth_date]">
                </div>
                <div class="col-md-3">
                    <label class="form-label">CPF</label>
                    <input type="text" class="form-control js-cpf" name="dependents[${newIndex}][cpf]">
                </div>
                <div class="col-md-2">
                    <label class="form-label">Deficiência?</label>
                    <select class="form-select" name="dependents[${newIndex}][has_disability]">
                        <option value="0">Não</option>
                        <option value="1">Sim</option>
                    </select>
                </div>
                <div class="col-md-6">
                    <label class="form-label">Local/cidade de nascimento</label>
                    <input type="text" class="form-control" name="dependents[${newIndex}][birth_city]">
                </div>
                <div class="col-md-6">
                    <label class="form-label">Certidão de nascimento do dependente ${newIndex + 1}</label>
                    <input type="file" class="form-control" name="dependent_birth_certificates[${newIndex}]" accept=".jpg,.jpeg,.png,.pdf">
                    <div class="form-text">Envie a certidão deste dependente.</div>
                </div>
            </div>
        `;

        wrapper.appendChild(card);
        initMasks();
        reindex();
    });

    wrapper.addEventListener('click', (event) => {
        const button = event.target.closest('.remove-dependent');
        if (!button) return;

        const card = button.closest('.dependent-card');
        if (card && wrapper.querySelectorAll('.dependent-card').length > 1) {
            card.remove();
            reindex();
        }
    });
}

function initMasks() {
    applyMask('.js-cpf', cpfMask, 'numeric');
    applyMask('.js-phone', phoneMask, 'tel');
    applyMask('.js-cep', cepMask, 'numeric');
    applyMask('.js-cnpj', cnpjMask, 'numeric');
    applyMoneyBehavior('.js-money');
}

function applyMask(selector, formatter, inputMode = null) {
    document.querySelectorAll(selector).forEach((input) => {
        input.removeEventListener('input', input._maskHandler || (() => { }));

        if (inputMode) {
            input.setAttribute('inputmode', inputMode);
        }

        const handler = () => {
            input.value = formatter(input.value);
        };

        input._maskHandler = handler;
        input.addEventListener('input', handler);
    });
}

function applyMoneyBehavior(selector) {
    document.querySelectorAll(selector).forEach((input) => {
        input.removeEventListener('input', input._moneyInputHandler || (() => { }));
        input.removeEventListener('blur', input._moneyBlurHandler || (() => { }));

        input.setAttribute('inputmode', 'decimal');
        if (!input.getAttribute('placeholder')) {
            input.setAttribute('placeholder', 'Ex.: 1500,00');
        }

        const inputHandler = () => {
            input.value = moneyTypingMask(input.value);
        };

        const blurHandler = () => {
            input.value = formatMoneyValue(input.value);
        };

        input._moneyInputHandler = inputHandler;
        input._moneyBlurHandler = blurHandler;

        input.addEventListener('input', inputHandler);
        input.addEventListener('blur', blurHandler);
    });
}

function initFilePreviews() {
    document.querySelectorAll('.js-file-preview').forEach((input) => {
        const wrapper = document.querySelector(input.dataset.previewTarget);
        const image = document.querySelector(input.dataset.previewImage);
        const meta = document.querySelector(input.dataset.previewMeta);

        if (!wrapper || !image || !meta) return;

        input.addEventListener('change', () => {
            const file = input.files && input.files[0] ? input.files[0] : null;
            const media = wrapper.querySelector('.upload-preview__media');

            if (!file) {
                wrapper.classList.add('is-empty');
                if (media) media.classList.add('d-none');
                image.removeAttribute('src');
                meta.innerHTML = `
                    <div class="upload-preview__filename">Nenhum arquivo selecionado</div>
                    <div class="upload-preview__hint">A miniatura aparece aqui quando você escolher uma imagem.</div>
                `;
                return;
            }

            wrapper.classList.remove('is-empty');

            if (file.type.startsWith('image/')) {
                const objectUrl = URL.createObjectURL(file);

                image.src = objectUrl;
                if (media) media.classList.remove('d-none');

                meta.innerHTML = `
                    <div class="upload-preview__filename">${escapeHtml(file.name)}</div>
                    <div class="upload-preview__hint">Pré-visualização da imagem selecionada</div>
                `;

                image.onload = () => URL.revokeObjectURL(objectUrl);
                return;
            }

            if (media) media.classList.add('d-none');
            image.removeAttribute('src');

            meta.innerHTML = `
                <div class="upload-preview__filename">${escapeHtml(file.name)}</div>
                <div class="upload-preview__hint">Arquivo selecionado. Prévia visual disponível apenas para imagens.</div>
            `;
        });
    });
}

function onlyDigits(v) {
    return v.replace(/\D/g, '');
}

function cpfMask(v) {
    v = onlyDigits(v).slice(0, 11);
    v = v.replace(/(\d{3})(\d)/, '$1.$2');
    v = v.replace(/(\d{3})(\d)/, '$1.$2');
    return v.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
}

function phoneMask(v) {
    v = onlyDigits(v).slice(0, 11);

    if (v.length <= 10) {
        v = v.replace(/(\d{2})(\d)/, '($1) $2');
        return v.replace(/(\d{4})(\d)/, '$1-$2');
    }

    v = v.replace(/(\d{2})(\d)/, '($1) $2');
    return v.replace(/(\d{5})(\d)/, '$1-$2');
}

function cepMask(v) {
    v = onlyDigits(v).slice(0, 8);
    return v.replace(/(\d{5})(\d)/, '$1-$2');
}

function cnpjMask(v) {
    v = onlyDigits(v).slice(0, 14);
    v = v.replace(/^(\d{2})(\d)/, '$1.$2');
    v = v.replace(/^(\d{2})\.(\d{3})(\d)/, '$1.$2.$3');
    v = v.replace(/\.(\d{3})(\d)/, '.$1/$2');
    return v.replace(/(\d{4})(\d)/, '$1-$2');
}

function moneyTypingMask(v) {
    v = String(v || '').replace(/[^\d,\.]/g, '');

    const lastComma = v.lastIndexOf(',');
    const lastDot = v.lastIndexOf('.');
    const separatorIndex = Math.max(lastComma, lastDot);

    if (separatorIndex === -1) {
        return v.replace(/[^\d]/g, '');
    }

    const integerPart = v.slice(0, separatorIndex).replace(/[^\d]/g, '');
    const decimalPart = v.slice(separatorIndex + 1).replace(/[^\d]/g, '').slice(0, 2);

    return `${integerPart},${decimalPart}`;
}

function formatMoneyValue(v) {
    const typedValue = moneyTypingMask(v);
    if (!typedValue) return '';

    const normalized = typedValue.replace(',', '.');
    const number = parseFloat(normalized);
    if (Number.isNaN(number)) return '';

    return number.toFixed(2).replace('.', ',');
}

function initDataTable() {
    const table = document.getElementById('admissions-table');
    if (!table || typeof window.DataTable === 'undefined') return;

    const tbody = table.querySelector('tbody');
    const headerCells = table.querySelectorAll('thead th').length;
    const rows = tbody ? Array.from(tbody.querySelectorAll('tr')) : [];

    if (!rows.length) return;

    const invalidRow = rows.some((row) => row.children.length !== headerCells);
    if (invalidRow) return;

    new DataTable(table, {
        language: {
            search: 'Filtrar resultados:',
            lengthMenu: 'Mostrar _MENU_ registros',
            info: 'Mostrando _START_ a _END_ de _TOTAL_ registros',
            paginate: {
                first: 'Primeira',
                last: 'Última',
                next: 'Próxima',
                previous: 'Anterior'
            },
            zeroRecords: 'Nenhum resultado encontrado',
            infoEmpty: 'Nenhum registro disponível',
            infoFiltered: '(filtrado de _MAX_ registros)'
        },
        order: [[0, 'desc']],
        pageLength: 10
    });
}

function escapeHtml(value) {
    const map = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };

    return String(value).replace(/[&<>"']/g, (m) => map[m]);
}

function scrollToFirstError() {
    const firstInvalid = document.querySelector('.is-invalid, .field-error');
    if (!firstInvalid) return;

    const target = firstInvalid.classList.contains('field-error')
        ? firstInvalid.previousElementSibling || firstInvalid
        : firstInvalid;

    window.requestAnimationFrame(() => {
        target.scrollIntoView({ behavior: 'smooth', block: 'center' });
        if (typeof target.focus === 'function') {
            target.focus({ preventScroll: true });
        }
    });
}
