/* Daniel — back-office : glisser-déposer, bascule de statut AJAX, modale de suppression. */
(function () {
    function token() {
        var m = document.querySelector('meta[name="csrf-token"]');
        return m ? m.getAttribute('content') : '';
    }

    function showToast(msg, ok) {
        ok = ok !== false;
        var container = document.querySelector('.toast-container');
        if (!container) {
            container = document.createElement('div');
            container.className = 'toast-container position-fixed bottom-0 end-0 p-3';
            container.style.zIndex = '1090';
            document.body.appendChild(container);
        }
        var el = document.createElement('div');
        el.className = 'toast align-items-center text-white border-0 ' + (ok ? 'bg-success' : 'bg-danger');
        el.setAttribute('role', 'alert');
        el.innerHTML = '<div class="d-flex"><div class="toast-body"><i class="ti ' + (ok ? 'ti-circle-check' : 'ti-alert-triangle') + ' me-1"></i>' + msg + '</div>'
            + '<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Fermer"></button></div>';
        container.appendChild(el);
        if (window.bootstrap) {
            var t = new bootstrap.Toast(el, { autohide: true, delay: 3000 });
            t.show();
            el.addEventListener('hidden.bs.toast', function () { el.remove(); });
        }
    }

    document.addEventListener('DOMContentLoaded', function () {

        // 1) Réordonnancement par glisser-déposer (tableaux ET grilles)
        document.querySelectorAll('[data-sortable]').forEach(function (el) {
            var container = el.tagName === 'TABLE' ? el.querySelector('tbody') : el;
            if (!container || !window.Sortable) {
                return;
            }
            var url = el.getAttribute('data-reorder-url');
            Sortable.create(container, {
                handle: '.sortable-handle',
                animation: 150,
                ghostClass: 'sortable-ghost',
                chosenClass: 'sortable-chosen',
                onEnd: function () {
                    var body = '_csrf=' + encodeURIComponent(token());
                    Array.prototype.forEach.call(container.children, function (item) {
                        if (item.hasAttribute && item.hasAttribute('data-id')) {
                            body += '&order%5B%5D=' + encodeURIComponent(item.getAttribute('data-id'));
                        }
                    });
                    fetch(url, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                        body: body,
                        credentials: 'same-origin'
                    }).then(function (r) { if (r && r.ok) { showToast('Ordre enregistré.'); } });
                }
            });
        });

        // 2) Bascule de statut (AJAX)
        document.addEventListener('change', function (e) {
            var el = e.target;
            if (!el.classList || !el.classList.contains('toggle-status')) {
                return;
            }
            var url   = el.getAttribute('data-url');
            var value = el.checked ? 1 : 0;
            el.disabled = true;
            fetch(url, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: '_csrf=' + encodeURIComponent(token()) + '&value=' + value,
                credentials: 'same-origin'
            })
            .then(function (r) { return r.json(); })
            .then(function (d) {
                el.disabled = false;
                if (!d || !d.success) { el.checked = !el.checked; }
                else { showToast('Statut mis à jour.'); }
            })
            .catch(function () { el.disabled = false; el.checked = !el.checked; });
        });

        // 3) Modale de suppression : renseigne l'action du formulaire et le libellé
        var deleteModal = document.getElementById('deleteModal');
        if (deleteModal) {
            deleteModal.addEventListener('show.bs.modal', function (ev) {
                var btn = ev.relatedTarget;
                if (!btn) {
                    return;
                }
                var form  = document.getElementById('deleteForm');
                var label = document.getElementById('deleteItemLabel');
                if (form)  { form.setAttribute('action', btn.getAttribute('data-delete-url') || ''); }
                if (label) { label.textContent = btn.getAttribute('data-delete-label') || ''; }
            });
        }

        // 4) Toast de notification (flash) — disparaît au bout de 4 s
        var flashToast = document.getElementById('flashToast');
        if (flashToast && window.bootstrap) {
            new bootstrap.Toast(flashToast, { autohide: true, delay: 4000 }).show();
        }

        // 5) Page images : ajout multiple (drag-drop), remplacement (drop/clic), édition, progression
        var imageGrid = document.querySelector('.image-grid[data-sortable]');
        if (imageGrid) {
            var MAX_BYTES = 31457280; // 30 Mo
            var pageDirty = false, submitting = false;

            // a) Édition (nom / alt) : bouton Enregistrer grisé -> bleu (délégation : inclut les cartes ajoutées)
            function autogrow(ta) { ta.style.height = 'auto'; ta.style.height = ta.scrollHeight + 'px'; }
            imageGrid.addEventListener('input', function (e) {
                if (e.target.classList && e.target.classList.contains('image-autogrow')) { autogrow(e.target); }
                var form = e.target.closest ? e.target.closest('form.image-edit') : null;
                if (!form) { return; }
                var btn = form.querySelector('.image-save');
                if (btn) { btn.disabled = false; }
                pageDirty = true;
            });
            // a-bis) Ouvrir / fermer l'éditeur inline d'une carte
            imageGrid.addEventListener('click', function (e) {
                var toggle = e.target.closest ? e.target.closest('.image-edit-toggle') : null;
                if (toggle) {
                    e.preventDefault();
                    var card = toggle.closest('.image-card');
                    if (!card) { return; }
                    var opening = !card.classList.contains('editing');
                    card.classList.toggle('editing');
                    if (opening) {
                        card.querySelectorAll('.image-autogrow').forEach(autogrow);
                        var first = card.querySelector('textarea[name="name"]');
                        if (first) { first.focus(); }
                    }
                    return;
                }
                var cancel = e.target.closest ? e.target.closest('.image-edit-cancel') : null;
                if (cancel) {
                    e.preventDefault();
                    var c = cancel.closest('.image-card');
                    if (c) { c.classList.remove('editing'); }
                }
            });
            document.addEventListener('submit', function () { submitting = true; });
            window.addEventListener('beforeunload', function (e) {
                if (pageDirty && !submitting) { e.preventDefault(); e.returnValue = ''; }
            });

            // b) Overlay de progression + modale des échecs
            var overlay = document.getElementById('uploadOverlay');
            var bar = document.getElementById('uploadBar');
            var txt = document.getElementById('uploadText');
            function setProgress(done, total, frac, label) {
                var pct = Math.round(((done + frac) / total) * 100);
                if (bar) { bar.style.width = pct + '%'; bar.textContent = pct + '%'; }
                if (txt) { txt.textContent = 'Image ' + Math.min(done + 1, total) + ' / ' + total + ' — ' + label; }
            }
            function showOverlay() { if (overlay) { overlay.classList.add('show'); } }
            function hideOverlay() { if (overlay) { overlay.classList.remove('show'); } if (bar) { bar.style.width = '0%'; bar.textContent = '0%'; } }
            function showFailures(failures) {
                var list = document.getElementById('uploadErrorList');
                if (list) {
                    list.innerHTML = '';
                    failures.forEach(function (f) {
                        var li = document.createElement('li');
                        li.className = 'mb-2';
                        var strong = document.createElement('strong');
                        strong.textContent = f.label;
                        var span = document.createElement('span');
                        span.className = 'text-secondary';
                        span.textContent = ' — ' + f.reason;
                        li.innerHTML = '<i class="ti ti-file-x text-danger me-1"></i>';
                        li.appendChild(strong);
                        li.appendChild(span);
                        list.appendChild(li);
                    });
                }
                var modalEl = document.getElementById('uploadErrorModal');
                if (modalEl && window.bootstrap) { bootstrap.Modal.getOrCreateInstance(modalEl).show(); }
            }

            // c) Exécution séquentielle des jobs (1 fichier = 1 requête : 10×28 Mo sans souci de POST géant)
            function runJobs(jobs, preFailures) {
                var failures = (preFailures || []).slice();
                if (!jobs.length) { if (failures.length) { showFailures(failures); } return; }
                showOverlay();
                var i = 0;
                (function next() {
                    if (i >= jobs.length) {
                        hideOverlay();
                        if (failures.length) { showFailures(failures); }
                        return;
                    }
                    var job = jobs[i];
                    setProgress(i, jobs.length, 0, job.label);
                    var xhr = new XMLHttpRequest();
                    xhr.open('POST', job.url, true);
                    xhr.upload.onprogress = function (e) {
                        if (e.lengthComputable) { setProgress(i, jobs.length, e.loaded / e.total, job.label); }
                    };
                    xhr.onload = function () {
                        var d = null;
                        try { d = JSON.parse(xhr.responseText); } catch (err) { d = null; }
                        if (d && d.success) {
                            try { job.onSuccess(d); } catch (err) {}
                        } else {
                            failures.push({ label: job.label, reason: (d && d.error) ? d.error : ('Erreur serveur (' + xhr.status + ').') });
                        }
                        i++; next();
                    };
                    xhr.onerror = function () { failures.push({ label: job.label, reason: 'Échec réseau.' }); i++; next(); };
                    var fd = new FormData();
                    fd.append('_csrf', token());
                    fd.append('file', job.file);
                    xhr.send(fd);
                })();
            }

            function localReject(file) {
                if (['image/jpeg', 'image/png'].indexOf(file.type) === -1) { return 'Type non supporté (JPEG ou PNG).'; }
                if (file.size > MAX_BYTES) { return 'Fichier trop volumineux (max 30 Mo).'; }
                return null;
            }
            function hasFiles(e) {
                return e.dataTransfer && Array.prototype.indexOf.call(e.dataTransfer.types || [], 'Files') !== -1;
            }

            // d) Ajout d'images : drop multiple + clic
            var addZone = document.getElementById('addDropzone');
            if (addZone) {
                var addUrl = addZone.getAttribute('data-upload-url');
                var addInput = addZone.querySelector('input[type="file"]');
                var emptyBox = document.getElementById('emptyImages');
                var reorderHint = document.getElementById('reorderHint');
                var appendCard = function (html) {
                    var tmp = document.createElement('div');
                    tmp.innerHTML = (html || '').trim();
                    var card = tmp.firstElementChild;
                    if (card) {
                        imageGrid.appendChild(card);
                        if (emptyBox) { emptyBox.classList.add('d-none'); }
                        if (reorderHint) { reorderHint.style.display = ''; }
                    }
                };
                var addFiles = function (fileList) {
                    var jobs = [], rejected = [];
                    Array.prototype.forEach.call(fileList, function (file) {
                        var bad = localReject(file);
                        if (bad) { rejected.push({ label: file.name, reason: bad }); }
                        else { jobs.push({ file: file, url: addUrl, label: file.name, onSuccess: function (d) { appendCard(d.html); } }); }
                    });
                    runJobs(jobs, rejected);
                };
                addInput.addEventListener('change', function () { addFiles(addInput.files); addInput.value = ''; });
                addZone.addEventListener('click', function (e) { if (e.target === addInput) { return; } addInput.click(); });
                addZone.addEventListener('dragover', function (e) { if (hasFiles(e)) { e.preventDefault(); addZone.classList.add('dragover'); } });
                addZone.addEventListener('dragleave', function () { addZone.classList.remove('dragover'); });
                addZone.addEventListener('drop', function (e) {
                    if (!hasFiles(e)) { return; }
                    e.preventDefault(); addZone.classList.remove('dragover');
                    addFiles(e.dataTransfer.files);
                });
            }

            // e) Remplacement : clic sur la vignette (ouvre le sélecteur) ou drop d'un fichier
            var replaceCard = function (card, file) {
                var bad = localReject(file);
                if (bad) { showFailures([{ label: file.name, reason: bad }]); return; }
                runJobs([{
                    file: file, url: card.getAttribute('data-replace-url'), label: file.name,
                    onSuccess: function (d) {
                        var img = card.querySelector('.image-thumb img');
                        if (img) { img.src = (d.thumb || img.src.split('?')[0]) + '?v=' + Date.now(); }
                        showToast('Image remplacée.');
                    }
                }]);
            };
            imageGrid.addEventListener('click', function (e) {
                if (e.target.classList && e.target.classList.contains('replace-input')) { return; }
                var thumb = e.target.closest ? e.target.closest('.image-drop') : null;
                if (!thumb || (e.target.closest && e.target.closest('.sortable-handle'))) { return; }
                var input = thumb.querySelector('.replace-input');
                if (input) { input.click(); }
            });
            imageGrid.addEventListener('change', function (e) {
                if (!e.target.classList || !e.target.classList.contains('replace-input')) { return; }
                var card = e.target.closest('[data-id]');
                if (card && e.target.files.length) { replaceCard(card, e.target.files[0]); }
                e.target.value = '';
            });
            imageGrid.addEventListener('dragover', function (e) {
                var thumb = e.target.closest ? e.target.closest('.image-drop') : null;
                if (thumb && hasFiles(e)) { e.preventDefault(); thumb.classList.add('dragover'); }
            });
            imageGrid.addEventListener('dragleave', function (e) {
                var thumb = e.target.closest ? e.target.closest('.image-drop') : null;
                if (thumb) { thumb.classList.remove('dragover'); }
            });
            imageGrid.addEventListener('drop', function (e) {
                var thumb = e.target.closest ? e.target.closest('.image-drop') : null;
                if (!thumb || !hasFiles(e)) { return; }
                e.preventDefault(); thumb.classList.remove('dragover');
                var card = thumb.closest('[data-id]');
                if (card && e.dataTransfer.files.length) { replaceCard(card, e.dataTransfer.files[0]); }
            });

            // f) Empêche le navigateur d'ouvrir un fichier déposé hors zone
            ['dragover', 'drop'].forEach(function (ev) {
                window.addEventListener(ev, function (e) {
                    if (hasFiles(e) && !(e.target.closest && e.target.closest('.image-drop, #addDropzone'))) { e.preventDefault(); }
                });
            });
        }

        // 6) Paramètres : synchronise chaque champ hexa avec sa pastille de couleur
        document.querySelectorAll('.color-hex').forEach(function (hex) {
            var picker = document.getElementById(hex.getAttribute('data-for'));
            if (!picker) { return; }
            // Pastille -> hexa
            picker.addEventListener('input', function () { hex.value = picker.value; });
            // Hexa -> pastille (dès que la saisie forme un hex valide à 6 chiffres)
            hex.addEventListener('input', function () {
                var v = hex.value.trim().replace(/^#?/, '#');
                if (/^#[0-9a-fA-F]{6}$/.test(v)) { picker.value = v.toLowerCase(); }
            });
            // À la sortie du champ : renormalise sur la valeur réelle de la pastille
            hex.addEventListener('blur', function () { hex.value = picker.value; });
        });

        // 7) Affichage conditionnel : [data-show-if="champ"] visible seulement si la case "champ" est cochée.
        // L'imbrication gère les dépendances en cascade (un enfant masqué avec son parent).
        var conditional = document.querySelectorAll('[data-show-if]');
        if (conditional.length) {
            var refreshConditional = function () {
                conditional.forEach(function (el) {
                    var ctrl = document.querySelector('input[name="' + el.getAttribute('data-show-if') + '"]');
                    el.style.display = (ctrl && ctrl.checked) ? '' : 'none';
                });
            };
            document.addEventListener('change', function (e) {
                if (e.target && e.target.matches && e.target.matches('input[type="checkbox"]')) { refreshConditional(); }
            });
            refreshConditional();
        }

        // 8) reCAPTCHA : impossible d'activer sans renseigner les deux clés.
        var rcToggle = document.querySelector('input[name="contact_recaptcha_enabled"]');
        if (rcToggle && rcToggle.form) {
            var rcKeys = [
                document.querySelector('input[name="recaptcha_site_key"]'),
                document.querySelector('input[name="recaptcha_secret_key"]')
            ];
            rcKeys.forEach(function (input) {
                if (input) { input.addEventListener('input', function () { input.classList.remove('is-invalid'); }); }
            });
            rcToggle.form.addEventListener('submit', function (e) {
                if (!rcToggle.checked) { return; }
                var missing = rcKeys.filter(function (input) { return input && input.value.trim() === ''; });
                if (missing.length) {
                    e.preventDefault();
                    missing.forEach(function (input) { input.classList.add('is-invalid'); });
                    showToast('Renseignez la clé du site et la clé secrète pour activer reCAPTCHA.', false);
                    missing[0].focus();
                }
            });
        }

        // 9) Bouton « Envoyer un email de test » (SMTP)
        var testBtn = document.getElementById('testEmailBtn');
        if (testBtn) {
            testBtn.addEventListener('click', function () {
                var original = testBtn.innerHTML;
                testBtn.disabled = true;
                testBtn.innerHTML = '<i class="ti ti-loader me-1"></i>Envoi…';
                fetch(testBtn.getAttribute('data-url'), {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: '_csrf=' + encodeURIComponent(token()),
                    credentials: 'same-origin'
                })
                .then(function (r) { return r.json(); })
                .then(function (d) { showToast((d && d.message) ? d.message : 'Réponse inattendue.', !!(d && d.success)); })
                .catch(function () { showToast('Erreur réseau lors de l\'envoi.', false); })
                .then(function () { testBtn.disabled = false; testBtn.innerHTML = original; });
            });
        }
    });
})();
