/**
 * NICC Style Config - Frontend
 */
(function(){
'use strict';

var APP, STYLEKEY, SECTOK;
var systemsCache = [];
var groupsCache = [];

// ── Init ───────────────────────────────────────────────────

document.addEventListener('DOMContentLoaded', function() {
    APP = document.getElementById('niccstyle-app');
    if (!APP) return;
    STYLEKEY = APP.dataset.stylekey || '';
    SECTOK = APP.dataset.sectok || '';

    initTabs();
    loadSystems();
    loadGroups();
    loadLogs();
    initSystemsTab();
    initGroupsTab();
    initAssignmentsTab();
    initApplyTab();
});

// ── AJAX Helper ────────────────────────────────────────────

function ajax(action, params, method) {
    method = method || 'GET';
    var url = DOKU_BASE + 'lib/exe/ajax.php';

    params = params || {};
    params.call = 'plugin_niccstyleconfig_' + action;
    params.stylekey = STYLEKEY;

    if (method === 'POST') {
        params.sectok = SECTOK;
        return fetch(url, {
            method: 'POST',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            body: new URLSearchParams(params).toString()
        }).then(handleResponse);
    } else {
        url += '?' + new URLSearchParams(params).toString();
        return fetch(url).then(handleResponse);
    }
}

function handleResponse(r) {
    if (!r.ok) throw new Error('HTTP ' + r.status);
    return r.json();
}

// ── Tabs ───────────────────────────────────────────────────

function initTabs() {
    var tabs = APP.querySelectorAll('.nsc-tab');
    tabs.forEach(function(tab) {
        tab.addEventListener('click', function(e) {
            e.preventDefault();
            tabs.forEach(function(t){ t.classList.remove('active'); });
            tab.classList.add('active');

            APP.querySelectorAll('.nsc-panel').forEach(function(p){ p.style.display = 'none'; });
            var panel = document.getElementById('nsc-panel-' + tab.dataset.tab);
            if (panel) panel.style.display = '';

            if (tab.dataset.tab === 'groups') loadGroups();
            if (tab.dataset.tab === 'assignments') refreshAssignmentsDropdown();
            if (tab.dataset.tab === 'apply') { loadGroups(); loadLogs(); }
        });
    });
}

// ── Tab 1: Systems ─────────────────────────────────────────

function initSystemsTab() {
    document.getElementById('nsc-btn-scan').addEventListener('click', scanSystems);
    document.getElementById('nsc-filter-systems').addEventListener('input', debounce(filterSystems, 200));
}

function loadSystems() {
    ajax('systems').then(function(data) {
        if (!data.ok) return;
        systemsCache = data.systems || [];
        renderSystemsTable(systemsCache);
        document.getElementById('nsc-systems-count').textContent = systemsCache.length;
        if (data.cache_date) {
            document.getElementById('nsc-cache-date').textContent = 'Escaneo: ' + data.cache_date;
        }
    }).catch(function(e) {
        console.error('niccstyleconfig: error loading systems', e);
    });
}

function scanSystems() {
    var btn = document.getElementById('nsc-btn-scan');
    var loading = document.getElementById('nsc-systems-loading');
    btn.disabled = true;
    loading.style.display = '';

    ajax('scan').then(function(data) {
        btn.disabled = false;
        loading.style.display = 'none';
        if (!data.ok) {
            alert('Error: ' + (data.error || 'desconocido'));
            return;
        }
        systemsCache = data.systems || [];
        renderSystemsTable(systemsCache);
        document.getElementById('nsc-systems-count').textContent = systemsCache.length;
        document.getElementById('nsc-cache-date').textContent = 'Escaneo: ahora';
    }).catch(function() {
        btn.disabled = false;
        loading.style.display = 'none';
        alert('Error de conexion al escanear');
    });
}

function renderSystemsTable(systems) {
    var tbody = document.getElementById('nsc-systems-tbody');
    if (!systems.length) {
        tbody.innerHTML = '<tr><td colspan="7" class="nsc-empty">No hay sistemas. Ejecute un escaneo.</td></tr>';
        return;
    }
    var html = '';
    systems.forEach(function(s, i) {
        var groupLabel = '';
        if (s.group_origin) groupLabel += '<span class="nsc-badge nsc-badge-sm nsc-badge-origin">Origen: ' + esc(s.group_origin) + '</span>';
        if (s.group_dest) groupLabel += '<span class="nsc-badge nsc-badge-sm">Dest: ' + esc(s.group_dest) + '</span>';
        html += '<tr data-name="' + escAttr(s.system_name) + '">';
        html += '<td>' + (i+1) + '</td>';
        html += '<td><strong>' + esc(s.system_name) + '</strong></td>';
        html += '<td>' + esc(s.system_title || '-') + '</td>';
        html += '<td><span class="nsc-badge nsc-badge-template">' + esc(s.template || '-') + '</span></td>';
        html += '<td>' + (s.has_style_ini_20 == 1 ? '<span class="nsc-dot nsc-dot-ok"></span>' : '<span class="nsc-dot nsc-dot-no"></span>') + '</td>';
        html += '<td>' + (s.has_style_ini_21 == 1 ? '<span class="nsc-dot nsc-dot-ok"></span>' : '<span class="nsc-dot nsc-dot-no"></span>') + '</td>';
        html += '<td>' + (groupLabel || '<span class="nsc-text-muted">-</span>') + '</td>';
        html += '</tr>';
    });
    tbody.innerHTML = html;
}

function filterSystems() {
    var q = document.getElementById('nsc-filter-systems').value.toLowerCase();
    var filtered = systemsCache.filter(function(s) {
        return s.system_name.toLowerCase().indexOf(q) !== -1 ||
               (s.system_title || '').toLowerCase().indexOf(q) !== -1;
    });
    renderSystemsTable(filtered);
    document.getElementById('nsc-systems-count').textContent = filtered.length;
}

// ── Tab 2: Groups ──────────────────────────────────────────

function initGroupsTab() {
    document.getElementById('nsc-btn-save-group').addEventListener('click', saveGroup);
    document.getElementById('nsc-btn-cancel-group').addEventListener('click', cancelGroupEdit);
}

function loadGroups() {
    ajax('group_list').then(function(data) {
        if (!data.ok) return;
        groupsCache = data.groups || [];
        renderGroupsGrid(groupsCache);
        renderApplyGroups(groupsCache);
    }).catch(function(e) {
        console.error('niccstyleconfig: error loading groups', e);
    });
}

function renderGroupsGrid(groups) {
    var grid = document.getElementById('nsc-groups-grid');
    if (!groups.length) {
        grid.innerHTML = '<div class="nsc-empty">No hay grupos creados. Cree uno arriba.</div>';
        return;
    }
    var html = '';
    groups.forEach(function(g) {
        var originName = g.origin ? g.origin.system_name : 'Sin origen';
        html += '<div class="nsc-group-card" data-id="' + g.id + '" data-label="' + escAttr(g.label) + '" data-color="' + escAttr(g.color) + '" data-desc="' + escAttr(g.description || '') + '">';
        html += '  <div class="nsc-group-header">';
        html += '    <span class="nsc-color-dot" style="background:' + escColor(g.color) + '"></span>';
        html += '    <strong>' + esc(g.label) + '</strong>';
        html += '    <label class="nsc-switch"><input type="checkbox" class="nsc-group-toggle" data-gid="' + g.id + '" ' + (g.is_active == 1 ? 'checked' : '') + '><span class="nsc-switch-slider"></span></label>';
        html += '  </div>';
        if (g.description) html += '  <p class="nsc-group-desc">' + esc(g.description) + '</p>';
        html += '  <div class="nsc-group-meta">';
        html += '    <span>Origen: <strong>' + esc(originName) + '</strong></span>';
        html += '    <span>Destinos: <strong>' + g.dest_count + '</strong></span>';
        html += '  </div>';
        html += '  <div class="nsc-group-actions">';
        html += '    <button class="nsc-btn nsc-btn-sm nsc-group-edit" data-gid="' + g.id + '">Editar</button>';
        html += '    <button class="nsc-btn nsc-btn-sm nsc-btn-danger-sm nsc-group-delete" data-gid="' + g.id + '">Eliminar</button>';
        html += '  </div>';
        html += '</div>';
    });
    grid.innerHTML = html;

    // Bind events via delegation (prevents XSS from inline onclick)
    grid.querySelectorAll('.nsc-group-edit').forEach(function(btn) {
        btn.addEventListener('click', function() {
            var card = btn.closest('.nsc-group-card');
            editGroup(card.dataset.id, card.dataset.label, card.dataset.color, card.dataset.desc);
        });
    });
    grid.querySelectorAll('.nsc-group-delete').forEach(function(btn) {
        btn.addEventListener('click', function() {
            var card = btn.closest('.nsc-group-card');
            deleteGroup(card.dataset.id, card.dataset.label);
        });
    });
    grid.querySelectorAll('.nsc-group-toggle').forEach(function(chk) {
        chk.addEventListener('change', function() {
            toggleGroup(chk.dataset.gid, chk.checked);
        });
    });
}

function editGroup(id, label, color, desc) {
    document.getElementById('nsc-group-edit-id').value = id;
    document.getElementById('nsc-group-label').value = label;
    document.getElementById('nsc-group-color').value = color;
    document.getElementById('nsc-group-desc').value = desc;
    document.getElementById('nsc-group-form-title').textContent = 'Editar Grupo';
    document.getElementById('nsc-btn-cancel-group').style.display = '';
    document.getElementById('nsc-group-label').focus();
}

function deleteGroup(id, label) {
    if (!confirm('Eliminar el grupo "' + label + '" y todas sus asignaciones?')) return;
    ajax('group_del', { id: id }, 'POST').then(function(data) {
        if (!data.ok) { alert('Error al eliminar'); return; }
        loadGroups();
    }).catch(function() { alert('Error de conexion'); });
}

function toggleGroup(id, active) {
    ajax('group_toggle', { id: id, is_active: active ? 1 : 0 }, 'POST').catch(function() {
        alert('Error al cambiar estado del grupo');
    });
}

function saveGroup() {
    var id = document.getElementById('nsc-group-edit-id').value;
    var label = document.getElementById('nsc-group-label').value.trim();
    var color = document.getElementById('nsc-group-color').value;
    var desc = document.getElementById('nsc-group-desc').value.trim();

    if (!label) { alert('La etiqueta es obligatoria'); return; }

    var params = { label: label, color: color, description: desc, is_active: 1 };
    if (id) params.id = id;

    ajax('group_save', params, 'POST').then(function(data) {
        if (!data.ok) { alert('Error: ' + (data.error || 'No se pudo guardar')); return; }
        cancelGroupEdit();
        loadGroups();
    }).catch(function() { alert('Error de conexion'); });
}

function cancelGroupEdit() {
    document.getElementById('nsc-group-edit-id').value = '';
    document.getElementById('nsc-group-label').value = '';
    document.getElementById('nsc-group-color').value = '#3b82f6';
    document.getElementById('nsc-group-desc').value = '';
    document.getElementById('nsc-group-form-title').textContent = 'Nuevo Grupo';
    document.getElementById('nsc-btn-cancel-group').style.display = 'none';
}

// ── Tab 3: Assignments ─────────────────────────────────────

function initAssignmentsTab() {
    document.getElementById('nsc-assign-group').addEventListener('change', onGroupSelected);
    document.getElementById('nsc-btn-set-origin').addEventListener('click', setOrigin);
    document.getElementById('nsc-btn-save-dests').addEventListener('click', saveDestinations);
    document.getElementById('nsc-btn-select-all').addEventListener('click', function() { toggleAllDests(true); });
    document.getElementById('nsc-btn-deselect-all').addEventListener('click', function() { toggleAllDests(false); });
    document.getElementById('nsc-filter-dest').addEventListener('input', debounce(filterDests, 200));
}

function refreshAssignmentsDropdown() {
    var sel = document.getElementById('nsc-assign-group');
    var currentVal = sel.value;
    var html = '<option value="">-- Seleccionar grupo --</option>';
    groupsCache.forEach(function(g) {
        html += '<option value="' + g.id + '">' + esc(g.label) + (g.is_active != 1 ? ' (inactivo)' : '') + '</option>';
    });
    sel.innerHTML = html;
    if (currentVal) sel.value = currentVal;
}

function onGroupSelected() {
    var groupId = document.getElementById('nsc-assign-group').value;
    var layout = document.getElementById('nsc-assign-layout');
    if (!groupId) { layout.style.display = 'none'; return; }
    layout.style.display = '';

    ajax('assignments', { group_id: groupId }).then(function(data) {
        if (!data.ok) return;

        // Origin
        var originDiv = document.getElementById('nsc-origin-current');
        if (data.origin) {
            originDiv.innerHTML = '<strong>' + esc(data.origin.system_name) + '</strong> <span class="nsc-text-muted">(' + esc(data.origin.template || '') + ')</span>';
            loadColorPreview(data.origin.system_name, data.origin.template || '20cones');
        } else {
            originDiv.innerHTML = '<span class="nsc-text-muted">Sin origen asignado</span>';
            document.getElementById('nsc-origin-preview').style.display = 'none';
        }

        // Populate origin dropdown
        var origSel = document.getElementById('nsc-origin-select');
        var optHtml = '<option value="">-- Seleccionar sistema --</option>';
        systemsCache.forEach(function(s) {
            optHtml += '<option value="' + escAttr(s.system_name) + '">' + esc(s.system_name) + ' (' + esc(s.template || '-') + ')</option>';
        });
        origSel.innerHTML = optHtml;

        // Destinations checklist
        var destNames = {};
        (data.destinations || []).forEach(function(d) { destNames[d.system_name] = true; });
        renderDestChecklist(destNames);
        document.getElementById('nsc-dest-count').textContent = Object.keys(destNames).length;
    }).catch(function(e) {
        console.error('niccstyleconfig: error loading assignments', e);
    });
}

function renderDestChecklist(selectedMap) {
    var container = document.getElementById('nsc-dest-list');
    var html = '';
    systemsCache.forEach(function(s) {
        var checked = selectedMap[s.system_name] ? 'checked' : '';
        html += '<label class="nsc-check-item" data-name="' + escAttr(s.system_name).toLowerCase() + '">';
        html += '  <input type="checkbox" value="' + escAttr(s.system_name) + '" ' + checked + '>';
        html += '  <span>' + esc(s.system_name) + '</span>';
        html += '</label>';
    });
    container.innerHTML = html || '<div class="nsc-empty">No hay sistemas en cache</div>';
}

function toggleAllDests(state) {
    var checks = document.querySelectorAll('#nsc-dest-list input[type=checkbox]');
    checks.forEach(function(c) {
        if (c.closest('.nsc-check-item').style.display !== 'none') c.checked = state;
    });
}

function filterDests() {
    var q = document.getElementById('nsc-filter-dest').value.toLowerCase();
    var items = document.querySelectorAll('#nsc-dest-list .nsc-check-item');
    items.forEach(function(item) {
        item.style.display = item.dataset.name.indexOf(q) !== -1 ? '' : 'none';
    });
}

function setOrigin() {
    var groupId = document.getElementById('nsc-assign-group').value;
    var systemName = document.getElementById('nsc-origin-select').value;
    if (!groupId || !systemName) { alert('Seleccione un grupo y un sistema'); return; }

    ajax('set_origin', { group_id: groupId, system_name: systemName }, 'POST').then(function(data) {
        if (!data.ok) { alert('Error: ' + (data.error || '')); return; }
        onGroupSelected();
    }).catch(function() { alert('Error de conexion'); });
}

function saveDestinations() {
    var groupId = document.getElementById('nsc-assign-group').value;
    if (!groupId) return;

    var btn = document.getElementById('nsc-btn-save-dests');
    btn.disabled = true;

    var checks = document.querySelectorAll('#nsc-dest-list input[type=checkbox]:checked');
    var names = [];
    checks.forEach(function(c) { names.push(c.value); });

    // Fetch existing, compute diff, apply changes
    ajax('assignments', { group_id: groupId }).then(function(data) {
        if (!data.ok) { btn.disabled = false; return; }
        var existingDests = (data.destinations || []).map(function(d) { return d.system_name; });

        // Remove unchecked
        var toRemove = existingDests.filter(function(n) { return names.indexOf(n) === -1; });
        var removePromises = toRemove.map(function(n) {
            return ajax('rem_dest', { group_id: groupId, system_name: n }, 'POST');
        });

        // Add new
        var toAdd = names.filter(function(n) { return existingDests.indexOf(n) === -1; });

        Promise.all(removePromises).then(function() {
            if (toAdd.length === 0) {
                btn.disabled = false;
                alert('Destinos actualizados. Removidos: ' + toRemove.length);
                onGroupSelected();
                return;
            }
            // Send array as form-encoded
            var params = new URLSearchParams();
            params.append('call', 'plugin_niccstyleconfig_add_dest');
            params.append('stylekey', STYLEKEY);
            params.append('sectok', SECTOK);
            params.append('group_id', groupId);
            toAdd.forEach(function(n) { params.append('system_names[]', n); });

            fetch(DOKU_BASE + 'lib/exe/ajax.php', {
                method: 'POST',
                headers: {'Content-Type': 'application/x-www-form-urlencoded'},
                body: params.toString()
            }).then(handleResponse).then(function(data) {
                btn.disabled = false;
                alert('Destinos actualizados. Agregados: ' + (data.added || 0) + ', Removidos: ' + toRemove.length);
                onGroupSelected();
            }).catch(function() {
                btn.disabled = false;
                alert('Error al agregar destinos');
            });
        }).catch(function() {
            btn.disabled = false;
            alert('Error al remover destinos');
        });
    }).catch(function() {
        btn.disabled = false;
        alert('Error de conexion');
    });
}

function loadColorPreview(systemName, template) {
    ajax('preview', { system_name: systemName, template: template }).then(function(data) {
        var div = document.getElementById('nsc-origin-preview');
        if (!data.ok || !data.colors || Object.keys(data.colors).length === 0) {
            div.style.display = 'none';
            return;
        }
        var html = '<h4>Colores del origen:</h4><div class="nsc-swatches">';
        for (var k in data.colors) {
            html += '<div class="nsc-swatch" title="' + escAttr(k) + '">';
            html += '  <span class="nsc-swatch-color" style="background:' + escColor(data.colors[k]) + '"></span>';
            html += '  <small>' + esc(k.replace(/__/g, '')) + '</small>';
            html += '</div>';
        }
        html += '</div>';
        div.innerHTML = html;
        div.style.display = '';
    }).catch(function() {});
}

// ── Tab 4: Apply & Logs ────────────────────────────────────

function initApplyTab() {
    document.getElementById('nsc-btn-apply-all').addEventListener('click', applyAll);
    document.getElementById('nsc-btn-load-backups').addEventListener('click', loadBackups);
}

function renderApplyGroups(groups) {
    var container = document.getElementById('nsc-apply-groups');
    var activeGroups = groups.filter(function(g) { return g.is_active == 1; });
    if (!activeGroups.length) {
        container.innerHTML = '<div class="nsc-empty">No hay grupos activos</div>';
        return;
    }
    var html = '';
    activeGroups.forEach(function(g) {
        var originName = g.origin ? g.origin.system_name : '?';
        html += '<div class="nsc-apply-row">';
        html += '  <span class="nsc-color-dot" style="background:' + escColor(g.color) + '"></span>';
        html += '  <strong>' + esc(g.label) + '</strong>';
        html += '  <span class="nsc-text-muted">' + esc(originName) + ' &rarr; ' + g.dest_count + ' destinos</span>';
        html += '  <button class="nsc-btn nsc-btn-sm nsc-btn-primary nsc-apply-single" data-gid="' + g.id + '" data-label="' + escAttr(g.label) + '" data-count="' + g.dest_count + '">Aplicar</button>';
        html += '</div>';
    });
    container.innerHTML = html;

    // Bind events
    container.querySelectorAll('.nsc-apply-single').forEach(function(btn) {
        btn.addEventListener('click', function() {
            applySingleGroup(btn.dataset.gid, btn.dataset.label, btn.dataset.count);
        });
    });
}

function applySingleGroup(id, label, destCount) {
    if (!confirm('Aplicar estilos del grupo "' + label + '" a ' + destCount + ' sistemas destino?')) return;

    var progress = document.getElementById('nsc-apply-progress');
    var results = document.getElementById('nsc-apply-results');
    progress.style.display = '';
    results.style.display = 'none';
    document.getElementById('nsc-progress-bar').style.width = '50%';
    document.getElementById('nsc-apply-status').textContent = 'Aplicando estilos del grupo "' + label + '"...';

    ajax('apply', { group_id: id }, 'POST').then(function(data) {
        document.getElementById('nsc-progress-bar').style.width = '100%';
        if (!data.ok) {
            document.getElementById('nsc-apply-status').textContent = 'Error: ' + (data.error || 'desconocido');
            return;
        }
        var r = data.results || {};
        var statusText = 'Completado. OK: ' + (r.success || []).length + ' | Fallidos: ' + (r.failed || []).length;
        document.getElementById('nsc-apply-status').textContent = statusText;

        if ((r.failed || []).length > 0) {
            var rhtml = '<div class="nsc-card" style="margin-top:0.5rem;"><h4>Errores:</h4><ul>';
            r.failed.forEach(function(f) {
                rhtml += '<li><strong>' + esc(f.system) + '</strong>: ' + esc(f.error) + '</li>';
            });
            rhtml += '</ul></div>';
            results.innerHTML = rhtml;
            results.style.display = '';
        }

        loadLogs();
    }).catch(function() {
        document.getElementById('nsc-progress-bar').style.width = '100%';
        document.getElementById('nsc-apply-status').textContent = 'Error de conexion';
    });
}

function applyAll() {
    var activeCount = groupsCache.filter(function(g) { return g.is_active == 1; }).length;
    if (!activeCount) { alert('No hay grupos activos'); return; }
    if (!confirm('Aplicar estilos de TODOS los ' + activeCount + ' grupos activos?')) return;

    var progress = document.getElementById('nsc-apply-progress');
    progress.style.display = '';
    document.getElementById('nsc-progress-bar').style.width = '30%';
    document.getElementById('nsc-apply-status').textContent = 'Aplicando todos los grupos activos...';

    ajax('apply_all', {}, 'POST').then(function(data) {
        document.getElementById('nsc-progress-bar').style.width = '100%';
        if (!data.ok) {
            document.getElementById('nsc-apply-status').textContent = 'Error general';
            return;
        }
        var total = 0, ok = 0, fail = 0;
        for (var lbl in data.results) {
            var r = data.results[lbl];
            if (r.results) {
                ok += (r.results.success || []).length;
                fail += (r.results.failed || []).length;
            }
            total++;
        }
        document.getElementById('nsc-apply-status').textContent = 'Completado. Grupos: ' + total + ' | OK: ' + ok + ' | Fallidos: ' + fail;
        loadLogs();
    }).catch(function() {
        document.getElementById('nsc-progress-bar').style.width = '100%';
        document.getElementById('nsc-apply-status').textContent = 'Error de conexion';
    });
}

function loadBackups() {
    var filter = document.getElementById('nsc-backup-filter').value.trim();
    ajax('backups', { system_name: filter }).then(function(data) {
        if (!data.ok) return;
        var tbody = document.getElementById('nsc-backups-tbody');
        var backups = data.backups || [];
        if (!backups.length) {
            tbody.innerHTML = '<tr><td colspan="7" class="nsc-empty">No hay backups' + (filter ? ' para "' + esc(filter) + '"' : '') + '</td></tr>';
            return;
        }
        var html = '';
        backups.forEach(function(b) {
            html += '<tr>';
            html += '<td>' + esc(b.created_at) + '</td>';
            html += '<td>' + esc(b.system_name) + '</td>';
            html += '<td>' + esc(b.template) + '</td>';
            html += '<td>' + esc(b.group_label || '-') + '</td>';
            html += '<td>v' + esc(b.version) + '</td>';
            html += '<td>' + esc(b.backup_reason || '-') + '</td>';
            html += '<td><button class="nsc-btn nsc-btn-sm nsc-rollback-btn" data-bid="' + b.id + '" data-sys="' + escAttr(b.system_name) + '" data-date="' + escAttr(b.created_at) + '">Restaurar</button></td>';
            html += '</tr>';
        });
        tbody.innerHTML = html;

        // Bind rollback buttons
        tbody.querySelectorAll('.nsc-rollback-btn').forEach(function(btn) {
            btn.addEventListener('click', function() {
                doRollback(btn.dataset.bid, btn.dataset.sys, btn.dataset.date);
            });
        });
    }).catch(function(e) {
        console.error('niccstyleconfig: error loading backups', e);
    });
}

function doRollback(id, system, date) {
    if (!confirm('Restaurar el style.ini de "' + system + '" desde el backup del ' + date + '?')) return;
    ajax('rollback', { backup_id: id }, 'POST').then(function(data) {
        if (!data.ok) { alert('Error: ' + (data.error || '')); return; }
        alert('Restauracion exitosa');
        loadBackups();
        loadLogs();
    }).catch(function() { alert('Error de conexion'); });
}

function loadLogs() {
    ajax('logs').then(function(data) {
        if (!data.ok) return;
        var tbody = document.getElementById('nsc-logs-tbody');
        var logs = data.logs || [];
        if (!logs.length) {
            tbody.innerHTML = '<tr><td colspan="6" class="nsc-empty">Sin operaciones registradas</td></tr>';
            return;
        }
        var html = '';
        logs.forEach(function(l) {
            var statusClass = l.status === 'ok' ? 'nsc-badge-ok' : (l.status === 'error' ? 'nsc-badge-error' : 'nsc-badge-warn');
            html += '<tr>';
            html += '<td>' + esc(l.created_at) + '</td>';
            html += '<td>' + esc(l.action) + '</td>';
            html += '<td>' + esc(l.group_label || '-') + '</td>';
            html += '<td class="nsc-log-details">' + esc((l.details || '').substring(0, 120)) + '</td>';
            html += '<td>' + esc(l.systems_affected) + '</td>';
            html += '<td><span class="nsc-badge ' + statusClass + '">' + esc(l.status) + '</span></td>';
            html += '</tr>';
        });
        tbody.innerHTML = html;
    }).catch(function(e) {
        console.error('niccstyleconfig: error loading logs', e);
    });
}

// ── Utility ────────────────────────────────────────────────

// Cached element for HTML escaping (performance: reuse instead of creating per call)
var _escEl = null;
function esc(s) {
    if (s === null || s === undefined) return '';
    if (!_escEl) _escEl = document.createElement('span');
    _escEl.textContent = String(s);
    return _escEl.innerHTML;
}

// Escape for use in HTML attributes (double quotes)
function escAttr(s) {
    if (s === null || s === undefined) return '';
    return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&#39;');
}

// Validate and escape color for use in CSS style attributes
function escColor(c) {
    if (!c || !/^#[0-9a-fA-F]{3,8}$/.test(c)) return '#cccccc';
    return c;
}

// Debounce helper for filter inputs
function debounce(fn, delay) {
    var timer;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(fn, delay);
    };
}

})();
