/* Page copie/import : bargraph live (blocs 'pending') + clic-trou → champ IP actif. ES5/IIFE. */
(function () {
    if (!window.SubnetBargraph || typeof SUBNET === 'undefined') return;
    var mount = document.getElementById('subnet-bargraph');
    if (!mount) return;

    var SBG = window.SubnetBargraph;

    // IP "a.b.c.d" → entier non signé, ou null si invalide
    function ipToInt(ip) {
        var m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(ip);
        if (!m) return null;
        var a = +m[1], b = +m[2], c = +m[3], d = +m[4];
        if (a > 255 || b > 255 || c > 255 || d > 255) return null;
        return (a * 16777216 + b * 65536 + c * 256 + d) >>> 0;
    }

    // Validation optimiste (affichage) : format + dans firstUsable..lastUsable + hors pools + hors réservé.
    // La barrière qui fait foi reste le garde-fou serveur (subnet_copy.php étape 2).
    function ipValidForPreview(ip) {
        var n = ipToInt(ip);
        if (n === null) return false;
        if (n < (SUBNET.firstUsable >>> 0) || n > (SUBNET.lastUsable >>> 0)) return false;
        if (SUBNET.dynStartInt != null && n >= (SUBNET.dynStartInt >>> 0) && n <= (SUBNET.dynEndInt >>> 0)) return false;
        if (SUBNET.shortStartInt != null && n >= (SUBNET.shortStartInt >>> 0) && n <= (SUBNET.shortEndInt >>> 0)) return false;
        if (SUBNET.reservedIps && SBG.parseReserved) {
            var blocks = SBG.parseReserved(SUBNET.reservedIps, SUBNET.networkInt >>> 0);
            for (var i = 0; i < blocks.length; i++) {
                if (n >= (blocks[i].startInt >>> 0) && n <= (blocks[i].endInt >>> 0)) return false;
            }
        }
        return true;
    }

    // Parcourt le tableau, retourne les lignes cochées & créables → rows _pending pour le bargraph.
    function collectPendingRows() {
        var pend = [], seen = {};
        var trs = document.querySelectorAll('.copy-row');
        for (var i = 0; i < trs.length; i++) {
            var tr = trs[i];
            var cb = tr.querySelector('input[type=checkbox][name$="[do]"]');
            if (!cb || cb.disabled || !cb.checked) continue;
            var stEl = tr.querySelector('input[name$="[status]"]');
            var status = stEl ? stEl.value : '';
            if (status === 'skip' || status === 'pool' || status === 'invalid') continue;
            // mac_conflict : ne compte comme "pending" (nouvelle occupation) que si action=update ET l'IP est libre.
            // En 'keep' la résa existante est déjà dans EXISTING_ROWS → ne rien ajouter.
            if (status === 'mac_conflict') {
                var sel = tr.querySelector('select[name$="[mac_action]"]');
                if (!sel || sel.value !== 'update') continue;
            }
            var ipField = tr.querySelector('.ip-field');
            var ip = ipField ? ipField.value.trim()
                             : (function () { var h = tr.querySelector('input[name$="[ip]"]'); return h ? h.value.trim() : ''; })();
            if (!ip || !ipValidForPreview(ip)) continue;
            var n = ipToInt(ip);
            if (seen[n]) continue;
            seen[n] = true;
            pend.push({ ip_int: n, host_id: 0, hostname: '(à créer)', group_name: '', short_lease: 0, _pending: true });
        }
        return pend;
    }

    var activeIpField = null; // cible du prochain clic-trou (capturée au mousedown)

    function attachHoleCapture() {
        var segs = mount.querySelectorAll('.sbg-seg');
        for (var i = 0; i < segs.length; i++) {
            segs[i].addEventListener('mousedown', function () {
                var el = document.activeElement;
                activeIpField = (el && el.classList && el.classList.contains('ip-field')) ? el : null;
            });
        }
    }

    function flash(el) {
        el.classList.add('ip-filled-flash');
        setTimeout(function () { el.classList.remove('ip-filled-flash'); }, 1000);
    }

    var hintEl = null;
    function hint(msg) {
        if (!hintEl) { hintEl = document.createElement('div'); hintEl.className = 'copy-hint'; document.body.appendChild(hintEl); }
        hintEl.textContent = msg;
        hintEl.style.opacity = '1';
        setTimeout(function () { hintEl.style.opacity = '0'; }, 1500);
    }

    function render() {
        var rows = (window.EXISTING_ROWS || []).slice();
        rows = rows.concat(collectPendingRows());
        SBG.init({
            mount: mount,
            rows: rows,
            subnet: SUBNET,
            canEdit: false,
            onHoleClick: function (ip) {
                if (!activeIpField) { hint('Clique d\'abord dans un champ IP'); return; }
                activeIpField.value = ip;
                flash(activeIpField);
                activeIpField.dispatchEvent(new Event('input', { bubbles: true }));
                activeIpField.dispatchEvent(new Event('blur', { bubbles: true }));
            }
        });
        attachHoleCapture(); // ré-attacher après chaque re-render (init recrée les segments)
    }

    var t = null;
    function schedule() { clearTimeout(t); t = setTimeout(render, 150); }

    var form = document.getElementById('copy-apply-form');
    if (form) {
        form.addEventListener('change', function (e) {
            if (e.target.matches && (e.target.matches('input[type=checkbox]') || e.target.matches('select'))) render();
        });
        form.addEventListener('input', function (e) {
            if (e.target.classList && e.target.classList.contains('ip-field')) schedule();
        });
    }

    render();
}());
