/* ZeroTrust Shield – Dashboard JS */
'use strict';

// ---------------------------------------------------------------
// Estado global
// ---------------------------------------------------------------
let currentPeriod = '24h';
let logPage       = 1;
let logFilters    = { search: '', category: '', reason: '' };
// Inicializar desde URL para que persista al refrescar
const _urlParams = new URLSearchParams(window.location.search);
let viewUserId = _urlParams.get('view_user') || '';

let chartTimeline   = null;
let chartCategories = null;
let chartTopDomains = null;
let chartTopClients = null;

// ---------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------
function api(action, extra = {}) {
    const params = new URLSearchParams({ action, period: currentPeriod, ...extra });
    if (ZT_CONFIG.clientFilter) params.set('client_id', ZT_CONFIG.clientFilter);
    if (ZT_CONFIG.isAdmin && viewUserId) params.set('view_user', viewUserId);
    return fetch('api.php?' + params).then(r => r.json());
}

function fmtNum(n) {
    if (n >= 1e6) return (n / 1e6).toFixed(1) + 'M';
    if (n >= 1e3) return (n / 1e3).toFixed(1) + 'K';
    return String(n);
}

function fmtDate(str) {
    if (!str) return '–';
    const d = new Date(str.replace(' ', 'T'));
    return d.toLocaleDateString('es-AR', { day:'2-digit', month:'2-digit' }) + ' ' +
           d.toLocaleTimeString('es-AR', { hour:'2-digit', minute:'2-digit', second:'2-digit' });
}

function reasonBadge(reason) {
    const map = {
        FilteredBlackList:    ['danger',   'Bloqueado'],
        FilteredSafeBrowsing: ['danger',   'Amenaza'],
        FilteredParental:     ['warning',  'Parental'],
        FilteredSafeSearch:   ['warning',  'SafeSearch'],
        NotFilteredWhiteList: ['success',  'Lista Blanca'],
        NotFilteredNotFound:  ['secondary','Permitido'],
        Rewrite:              ['info',     'Reescritura'],
    };
    const [cls, label] = map[reason] || ['secondary', reason];
    return `<span class="badge text-bg-${cls}">${label}</span>`;
}

// ---------------------------------------------------------------
// Explicación de dominio (modal IA)
// ---------------------------------------------------------------
let _explainModal = null;

function riskBadge(riesgo) {
    const map = {
        bajo:  ['#198754', 'bi-shield-check',          'Riesgo bajo'],
        medio: ['#ffc107', 'bi-shield-exclamation',    'Riesgo medio'],
        alto:  ['#dc3545', 'bi-shield-fill-exclamation','Riesgo alto'],
    };
    const [color, icon, label] = map[riesgo] || map.medio;
    return `<span class="badge" style="background:${color}1f;color:${color};border:1px solid ${color}55;font-size:.72rem">
                <i class="bi ${icon} me-1"></i>${label}
            </span>`;
}

function escapeHtml(s) {
    const div = document.createElement('div');
    div.textContent = s || '';
    return div.innerHTML;
}

async function showExplainModal(domain, category) {
    if (!_explainModal) {
        _explainModal = new bootstrap.Modal(document.getElementById('explainModal'));
    }
    const body = document.getElementById('explainModalBody');
    body.innerHTML = `
        <div class="text-center py-4">
            <div class="spinner-border text-primary mb-3" role="status"></div>
            <div class="text-secondary" style="font-size:.85rem">
                Analizando <strong class="text-white">${escapeHtml(domain)}</strong>…
            </div>
        </div>`;
    _explainModal.show();

    try {
        const d = await api('explain_domain', { domain, category });
        if (d.error || !d.success) {
            body.innerHTML = `<div class="alert alert-warning mb-0" style="font-size:.85rem">
                <i class="bi bi-exclamation-triangle me-1"></i>${escapeHtml(d.error || 'No se pudo generar la explicación.')}
            </div>`;
            return;
        }
        body.innerHTML = `
            <div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
                <code style="color:#3b82f6;font-size:.9rem;word-break:break-all">${escapeHtml(d.domain)}</code>
                ${riskBadge(d.riesgo)}
            </div>
            <div class="mb-3">
                <div class="text-secondary text-uppercase mb-1" style="font-size:.68rem;letter-spacing:.05em">
                    <i class="bi bi-info-circle me-1"></i>Qué es
                </div>
                <div class="text-white" style="font-size:.88rem;line-height:1.5">${escapeHtml(d.que_es)}</div>
            </div>
            <div class="mb-3">
                <div class="text-secondary text-uppercase mb-1" style="font-size:.68rem;letter-spacing:.05em">
                    <i class="bi bi-shield-x me-1"></i>Por qué se bloqueó
                </div>
                <div class="text-white" style="font-size:.88rem;line-height:1.5">${escapeHtml(d.por_que)}</div>
            </div>
            ${d.consejo ? `<div class="p-2 rounded" style="background:rgba(59,130,246,0.08);border:1px solid rgba(59,130,246,0.2)">
                <div style="font-size:.85rem;color:#cbd5e1"><i class="bi bi-lightbulb me-1" style="color:#3b82f6"></i>${escapeHtml(d.consejo)}</div>
            </div>` : ''}`;
    } catch (e) {
        body.innerHTML = `<div class="alert alert-danger mb-0" style="font-size:.85rem">
            <i class="bi bi-x-circle me-1"></i>Error de conexión. Intentá de nuevo.
        </div>`;
    }
}

// ---------------------------------------------------------------
// Cargar stats resumen
// ---------------------------------------------------------------
async function loadStats() {
    const d = await api('stats');
    document.getElementById('statTotalQueries').textContent = fmtNum(d.total_queries  || 0);
    document.getElementById('statTotalBlocked').textContent = fmtNum(d.total_blocked  || 0);
    document.getElementById('statBlockRate').textContent    = (d.block_rate || 0) + '%';
    document.getElementById('statTopCategory').textContent  = d.top_category || '–';
}

// ---------------------------------------------------------------
// Timeline chart
// ---------------------------------------------------------------
async function loadTimeline() {
    const d = await api('timeline');
    const subtitleMap = { '6h': 'últimas 6 horas', '24h': 'últimas 24 horas', '7d': 'últimos 7 días', '30d': 'últimos 30 días' };
    document.getElementById('timelineSubtitle').textContent = subtitleMap[currentPeriod] || '';

    // Formatear labels
    const labels = (d.labels || []).map(ts => {
        const dt = new Date(ts.replace(' ', 'T'));
        if (currentPeriod === '7d' || currentPeriod === '30d')
            return dt.toLocaleDateString('es-AR', { day:'2-digit', month:'2-digit' });
        return dt.toLocaleTimeString('es-AR', { hour:'2-digit', minute:'2-digit' });
    });

    const cfg = {
        type: 'line',
        data: {
            labels,
            datasets: [
                {
                    label: 'Total consultas',
                    data: d.totals || [],
                    borderColor: '#3b82f6',
                    backgroundColor: 'rgba(59,130,246,0.1)',
                    fill: true,
                    tension: 0.4,
                    pointRadius: 2,
                    borderWidth: 2,
                },
                {
                    label: 'Bloqueadas',
                    data: d.blocked || [],
                    borderColor: '#ef4444',
                    backgroundColor: 'rgba(239,68,68,0.1)',
                    fill: true,
                    tension: 0.4,
                    pointRadius: 2,
                    borderWidth: 2,
                },
            ],
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: { labels: { color: '#64748b', font: { size: 11 } } },
                tooltip: { mode: 'index', intersect: false },
            },
            scales: {
                x: { ticks: { color: '#64748b', maxTicksLimit: 12 }, grid: { color: 'rgba(0,0,0,0.05)' } },
                y: { ticks: { color: '#64748b' }, grid: { color: 'rgba(0,0,0,0.06)' }, beginAtZero: true },
            },
        },
    };

    if (chartTimeline) { chartTimeline.destroy(); }
    chartTimeline = new Chart(document.getElementById('chartTimeline'), cfg);
}

// ---------------------------------------------------------------
// Categorías (donut)
// ---------------------------------------------------------------
async function loadCategories() {
    const d = await api('categories');
    const cfg = {
        type: 'doughnut',
        data: {
            labels: d.labels || [],
            datasets: [{ data: d.values || [], backgroundColor: d.colors || [], borderWidth: 2, borderColor: '#1e293b' }],
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            cutout: '60%',
            plugins: {
                legend: { display: false },
                tooltip: { callbacks: {
                    label: ctx => ` ${ctx.label}: ${fmtNum(ctx.raw)} bloqueos`
                }},
            },
        },
    };
    if (chartCategories) chartCategories.destroy();
    chartCategories = new Chart(document.getElementById('chartCategories'), cfg);

    // Leyenda manual
    const legend = document.getElementById('categoryLegend');
    legend.innerHTML = (d.labels || []).map((lbl, i) =>
        `<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;background:transparent">
            <span style="width:9px;height:9px;border-radius:2px;background:${d.colors[i]};flex-shrink:0;display:inline-block"></span>
            <span style="color:#64748b;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${lbl}</span>
            <span style="color:#1e293b;font-weight:600">${fmtNum(d.values[i])}</span>
         </div>`
    ).join('');

    // Tabla resumen de categorías (solo para clientes)
    if (!ZT_CONFIG.isAdmin) {
        const tbl = document.getElementById('categorySummaryTable');
        if (tbl) {
            const rows = (d.labels || []).map((lbl, i) =>
                `<tr style="background:transparent;border-color:rgba(255,255,255,0.07)">
                    <td style="background:transparent;border-color:rgba(255,255,255,0.07);padding:.4rem .5rem;color:#94a3b8;vertical-align:middle">
                        <span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${d.colors[i]};margin-right:6px"></span>${lbl}
                    </td>
                    <td style="background:transparent;border-color:rgba(255,255,255,0.07);padding:.4rem .5rem;text-align:right;font-weight:600;color:#fff">${fmtNum(d.values[i])}</td>
                </tr>`
            ).join('');
            tbl.innerHTML = `<div style="overflow-x:auto">
                <table style="width:100%;border-collapse:collapse;font-size:.8rem">
                    <thead><tr style="background:#162032">
                        <th style="padding:.45rem .5rem;color:#64748b;font-size:.68rem;text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid rgba(255,255,255,0.07)">Categoría</th>
                        <th style="padding:.45rem .5rem;color:#64748b;font-size:.68rem;text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid rgba(255,255,255,0.07);text-align:right">Bloqueos</th>
                    </tr></thead>
                    <tbody>${rows}</tbody>
                </table></div>`;
        }
    }
}

// ---------------------------------------------------------------
// Top dominios bloqueados
// ---------------------------------------------------------------
async function loadTopDomains() {
    const d = await api('top_domains', { limit: 10 });
    const rows = Array.isArray(d) ? d : [];
    const labels = rows.map(r => r.domain.length > 35 ? r.domain.slice(0,33)+'…' : r.domain);
    const values = rows.map(r => parseInt(r.cnt));
    const colors = rows.map(r => r.category_color || '#6c757d');

    const cfg = {
        type: 'bar',
        data: {
            labels,
            datasets: [{ data: values, backgroundColor: colors, borderWidth: 0, borderRadius: 4 }],
        },
        options: {
            indexAxis: 'y',
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: { display: false },
                tooltip: { callbacks: {
                    label: ctx => ` ${fmtNum(ctx.raw)} bloqueos`,
                    afterLabel: (ctx) => ` Categoría: ${rows[ctx.dataIndex]?.category || ''}`,
                }},
            },
            scales: {
                x: { ticks: { color: '#64748b' }, grid: { color: 'rgba(0,0,0,0.06)' }, beginAtZero: true },
                y: { ticks: { color: '#64748b', font: { size: 11 } }, grid: { display: false } },
            },
        },
    };
    if (chartTopDomains) chartTopDomains.destroy();
    chartTopDomains = new Chart(document.getElementById('chartTopDomains'), cfg);
}

// ---------------------------------------------------------------
// Top clientes (solo admin)
// ---------------------------------------------------------------
async function loadTopClients() {
    if (!ZT_CONFIG.isAdmin) return;
    const d = await api('top_clients');
    const rows = Array.isArray(d) ? d.slice(0,15) : [];
    const labels  = rows.map(r => r.client_name || r.adguard_client_id);
    const totals  = rows.map(r => parseInt(r.total));
    const blocked = rows.map(r => parseInt(r.blocked));

    const cfg = {
        type: 'bar',
        data: {
            labels,
            datasets: [
                { label: 'Total',     data: totals,  backgroundColor: 'rgba(59,130,246,0.5)', borderRadius: 3 },
                { label: 'Bloqueado', data: blocked, backgroundColor: 'rgba(239,68,68,0.7)',  borderRadius: 3 },
            ],
        },
        options: {
            indexAxis: 'y',
            responsive: true,
            maintainAspectRatio: false,
            plugins: { legend: { labels: { color: '#64748b', font: { size: 11 } } } },
            scales: {
                x: { ticks: { color: '#64748b' }, grid: { color: 'rgba(0,0,0,0.06)' }, stacked: false },
                y: { ticks: { color: '#64748b', font: { size: 11 } }, grid: { display: false } },
            },
        },
    };
    if (chartTopClients) chartTopClients.destroy();
    chartTopClients = new Chart(document.getElementById('chartTopClients'), cfg);
}

// ---------------------------------------------------------------
// Log de consultas (tabla paginada)
// ---------------------------------------------------------------
async function loadLog() {
    const params = {
        page:     logPage,
        limit:    50,
        search:   logFilters.search,
        category: logFilters.category,
        reason:   logFilters.reason,
    };
    const d = await api('logs', params);
    const tbody = document.getElementById('logTableBody');

    if (!d.data || d.data.length === 0) {
        tbody.innerHTML = '<tr><td colspan="6" class="text-center text-secondary py-4">Sin registros para el período seleccionado.</td></tr>';
        document.getElementById('logInfo').textContent = '0 registros';
        document.getElementById('logPagination').innerHTML = '';
        return;
    }

    tbody.innerHTML = d.data.map(r => {
        const isBlocked = r.reason && r.reason.startsWith('Filtered');
        const canExplain = isBlocked && ZT_CONFIG.aiEnabled;
        const domainCell = canExplain
            ? `<a href="#" class="zt-explain-link" data-domain="${r.domain}" data-category="${r.category || ''}" title="¿Qué es ${r.domain}? — Click para explicación">
                   ${r.domain} <i class="bi bi-question-circle ms-1" style="color:#3b82f6"></i>
               </a>`
            : `<span title="${r.domain}">${r.domain}</span>`;
        return `<tr class="${isBlocked ? 'zt-row-blocked' : ''}">
            <td class="text-nowrap" style="font-size:.78rem">${fmtDate(r.log_time)}</td>
            <td class="text-truncate" style="max-width:220px;font-size:.82rem">${domainCell}</td>
            <td><span class="badge bg-secondary" style="font-size:.65rem">${r.query_type || 'A'}</span></td>
            <td>${reasonBadge(r.reason)}</td>
            <td>
                ${r.category ? `<span class="d-flex align-items-center gap-1" style="font-size:.78rem">
                    <span style="width:8px;height:8px;border-radius:50%;background:${r.category_color};flex-shrink:0;display:inline-block"></span>
                    ${r.category}
                </span>` : '<span class="text-secondary">–</span>'}
            </td>
            <td class="text-secondary" style="font-size:.75rem;max-width:180px" title="${r.filter_name || ''}">
                ${r.filter_name ? r.filter_name.slice(0, 30) + (r.filter_name.length > 30 ? '…' : '') : '–'}
            </td>
        </tr>`;
    }).join('');

    const from = (d.current_page - 1) * 50 + 1;
    const to   = Math.min(d.current_page * 50, d.total);
    document.getElementById('logInfo').textContent = `Mostrando ${from}–${to} de ${d.total.toLocaleString('es-AR')} registros`;

    renderPagination(d.current_page, d.pages);
}

function renderPagination(current, total) {
    const ul = document.getElementById('logPagination');
    if (total <= 1) { ul.innerHTML = ''; return; }

    let pages = [];
    if (total <= 7) {
        pages = Array.from({ length: total }, (_, i) => i + 1);
    } else {
        pages = [1];
        if (current > 3) pages.push('…');
        for (let p = Math.max(2, current - 1); p <= Math.min(total - 1, current + 1); p++) pages.push(p);
        if (current < total - 2) pages.push('…');
        pages.push(total);
    }

    ul.innerHTML = `
        <li class="page-item ${current === 1 ? 'disabled' : ''}">
            <a class="page-link zt-page" href="#" data-page="${current - 1}">‹</a>
        </li>
        ${pages.map(p => p === '…'
            ? `<li class="page-item disabled"><span class="page-link">…</span></li>`
            : `<li class="page-item ${p === current ? 'active' : ''}">
                <a class="page-link zt-page" href="#" data-page="${p}">${p}</a>
               </li>`
        ).join('')}
        <li class="page-item ${current === total ? 'disabled' : ''}">
            <a class="page-link zt-page" href="#" data-page="${current + 1}">›</a>
        </li>
    `;
}

// ---------------------------------------------------------------
// Cargar lista de categorías en el filtro del log
// ---------------------------------------------------------------
async function loadCategoryOptions() {
    const d = await api('categories_list');
    const sel = document.getElementById('logCategory');
    if (!Array.isArray(d)) return;
    d.forEach(row => {
        const opt = document.createElement('option');
        opt.value = row.category;
        opt.textContent = row.category;
        sel.appendChild(opt);
    });
}

// ---------------------------------------------------------------
// Placeholder para admin sin cliente seleccionado
// ---------------------------------------------------------------
function _showChartPlaceholder(canvasId) {
    const canvas = document.getElementById(canvasId);
    if (!canvas) return;
    canvas.style.display = 'none';
    const parent = canvas.parentElement;
    if (!parent.querySelector('.zt-no-client')) {
        const ph = document.createElement('div');
        ph.className = 'zt-no-client';
        ph.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;min-height:160px;color:#334155;font-size:.85rem;gap:6px;';
        ph.innerHTML = '<i class="bi bi-person-circle"></i>Seleccioná un cliente arriba';
        parent.appendChild(ph);
    }
}

function _hideChartPlaceholders() {
    document.querySelectorAll('.zt-no-client').forEach(el => el.remove());
    ['chartTimeline','chartCategories','chartTopDomains','chartTopClients'].forEach(id => {
        const c = document.getElementById(id);
        if (c) c.style.display = '';
    });
}

function showAdminPlaceholder() {
    ['statTotalQueries','statTotalBlocked','statBlockRate','statTopCategory'].forEach(id => {
        document.getElementById(id).textContent = '–';
    });
    [chartTimeline, chartCategories, chartTopDomains, chartTopClients].forEach(c => { if (c) c.destroy(); });
    chartTimeline = chartCategories = chartTopDomains = chartTopClients = null;
    _showChartPlaceholder('chartTimeline');
    _showChartPlaceholder('chartCategories');
    _showChartPlaceholder('chartTopDomains');
    _showChartPlaceholder('chartTopClients');
    document.getElementById('logTableBody').innerHTML =
        '<tr><td colspan="6" class="text-center py-5" style="color:#334155"><i class="bi bi-person-circle me-2"></i>Seleccioná un cliente para ver los registros.</td></tr>';
    document.getElementById('logInfo').textContent = '';
    document.getElementById('logPagination').innerHTML = '';
}

// ---------------------------------------------------------------
// Cargar todo
// ---------------------------------------------------------------
function loadAll() {
    if (ZT_CONFIG.isAdmin && !viewUserId) {
        showAdminPlaceholder();
        return;
    }
    _hideChartPlaceholders();
    loadStats();
    loadTimeline();
    loadCategories();
    loadTopDomains();
    if (ZT_CONFIG.isAdmin) loadTopClients();
    logPage = 1;
    loadLog();
}

// ---------------------------------------------------------------
// User switcher (admin only)
// ---------------------------------------------------------------
function loadUserSwitcher() {
    if (!ZT_CONFIG.isAdmin) return;
    const sel = document.getElementById('userSwitcher');
    if (!sel) return;
    (ZT_CONFIG.clientUsers || []).forEach(u => {
        const opt = document.createElement('option');
        opt.value = u.id;
        opt.textContent = u.display_name;
        sel.appendChild(opt);
    });
    // Pre-seleccionar cliente desde URL (persiste al refrescar)
    if (viewUserId) {
        sel.value = viewUserId;
        const topClientsCard = document.querySelector('#chartTopClients')?.closest('.col-12');
        if (topClientsCard) topClientsCard.style.display = 'none';
    }
    sel.addEventListener('change', () => {
        viewUserId = sel.value;
        // Actualizar URL sin recargar para que el F5 vuelva al mismo cliente
        const url = new URL(window.location.href);
        if (viewUserId) url.searchParams.set('view_user', viewUserId);
        else            url.searchParams.delete('view_user');
        history.pushState({}, '', url);
        const topClientsCard = document.querySelector('#chartTopClients')?.closest('.col-12');
        if (topClientsCard) topClientsCard.style.display = viewUserId ? 'none' : '';
        loadAll();
    });
}

// ---------------------------------------------------------------
// Event listeners
// ---------------------------------------------------------------
document.addEventListener('DOMContentLoaded', () => {
    loadCategoryOptions();
    loadUserSwitcher();
    loadAll();

    // Periodo
    document.querySelectorAll('.zt-period-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            document.querySelectorAll('.zt-period-btn').forEach(b => b.classList.remove('active'));
            btn.classList.add('active');
            currentPeriod = btn.dataset.period;
            loadAll();
        });
    });

    // Refresh
    document.getElementById('btnRefresh').addEventListener('click', () => loadAll());

    // Export
    document.getElementById('btnExport').addEventListener('click', () => {
        const params = new URLSearchParams({ period: currentPeriod });
        if (ZT_CONFIG.isAdmin && viewUserId) params.set('view_user', viewUserId);
        window.open('export.php?' + params, '_blank');
    });

    // Filtro del log
    document.getElementById('logApplyFilter').addEventListener('click', () => {
        logFilters.search   = document.getElementById('logSearch').value.trim();
        logFilters.category = document.getElementById('logCategory').value;
        logFilters.reason   = document.getElementById('logReason').value;
        logPage = 1;
        loadLog();
    });

    document.getElementById('logClearFilter').addEventListener('click', () => {
        document.getElementById('logSearch').value = '';
        document.getElementById('logCategory').value = '';
        document.getElementById('logReason').value   = '';
        logFilters = { search: '', category: '', reason: '' };
        logPage = 1;
        loadLog();
    });

    document.getElementById('logSearch').addEventListener('keydown', e => {
        if (e.key === 'Enter') document.getElementById('logApplyFilter').click();
    });

    // Click en dominio bloqueado → modal de explicación (delegated)
    document.getElementById('logTableBody').addEventListener('click', e => {
        const link = e.target.closest('.zt-explain-link');
        if (!link) return;
        e.preventDefault();
        showExplainModal(link.dataset.domain, link.dataset.category || '');
    });

    // Paginación (delegated)
    document.getElementById('logPagination').addEventListener('click', e => {
        const a = e.target.closest('.zt-page');
        if (!a) return;
        e.preventDefault();
        const p = parseInt(a.dataset.page);
        if (p && p !== logPage) { logPage = p; loadLog(); }
    });

    // Auto-refresh cada 5 minutos
    setInterval(() => loadAll(), 5 * 60 * 1000);
});
