<?php
/**
 * Log de Actividad — Trazabilidad del Módulo Administrativo de Laboratorio
 */
require_once 'config/config.php';
if (!defined('APP_ROOT')) { define('APP_ROOT', __DIR__); }

if (!isUserLoggedIn()) { header('Location: login.php'); exit; }
if (isEnfermero())     { header('Location: enfermero_portal.php'); exit; }

$adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['username'] ?? 'Admin';
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Log de Actividad — Módulo Lab</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="./assets/css/styles.css?v=12" rel="stylesheet">
    <style>
        .log-row td { font-size: .85rem; vertical-align: middle; }
        .detalle-cell { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
        .detalle-cell:hover { text-decoration: underline dotted; color: #0d6efd; }
        .badge-accion { font-size: .72rem; }
        .ctrl { height: 31px; }
    </style>
</head>
<body>

<?php
$SIDEBAR_TITLE = 'Panel Lab';
$SIDEBAR_ICON  = 'fas fa-flask';
require_once __DIR__ . '/shared/components/sidebar.php';
?>

<main class="main-content">
    <header class="content-header d-flex align-items-center justify-content-between">
        <div>
            <h1><i class="fas fa-history text-primary"></i> Log de Actividad</h1>
            <small class="text-muted"><?= htmlspecialchars($adminNombre) ?></small>
        </div>
        <button class="btn btn-success btn-sm" onclick="exportarCSV()">
            <i class="fas fa-file-csv me-1"></i> Exportar CSV
        </button>
    </header>

    <div class="container-fluid py-3">

        <!-- Filtros -->
        <div class="card border-0 shadow-sm mb-3">
            <div class="card-body py-2">
                <div class="row g-2 align-items-end">
                    <div class="col-auto">
                        <label class="form-label mb-0 small fw-semibold">Desde</label>
                        <input type="date" id="act-desde" class="form-control form-control-sm ctrl">
                    </div>
                    <div class="col-auto">
                        <label class="form-label mb-0 small fw-semibold">Hasta</label>
                        <input type="date" id="act-hasta" class="form-control form-control-sm ctrl">
                    </div>
                    <div class="col-auto">
                        <label class="form-label mb-0 small fw-semibold">Módulo</label>
                        <select id="act-modulo" class="form-select form-select-sm ctrl">
                            <option value="">Todos</option>
                            <option value="ordenes">Órdenes</option>
                            <option value="domicilios">Domicilios</option>
                            <option value="pacientes">Pacientes</option>
                            <option value="enfermeras">Enfermeras</option>
                            <option value="formularios">Formularios</option>
                            <option value="asignaciones">Asignaciones</option>
                            <option value="turnero">Turnero</option>
                            <option value="turnero_config">Turnero · configuración</option>
                        </select>
                    </div>
                    <div class="col-auto">
                        <label class="form-label mb-0 small fw-semibold">Acción</label>
                        <select id="act-accion" class="form-select form-select-sm ctrl">
                            <option value="">Todas</option>
                            <option value="crear">crear</option>
                            <option value="editar">editar</option>
                            <option value="eliminar">eliminar</option>
                            <option value="autorizar">autorizar</option>
                            <option value="rechazar">rechazar</option>
                            <option value="asignar">asignar</option>
                            <option value="enviar">enviar</option>
                            <option value="reprogramar">reprogramar</option>
                            <option value="cambiar_estado">cambiar_estado</option>
                            <option value="quitar_consentimiento">quitar_consentimiento</option>
                            <option value="resetear_consentimiento">resetear_consentimiento</option>
                            <option value="resetear_toma">resetear_toma</option>
                            <option value="cancelar_toma_pendiente">cancelar_toma_pendiente</option>
                            <option value="vincular_paciente">vincular_paciente</option>
                        </select>
                    </div>
                    <div class="col">
                        <label class="form-label mb-0 small fw-semibold">Buscar</label>
                        <input type="text" id="act-buscar" class="form-control form-control-sm ctrl" placeholder="Usuario o detalle…">
                    </div>
                    <div class="col-auto d-flex gap-2">
                        <button class="btn btn-primary btn-sm ctrl" onclick="cargar(1)">
                            <i class="fas fa-search"></i>
                        </button>
                        <button class="btn btn-outline-secondary btn-sm ctrl" onclick="limpiar()">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Tabla -->
        <!-- Salud de la voz del televisor: alimentada por turnero_tv_log.
             Responde de un vistazo «¿la pantalla está llamando bien?» sin
             tener que consultar la base a mano. -->
        <div class="card border-0 shadow-sm mb-3" id="card-voz-tv" style="display:none">
            <div class="card-body py-3">
                <h6 class="mb-2"><i class="fas fa-volume-up text-primary me-1"></i>
                    Voz del televisor — últimos 7 días</h6>
                <div class="d-flex gap-4 flex-wrap mb-2" id="voz-tv-resumen"></div>
                <div id="voz-tv-incidentes" class="small"></div>
            </div>
        </div>

        <div class="card border-0 shadow-sm">
            <div class="card-body p-0">
                <div id="act-spinner" class="text-center py-5 text-muted">
                    <i class="fas fa-spinner fa-spin fa-2x"></i>
                </div>
                <div id="act-wrap" class="d-none">
                    <table class="table table-hover table-sm mb-0">
                        <thead class="table-light">
                            <tr>
                                <th style="width:145px">Fecha / Hora</th>
                                <th>Usuario</th>
                                <th style="width:110px">Módulo</th>
                                <th style="width:120px">Acción</th>
                                <th style="width:70px" class="text-center">Entidad</th>
                                <th>Detalle</th>
                                <th style="width:105px">IP</th>
                            </tr>
                        </thead>
                        <tbody id="act-tbody"></tbody>
                    </table>
                </div>
                <div id="act-empty" class="d-none text-center py-5 text-muted">
                    <i class="fas fa-history fa-2x mb-2 d-block opacity-25"></i>
                    Sin actividad para los filtros seleccionados
                </div>
            </div>
            <div class="card-footer bg-white" id="act-footer"></div>
        </div>

    </div><!-- /container -->
</main>

<!-- Modal detalle -->
<div class="modal fade" id="modalDetalle" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><i class="fas fa-info-circle me-2 text-primary"></i>Detalle del evento</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <pre id="modal-detalle-pre" class="bg-light p-3 rounded small mb-0" style="white-space:pre-wrap;word-break:break-all;max-height:420px;overflow-y:auto"></pre>
            </div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
const MODULO_COLOR = {
    ordenes:'warning', domicilios:'success', pacientes:'primary',
    enfermeras:'info', formularios:'secondary', asignaciones:'dark',
};
const ACCION_COLOR = {
    crear:'success', editar:'primary', eliminar:'danger',
    autorizar:'success', rechazar:'danger', asignar:'info',
    enviar:'secondary', reprogramar:'warning', cambiar_estado:'primary',
};

let _actPag  = 1;
let _actData = [];
let _debounce;

document.addEventListener('DOMContentLoaded', () => {
    const hoy = new Date().toISOString().slice(0,10);
    document.getElementById('act-desde').value = hoy.slice(0,7) + '-01';
    document.getElementById('act-hasta').value = hoy;

    ['act-desde','act-hasta','act-modulo','act-accion'].forEach(id =>
        document.getElementById(id).addEventListener('change', () => cargar(1))
    );
    document.getElementById('act-buscar').addEventListener('input', () => {
        clearTimeout(_debounce);
        _debounce = setTimeout(() => cargar(1), 400);
    });

    cargar(1);
});

async function cargar(pag = 1) {
    _actPag = pag;
    document.getElementById('act-spinner').classList.remove('d-none');
    document.getElementById('act-wrap').classList.add('d-none');
    document.getElementById('act-empty').classList.add('d-none');

    const params = new URLSearchParams({
        desde:  document.getElementById('act-desde').value,
        hasta:  document.getElementById('act-hasta').value,
        modulo: document.getElementById('act-modulo').value,
        accion: document.getElementById('act-accion').value,
        buscar: document.getElementById('act-buscar').value,
        page:   pag,
        limit:  50,
    });

    try {
        const r = await fetch(`api/lab/get_actividad.php?${params}`);
        const d = await r.json();
        document.getElementById('act-spinner').classList.add('d-none');

        if (!d.data?.length) {
            document.getElementById('act-empty').classList.remove('d-none');
            document.getElementById('act-footer').innerHTML = '';
            return;
        }
        _actData = d.data;
        renderTabla(d.data);
        renderPaginacion(d.total, d.paginas, pag);
    } catch(e) {
        document.getElementById('act-spinner').classList.add('d-none');
        document.getElementById('act-empty').classList.remove('d-none');
    }
}

function renderTabla(rows) {
    document.getElementById('act-wrap').classList.remove('d-none');
    document.getElementById('act-tbody').innerHTML = rows.map((a, i) => {
        const det      = a.detalle || '';
        const detShort = det.length > 70 ? det.slice(0,70) + '…' : det;
        const mColor   = MODULO_COLOR[a.modulo]  || 'secondary';
        const aColor   = ACCION_COLOR[a.accion]  || 'secondary';
        const usuario  = esc(a.admin_nombre || a.admin_username || 'Sistema');
        const sub      = (a.admin_username && a.admin_nombre)
            ? `<div class="text-muted" style="font-size:.74rem">@${esc(a.admin_username)}</div>` : '';
        return `<tr class="log-row">
            <td class="text-muted text-nowrap">${formatFecha(a.created_at)}</td>
            <td><span class="fw-semibold">${usuario}</span>${sub}</td>
            <td><span class="badge bg-${mColor} badge-accion">${esc(a.modulo)}</span></td>
            <td><span class="badge bg-${aColor} bg-opacity-75 badge-accion text-dark">${esc(a.accion)}</span></td>
            <td class="text-center text-muted">${a.entidad_id ? '#' + a.entidad_id : '—'}</td>
            <td class="detalle-cell" onclick="verDetalle(${i})" title="Click para ver detalle completo">${esc(detShort) || '<span class="text-muted">—</span>'}</td>
            <td class="text-muted small">${esc(a.ip_address || '—')}</td>
        </tr>`;
    }).join('');
}

function renderPaginacion(total, paginas, pag) {
    const el = document.getElementById('act-footer');
    if (paginas <= 1) {
        el.innerHTML = `<small class="text-muted">${total} evento(s)</small>`;
        return;
    }
    const pages = [];
    for (let p = Math.max(1, pag - 2); p <= Math.min(paginas, pag + 2); p++) pages.push(p);
    el.innerHTML = `
        <div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
            <small class="text-muted">${total} evento(s) — página ${pag} de ${paginas}</small>
            <div class="btn-group btn-group-sm">
                <button class="btn btn-outline-secondary" onclick="cargar(1)" ${pag===1?'disabled':''}>«</button>
                <button class="btn btn-outline-secondary" onclick="cargar(${pag-1})" ${pag===1?'disabled':''}>‹</button>
                ${pages.map(p => `<button class="btn ${p===pag?'btn-primary':'btn-outline-secondary'}" onclick="cargar(${p})">${p}</button>`).join('')}
                <button class="btn btn-outline-secondary" onclick="cargar(${pag+1})" ${pag>=paginas?'disabled':''}>›</button>
                <button class="btn btn-outline-secondary" onclick="cargar(${paginas})" ${pag>=paginas?'disabled':''}>»</button>
            </div>
        </div>`;
}

function verDetalle(i) {
    const a = _actData[i];
    let det = a.detalle || '(sin detalle)';
    try { det = JSON.stringify(JSON.parse(det), null, 2); } catch(e) {}
    document.getElementById('modal-detalle-pre').textContent =
        `Módulo:  ${a.modulo}\nAcción:  ${a.accion}\nEntidad: ${a.entidad_id ? '#' + a.entidad_id : '—'}\nUsuario: ${a.admin_nombre || a.admin_username || 'Sistema'}\nFecha:   ${a.created_at}\nIP:      ${a.ip_address || '—'}\n\nDetalle:\n${det}`;
    new bootstrap.Modal(document.getElementById('modalDetalle')).show();
}

// ── Salud de la voz del televisor ────────────────────────────
const VOZ_EVENTO_TXT = {
    mudo:      ['🔇 No sonó',            'text-danger',  'El llamado salió sin voz: ni el reintento habló'],
    sin_start: ['⚠️ Arrancó con reintento','text-warning','La voz elegida no arrancó; habló la del navegador'],
    error:     ['⚠️ Error del motor',     'text-warning', 'El motor de voz falló a mitad; se reintentó'],
    lag:       ['⏸ Pantalla congelada',   'text-warning', 'La pestaña estuvo oculta o el equipo suspendido: en ese lapso no ve llamados. En el televisor debe estar siempre visible'],
};

async function cargarVozTV() {
    try {
        const r = await fetch('api/lab/get_tv_log.php');
        const d = await r.json();
        if (!d.ok) return;
        // Sin datos todavía (recién desplegado): la tarjeta no aparece
        if (!d.anuncios_7d && !d.incidentes.length) return;

        document.getElementById('card-voz-tv').style.display = '';
        const pct = d.anuncios_7d ? Math.round(d.completos_7d / d.anuncios_7d * 100) : 0;
        document.getElementById('voz-tv-resumen').innerHTML = `
            <div><span class="fw-bold fs-5">${d.anuncios_7d}</span>
                 <span class="text-muted small">llamados con voz</span></div>
            <div><span class="fw-bold fs-5 ${pct >= 97 ? 'text-success' : 'text-warning'}">${pct}%</span>
                 <span class="text-muted small">hablados completos</span></div>
            <div><span class="fw-bold fs-5 ${d.mudos_7d ? 'text-danger' : 'text-success'}">${d.mudos_7d}</span>
                 <span class="text-muted small">salieron mudos</span></div>
            <div><span class="fw-bold fs-5 ${d.avisos_7d ? 'text-warning' : 'text-success'}">${d.avisos_7d}</span>
                 <span class="text-muted small">se recuperaron con reintento</span></div>`;

        const inc = document.getElementById('voz-tv-incidentes');
        if (!d.incidentes.length) {
            inc.innerHTML = '<span class="text-success"><i class="fas fa-check-circle me-1"></i>Sin fallos registrados</span>';
            return;
        }
        inc.innerHTML = '<div class="text-muted mb-1">Últimos fallos:</div>' +
            d.incidentes.slice(0, 10).map(i => {
                const [txt, cls, ayuda] = VOZ_EVENTO_TXT[i.evento] || [i.evento, '', ''];
                return `<div class="py-1 border-bottom" title="${ayuda}">
                    <span class="text-muted">${(i.cuando || '').slice(0, 16)}</span>
                    · turno <b>${i.turno || '—'}</b>
                    · <span class="${cls}">${txt}</span>
                    ${i.voz ? `<span class="text-muted"> (voz: ${i.voz})</span>` : ''}
                </div>`;
            }).join('');
    } catch (_) {}
}
cargarVozTV();

async function exportarCSV() {
    const params = new URLSearchParams({
        desde:  document.getElementById('act-desde').value,
        hasta:  document.getElementById('act-hasta').value,
        modulo: document.getElementById('act-modulo').value,
        accion: document.getElementById('act-accion').value,
        buscar: document.getElementById('act-buscar').value,
        page:   1,
        limit:  2000,
    });
    const r = await fetch(`api/lab/get_actividad.php?${params}`);
    const d = await r.json();
    if (!d.data?.length) { alert('Sin datos para exportar'); return; }

    const cols = ['id','created_at','admin_nombre','admin_username','modulo','accion','entidad_id','detalle','ip_address'];
    const rows = d.data.map(a =>
        cols.map(c => '"' + String(a[c] ?? '').replace(/"/g, '""') + '"').join(',')
    );
    const csv  = '\uFEFF' + [cols.join(','), ...rows].join('\r\n');
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const url  = URL.createObjectURL(blob);
    const a    = document.createElement('a');
    a.href = url;
    a.download = `actividad_${new Date().toISOString().slice(0,10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
}

function limpiar() {
    const hoy = new Date().toISOString().slice(0,10);
    document.getElementById('act-desde').value = hoy.slice(0,7) + '-01';
    document.getElementById('act-hasta').value = hoy;
    document.getElementById('act-modulo').value = '';
    document.getElementById('act-accion').value = '';
    document.getElementById('act-buscar').value = '';
    cargar(1);
}

const esc        = s => String(s||'').replace(/[<>&"]/g, c => ({'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c]));
const formatFecha = s => s ? new Date(s).toLocaleString('es-CO', {day:'2-digit',month:'short',year:'numeric',hour:'2-digit',minute:'2-digit'}) : '—';
</script>
</body>
</html>
