<?php
/**
 * modules/turnero/views/dashboard.php
 * Panel de resumen diario del Turnero.
 * Carga datos vía fetch a get_dashboard.php (permite cambiar fecha sin recargar).
 */
require_once APP_ROOT . '/config/config.php';
if (!isUserLoggedIn()) { header('Location: ' . BASE_URL . 'login.php'); exit; }

// Tablet asignada → no tiene acceso al dashboard, ir a su lugar
if (!empty($_SESSION['turnero_dispositivo'])) {
    $_d = $_SESSION['turnero_dispositivo'];
    header('Location: ' . BASE_URL . ($_d['tipo'] === 'recepcion'
        ? 'erp.php?m=turnero&v=recepcion&desk_id=' . $_d['lugar_id']
        : 'erp.php?m=turnero&v=lugar&lugar_id='    . $_d['lugar_id']));
    exit;
}

$_iaActiva = false;
$_liaTokensUsados = 0;
try {
    $_db   = Database::getInstance();
    $_cfgIA = $_db->fetch("SELECT valor FROM lab_config WHERE clave = 'ia_activa'");
    $_iaActiva = ($_cfgIA['valor'] ?? '0') === '1';
    $_liaTok = $_db->fetch("SELECT valor FROM lab_config WHERE clave = 'lia_tokens_usados'");
    $_liaTokensUsados = (int)($_liaTok['valor'] ?? 0);
} catch (\Throwable $_) {}

Layout::open('Dashboard Turnero', 'fas fa-chart-bar');
?>
<style>
        body { background:#f1f5f9; }
        .page-header {
            background:#fff; border-bottom:1px solid #e2e8f0;
            padding:14px 24px; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
        }
        .page-header h1 { font-size:1.18rem; font-weight:700; color:#1e293b; margin:0; flex:1; }
        .page-header .back-btn { color:#64748b; text-decoration:none; font-size:.9rem; }
        .content-wrap { max-width:1100px; margin:24px auto; padding:0 16px 48px; }

        /* ── KPI cards ── */
        .kpi-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:14px; margin-bottom:24px; }
        .kpi-card {
            background:#fff; border:1px solid #e2e8f0; border-radius:12px;
            padding:16px 18px; text-align:center;
        }
        .kpi-card .kpi-val { font-size:2rem; font-weight:800; line-height:1.1; }
        .kpi-card .kpi-lbl { font-size:.72rem; text-transform:uppercase; letter-spacing:.07em; color:#64748b; margin-top:4px; }
        .kpi-card .kpi-sub { font-size:.75rem; color:#94a3b8; margin-top:2px; }
    .kpi-ayuda { font-size:.62rem; color:#94a3b8; line-height:1.3; margin-top:5px;
                 border-top:1px solid #f1f5f9; padding-top:5px; }

        /* ── Charts / tables section ── */
        .section-card { background:#fff; border:1px solid #e2e8f0; border-radius:12px; padding:20px; margin-bottom:20px; }
        .section-title { font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:#64748b; margin:0 0 14px; }

        /* ── Priority bar ── */
        .pri-row { display:flex; align-items:center; gap:8px; margin-bottom:8px; }
        .pri-dot  { width:10px; height:10px; border-radius:50%; flex-shrink:0; }
        .pri-name { width:160px; font-size:.82rem; color:#334155; }
        .pri-bar-wrap { flex:1; background:#f1f5f9; border-radius:99px; height:10px; overflow:hidden; }
        .pri-bar-fill { height:100%; border-radius:99px; transition:width .5s; }
        .pri-nums { font-size:.78rem; color:#64748b; white-space:nowrap; }

        /* ── Lugar cards ── */
        .lugar-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:12px; }
        .lugar-card { border:1px solid #e2e8f0; border-radius:10px; padding:14px; }
        .lugar-card .lc-name { font-weight:600; font-size:.9rem; color:#1e293b; margin-bottom:8px; }
        .lugar-card .lc-row  { display:flex; justify-content:space-between; font-size:.8rem; color:#475569; margin-bottom:4px; }
        .lugar-card .lc-row span:last-child { font-weight:600; color:#0f172a; }

        /* ── Tabla de turnos ── */
        .estado-badge { font-size:.65rem; padding:2px 7px; border-radius:99px; font-weight:600; white-space:nowrap; }
        .eb-espera          { background:#fef9c3; color:#92400e; }
        .eb-en_recepcion    { background:#dbeafe; color:#1e40af; }
        .eb-en_espera_lugar { background:#fde68a; color:#92400e; }
        .eb-en_servicio     { background:#dcfce7; color:#166534; }
        .eb-finalizado      { background:#f1f5f9; color:#475569; }
        .eb-ausente         { background:#fee2e2; color:#991b1b; }
        .eb-cancelado       { background:#f1f5f9; color:#9ca3af; }
        .row-expandible { cursor:pointer; transition:background .15s; }
        .row-expandible:hover { background: color-mix(in srgb, var(--brand,#1565c0) 5%, #fff) !important; }
        .row-expandible.det-open { background: color-mix(in srgb, var(--brand,#1565c0) 8%, #fff) !important; }
        .det-row { border-top:none !important; }
        .det-row td { padding:0 !important; border-top:none !important; }
        .det-inner { padding:12px 16px 14px; border-top:2px solid color-mix(in srgb, var(--brand,#1565c0) 20%, #e2e8f0); background:#f8fafc; }

        /* ── Origen de cada nota ── */
        .com-tipo { font-size:.62rem; font-weight:700; letter-spacing:.04em; padding:1px 7px;
                    border-radius:10px; text-transform:uppercase; margin-right:6px; }
        .com-tipo.recepcion { background:#dbeafe; color:#1d4ed8; }
        .com-tipo.muestras  { background:#dcfce7; color:#15803d; }
        .com-tipo.general   { background:#fef3c7; color:#92400e; }

        /* ── Sesión badge ── */
        .sesion-open   { background:#dcfce7; color:#15803d; }
        .sesion-closed { background:#f1f5f9; color:#64748b; }

        /* ── Spinner / empty ── */
        #loadingOverlay { min-height:180px; display:flex; align-items:center; justify-content:center; }
        .empty-msg { color:#94a3b8; font-size:.9rem; text-align:center; padding:40px 0; }

        /* ── Panel LIA ── */
        #aiPanel {
            position:fixed; bottom:0; right:24px; width:400px; z-index:1080;
            box-shadow:0 -8px 40px rgba(0,0,0,.22); border-radius:20px 20px 0 0;
            background:#fff; border:1px solid #e2e8f0; border-bottom:none;
            transform:translateY(100%); transition:transform .35s cubic-bezier(.4,0,.2,1);
            display:flex; flex-direction:column; max-height:580px;
        }
        #aiPanel.open { transform:translateY(0); }
        #aiPanel.minimized .ai-body { display:none; }
        #aiPanel.minimized { max-height:none; }
        .ai-header {
            background:linear-gradient(135deg,#0d47a1,#1565c0,#0288d1);
            color:#fff; padding:14px 18px; border-radius:20px 20px 0 0;
            display:flex; align-items:center; gap:12px; flex-shrink:0; cursor:pointer; user-select:none;
        }
        .lia-logo {
            width:44px; height:44px; border-radius:50%;
            background:rgba(255,255,255,.15); border:2px solid rgba(255,255,255,.4);
            display:flex; align-items:center; justify-content:center;
            font-size:1rem; font-weight:900; letter-spacing:-1px; flex-shrink:0;
            transition:transform .3s;
        }
        .lia-logo:hover { transform:scale(1.08); }
        .lia-logo .lia-i { color:#7dd3fc; }
        .lia-logo.speaking { animation:lia-pulse 1s infinite; }
        @keyframes lia-pulse { 0%,100%{box-shadow:0 0 0 0 rgba(255,255,255,.4)} 50%{box-shadow:0 0 0 8px rgba(255,255,255,0)} }
        .ai-title { font-weight:800; font-size:1.05rem; letter-spacing:.5px; }
        .ai-header .btn-close { filter:invert(1) brightness(2); opacity:.7; }
        .ai-header .btn-close:hover { opacity:1; }
        .btn-tts { background:rgba(255,255,255,.15); border:1px solid rgba(255,255,255,.3); color:rgba(255,255,255,.7); cursor:pointer; padding:5px 9px; border-radius:8px; font-size:.88rem; transition:all .2s; }
        .btn-tts.active { background:rgba(255,255,255,.25); color:#fff; }
        .ai-body { display:flex; flex-direction:column; flex:1; overflow:hidden; }
        .ai-quick { display:flex; gap:7px; flex-wrap:wrap; padding:10px 14px; border-bottom:1px solid #f1f5f9; flex-shrink:0; background:#fafbff; }
        .ai-chip { background:#fff; border:1.5px solid #e2e8f0; border-radius:99px; padding:6px 13px; font-size:.82rem; cursor:pointer; color:#334155; white-space:nowrap; transition:all .15s; font-weight:500; }
        .ai-chip:hover { background:#eff6ff; border-color:#93c5fd; color:#1d4ed8; }
        .ai-messages { flex:1; overflow-y:auto; padding:14px 16px; display:flex; flex-direction:column; gap:10px; }
        .ai-msg { max-width:92%; padding:10px 14px; border-radius:16px; font-size:.9rem; line-height:1.55; animation:msg-in .2s ease; }
        @keyframes msg-in { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:none} }
        .ai-msg.user { background:linear-gradient(135deg,#1565c0,#0288d1); color:#fff; align-self:flex-end; border-radius:16px 16px 2px 16px; }
        .ai-msg.bot  { background:#f1f5f9; color:#1e293b; align-self:flex-start; border-radius:16px 16px 16px 2px; }
        .ai-msg.bot.typing::after { content:'●●●'; animation:dots 1.2s infinite; letter-spacing:2px; }
        @keyframes dots { 0%,100%{opacity:.3} 50%{opacity:1} }
        .ai-msg.bot strong { color:#1565c0; }
        .ai-msg.bot ul { margin:4px 0 4px 16px; padding:0; }
        .lia-wave { display:flex; align-items:center; justify-content:center; gap:4px; height:32px; }
        .lia-wave span { width:4px; border-radius:2px; background:#1565c0; animation:wave .8s infinite ease-in-out; }
        .lia-wave span:nth-child(1){height:8px;animation-delay:0s}
        .lia-wave span:nth-child(2){height:16px;animation-delay:.1s}
        .lia-wave span:nth-child(3){height:24px;animation-delay:.2s}
        .lia-wave span:nth-child(4){height:16px;animation-delay:.3s}
        .lia-wave span:nth-child(5){height:8px;animation-delay:.4s}
        @keyframes wave { 0%,100%{transform:scaleY(.5);opacity:.6} 50%{transform:scaleY(1);opacity:1} }
        .lia-tokens { padding:6px 14px; background:#f8faff; border-top:1px solid #f1f5f9; flex-shrink:0; }
        .lia-tokens-bar { height:5px; border-radius:3px; background:#e2e8f0; overflow:hidden; margin-bottom:3px; }
        .lia-tokens-fill { height:100%; border-radius:3px; background:linear-gradient(90deg,#1565c0,#0288d1); transition:width .6s ease; }
        .lia-tokens-fill.warn { background:linear-gradient(90deg,#f59e0b,#ef4444); }
        .lia-tokens-label { font-size:.68rem; color:#94a3b8; display:flex; justify-content:space-between; }
        .ai-footer { padding:10px 14px; border-top:1px solid #f1f5f9; display:flex; gap:8px; flex-shrink:0; background:#fafbff; }
        .ai-footer input { flex:1; border:1.5px solid #e2e8f0; border-radius:10px; padding:9px 14px; font-size:.9rem; outline:none; background:#fff; }
        .ai-footer input:focus { border-color:#1565c0; }
        .btn-mic { background:#fff; border:1.5px solid #e2e8f0; border-radius:10px; padding:9px 13px; cursor:pointer; color:#64748b; font-size:.88rem; transition:all .2s; min-width:42px; }
        .btn-mic.listening { background:#fee2e2; color:#dc2626; border-color:#fca5a5; }
        .ai-footer .btn-send { background:linear-gradient(135deg,#1565c0,#0288d1); color:#fff; border:none; border-radius:10px; padding:9px 16px; cursor:pointer; font-size:.88rem; min-width:42px; }
        #btnAI {
            position:fixed; bottom:24px; right:24px; z-index:1079;
            background:linear-gradient(135deg,#0d47a1,#1565c0,#0288d1);
            color:#fff; border:none; border-radius:50%; width:58px; height:58px;
            font-size:.78rem; font-weight:900; letter-spacing:-.5px;
            cursor:pointer; box-shadow:0 4px 20px rgba(21,101,192,.45);
            transition:transform .2s,box-shadow .2s;
            display:flex; align-items:center; justify-content:center;
        }
        #btnAI:hover { transform:scale(1.1); box-shadow:0 6px 28px rgba(21,101,192,.55); }
        #btnAI.hidden { display:none; }
        @media(max-width:600px) { #aiPanel { width:100%; right:0; border-radius:16px 16px 0 0; } }
</style>

<?php
$_dashRole    = $_SESSION['admin_user']['role'] ?? 'admin';
$_dashIsAdmin = in_array($_dashRole, ['superadmin', 'admin', 'supervisor'], true);
$_dashIsRecep = $_dashRole === 'recepcionista';
$_dashIsBacte = $_dashRole === 'bacteriologo';

$_dashReceps   = [];
$_dashMuestras = [];
try {
    $_pdo = Database::getInstance()->getConnection();
    if ($_dashIsAdmin || $_dashIsRecep)
        $_dashReceps   = $_pdo->query("SELECT id, nombre FROM turnero_lugares WHERE activo=1 AND tipo='recepcion' ORDER BY sort_order")->fetchAll(PDO::FETCH_ASSOC);
    if ($_dashIsAdmin || $_dashIsBacte)
        $_dashMuestras = $_pdo->query("SELECT id, nombre FROM turnero_lugares WHERE activo=1 AND tipo='muestras'  ORDER BY sort_order")->fetchAll(PDO::FETCH_ASSOC);
} catch (\Throwable $_) {}
?>
<div class="page-header">
    <h1><i class="fas fa-chart-bar me-2 text-primary"></i>Dashboard Turnero</h1>

    <!-- Accesos rápidos: dropdown por grupo, filtrado por rol -->
    <?php if (!empty($_dashReceps)): ?>
    <div class="dropdown">
        <button class="btn btn-sm btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown">
            <i class="fas fa-concierge-bell me-1"></i>Recepción
        </button>
        <ul class="dropdown-menu shadow-sm">
            <?php foreach ($_dashReceps as $_r): ?>
            <li><a class="dropdown-item" href="<?= BASE_URL ?>erp.php?m=turnero&v=recepcion&desk_id=<?= (int)$_r['id'] ?>">
                <i class="fas fa-chair me-1 text-primary"></i><?= htmlspecialchars($_r['nombre'], ENT_QUOTES) ?>
            </a></li>
            <?php endforeach; ?>
        </ul>
    </div>
    <?php endif; ?>

    <?php if (!empty($_dashMuestras)): ?>
    <div class="dropdown">
        <button class="btn btn-sm btn-outline-success dropdown-toggle" type="button" data-bs-toggle="dropdown">
            <i class="fas fa-flask me-1"></i>Toma de Muestras
        </button>
        <ul class="dropdown-menu shadow-sm">
            <?php foreach ($_dashMuestras as $_m): ?>
            <li><a class="dropdown-item" href="<?= BASE_URL ?>erp.php?m=turnero&v=lugar&lugar_id=<?= (int)$_m['id'] ?>">
                <i class="fas fa-vial me-1 text-success"></i><?= htmlspecialchars($_m['nombre'], ENT_QUOTES) ?>
            </a></li>
            <?php endforeach; ?>
        </ul>
    </div>
    <?php endif; ?>

    <!-- Selector de fecha -->
    <div class="d-flex align-items-center gap-2 ms-auto">
        <label class="small fw-semibold text-muted mb-0">Fecha:</label>
        <input type="date" id="fechaInput" class="form-control form-control-sm" style="width:150px"
               value="<?= date('Y-m-d') ?>" max="<?= date('Y-m-d') ?>">
    </div>
    <button class="btn btn-outline-success btn-sm" id="btnExport" title="Exportar CSV del día">
        <i class="fas fa-file-csv me-1"></i>CSV
    </button>
    <button class="btn btn-outline-success btn-sm" id="btnExcel" title="Exportar Excel del día">
        <i class="fas fa-file-excel me-1"></i>Excel
    </button>
    <button class="btn btn-outline-success btn-sm" id="btnWAInforme" title="Enviar informe por WhatsApp" data-bs-toggle="modal" data-bs-target="#modalWAInforme">
        <i class="fab fa-whatsapp me-1"></i>Informe WA
    </button>
    <button class="btn btn-outline-secondary btn-sm" onclick="cargarDatos()" title="Refrescar">
        <i class="fas fa-sync-alt"></i>
    </button>
    <a href="<?= BASE_URL ?>erp.php?m=turnero&v=configuracion" class="btn btn-outline-secondary btn-sm">
        <i class="fas fa-cogs"></i>
    </a>
</div>

<div class="content-wrap">
    <!-- Estado sesión -->
    <div id="sesionInfo" class="mb-3 small text-muted"></div>

    <!-- KPIs -->
    <div class="kpi-grid" id="kpiGrid">
        <div id="loadingOverlay" class="col-span-full">
            <div class="text-center text-muted"><i class="fas fa-spinner fa-spin me-2"></i>Cargando...</div>
        </div>
    </div>

    <!-- Proyección de ventas -->
    <div class="section-card" id="sectionProyeccion" style="display:none">
        <div class="d-flex align-items-center justify-content-between mb-2">
            <div class="section-title mb-0"><i class="fas fa-chart-line me-1"></i>Facturación del día</div>
            <span id="proyeccionResumen" class="small text-muted"></span>
        </div>
        <canvas id="chartProyeccion" height="90"></canvas>
    </div>

    <!-- Consentimientos (solo si hay) -->
    <div class="section-card" id="sectionConsent" style="display:none">
        <div class="section-title"><i class="fas fa-file-signature me-1"></i>Consentimientos del día</div>
        <div id="consentKpis" class="d-flex gap-4 flex-wrap"></div>
    </div>

    <!-- Desglose por prioridad -->
    <div class="section-card" id="sectionPrioridad" style="display:none">
        <div class="section-title"><i class="fas fa-sort-amount-up me-1"></i>Por prioridad</div>
        <div id="barrasPrioridad"></div>
    </div>

    <!-- Desglose por lugar -->
    <div class="section-card" id="sectionLugar" style="display:none">
        <div class="section-title"><i class="fas fa-map-marker-alt me-1"></i>Por lugar / estación</div>
        <div class="lugar-grid" id="lugarGrid"></div>
    </div>

    <!-- Desglose por recepcionista -->
    <div class="section-card" id="sectionRecepcionista" style="display:none">
        <div class="section-title"><i class="fas fa-user-check me-1"></i>Por recepcionista</div>
        <div class="lugar-grid" id="recepcionistaGrid"></div>
    </div>

    <!-- Desglose por bacteriólogo -->
    <div class="section-card" id="sectionBacteriologo" style="display:none">
        <div class="section-title"><i class="fas fa-user-nurse me-1"></i>Por bacteriólogo</div>
        <div class="lugar-grid" id="bacteriologoGrid"></div>
    </div>

    <!-- Tabla detalle de turnos -->
    <div class="section-card">
        <div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
            <div class="section-title mb-0"><i class="fas fa-list me-1"></i>Detalle de turnos</div>
            <input type="text" id="filtroBusqueda" class="form-control form-control-sm"
                   style="max-width:260px" placeholder="Buscar paciente, código o cédula…">
        </div>
        <div class="table-responsive">
            <table class="table table-sm table-hover small align-middle" id="tablaTurnos">
                <thead class="table-light">
                    <tr>
                        <th>Código</th>
                        <th>Prioridad</th>
                        <th>Paciente</th>
                        <th>Recepción</th>
                        <th>Lugar / Bacteriólogo</th>
                        <th>Exámenes</th>
                        <th>Estado</th>
                        <th>Espera</th>
                        <th>Serv.</th>
                        <th>Total</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody id="tbodyTurnos">
                    <tr><td colspan="10" class="empty-msg">Cargando...</td></tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

<?php if ($_iaActiva): ?>
<!-- ── Botón flotante IA ── -->
<button id="btnAI" title="Abrir LIA - Asistente Inteligente" onclick="toggleAI()">
    L<span style="color:#7dd3fc">I</span>A
</button>

<!-- ── Modal informe WA ── -->
<div class="modal fade" id="modalWAInforme" tabindex="-1">
    <div class="modal-dialog modal-sm">
        <div class="modal-content">
            <div class="modal-header"><h5 class="modal-title"><i class="fab fa-whatsapp me-2 text-success"></i>Enviar informe por WA</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <label class="form-label small fw-semibold">Número WhatsApp (con código país)</label>
                <input type="tel" id="waInformePhone" class="form-control" placeholder="573001234567">
                <div class="form-text">Ej: 573001234567 (57 = Colombia)</div>
                <div id="waInformeMsg" class="mt-2 small"></div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-success" onclick="enviarInformeWA()"><i class="fab fa-whatsapp me-1"></i>Enviar</button>
            </div>
        </div>
    </div>
</div>

<!-- ── Panel IA ── -->
<div id="aiPanel">
    <div class="ai-header" onclick="minimizarIA(event)">
        <div class="lia-logo" id="liaLogo">
            <span>L</span><span class="lia-i">I</span><span>A</span>
        </div>
        <div style="flex:1;line-height:1.1">
            <div class="ai-title">LIA</div>
            <div style="font-size:.68rem;opacity:.75;font-weight:400">Asistente Inteligente del Lab.</div>
        </div>
        <button id="btnTTS" class="btn-tts" onclick="event.stopPropagation();toggleTTS()" title="Activar/silenciar voz">
            <i class="fas fa-volume-up"></i>
        </button>
        <button class="btn-tts" onclick="event.stopPropagation();minimizarIA(event)" title="Minimizar" id="btnMin">
            <i class="fas fa-minus" id="iconMin"></i>
        </button>
        <button class="btn-close" onclick="event.stopPropagation();toggleAI()"></button>
    </div>
    <div class="ai-body" id="aiBody">
        <div class="ai-quick" id="aiQuick">
            <button class="ai-chip" onclick="enviarRapido('¿Cuántos pacientes atendidos hoy y cuántos faltan?')">📊 Resumen</button>
            <button class="ai-chip" onclick="enviarRapido('¿Cuánto se ha facturado hoy?')">💰 Facturación</button>
            <button class="ai-chip" onclick="enviarRapido('¿Cuáles son los tiempos promedio de hoy?')">⏱ Tiempos</button>
            <button class="ai-chip" onclick="enviarRapido('¿Cuántos pacientes están en espera ahora mismo?')">⏳ En espera</button>
        </div>
        <div class="ai-messages" id="aiMessages"></div>
        <div class="lia-tokens" id="liaTokensBar">
            <div class="lia-tokens-bar"><div class="lia-tokens-fill" id="liaFill" style="width:0%"></div></div>
            <div class="lia-tokens-label">
                <span id="liaTokensUsed">0 tokens usados</span>
                <span id="liaTokensLeft">1.000.000 restantes</span>
            </div>
        </div>
        <div id="liaListening" style="display:none;text-align:center;padding:10px 0">
            <div class="lia-wave"><span></span><span></span><span></span><span></span><span></span></div>
            <div style="font-size:.75rem;color:#64748b;margin-top:4px">Escuchando…</div>
        </div>
        <div class="ai-footer">
            <input type="text" id="aiInput" placeholder="Escribe o habla con LIA…" maxlength="400"
                   onkeydown="if(event.key==='Enter')enviarIA()">
            <button class="btn-mic" id="btnMic" onclick="iniciarVoz()" title="Hablar"><i class="fas fa-microphone"></i></button>
            <button class="btn-send" onclick="enviarIA()"><i class="fas fa-paper-plane"></i></button>
        </div>
    </div>
</div>
<?php endif; ?>

<script>
/* ═══════════════════════════════════════════════════════════
   Dashboard Turnero
   ═══════════════════════════════════════════════════════════ */
const API      = '<?= BASE_URL ?>modules/turnero/api/';
const BASE_WA  = '<?= BASE_URL ?>';
let _turnos    = [];   // cache para búsqueda local
let _autoReloadId = null;
let _liaHistorial = [];  // últimos intercambios con LIA (contexto de seguimiento)

// ── Entrada ──────────────────────────────────────────────────
document.addEventListener('DOMContentLoaded', () => {
    cargarDatos();
    document.getElementById('fechaInput').addEventListener('change', () => {
        cargarDatos();
        cargarProyeccion(document.getElementById('fechaInput').value);
    });
    document.getElementById('filtroBusqueda').addEventListener('input', filtrarTabla);
    document.getElementById('btnExport').addEventListener('click', exportarCSV);
    document.getElementById('btnExcel').addEventListener('click', exportarExcel);
    cargarProyeccion(document.getElementById('fechaInput').value);

    // Auto-refresh cada 30s solo si la fecha es hoy
    _autoReloadId = setInterval(() => {
        const hoy = new Date().toISOString().slice(0, 10);
        if (document.getElementById('fechaInput').value === hoy) cargarDatos();
    }, 30000);
});

// ── Carga principal ──────────────────────────────────────────
async function cargarDatos() {
    const fecha = document.getElementById('fechaInput').value;
    document.getElementById('kpiGrid').innerHTML =
        '<div id="loadingOverlay"><div class="text-center text-muted"><i class="fas fa-spinner fa-spin me-2"></i>Cargando...</div></div>';
    document.getElementById('sesionInfo').textContent = '';

    try {
        const res  = await fetch(`${API}get_dashboard.php?fecha=${fecha}`);
        const json = await res.json();
        if (!json.ok) { mostrarError(json.error || 'Error'); return; }
        renderDashboard(json);
    } catch (e) {
        mostrarError('Error de conexión');
    }
}

function mostrarError(msg) {
    document.getElementById('kpiGrid').innerHTML =
        `<div class="empty-msg text-danger"><i class="fas fa-exclamation-circle me-1"></i>${escHtml(msg)}</div>`;
}

// ── Render ───────────────────────────────────────────────────
function renderDashboard(json) {
    const { sesion, resumen, por_prioridad, por_lugar, consent_stats = {}, turnos,
            por_recepcionista = [], por_bacteriologo = [] } = json;

    // ── Sesión info ────────────────────────────────────────
    const si = document.getElementById('sesionInfo');
    if (!sesion) {
        si.innerHTML = '<span class="badge bg-secondary-subtle text-secondary">Sin sesión para este día</span>';
    } else {
        const cls = sesion.abierta ? 'bg-success-subtle text-success' : 'bg-secondary-subtle text-secondary';
        const est = sesion.abierta ? 'Abierta' : 'Cerrada';
        si.innerHTML = `<span class="badge ${cls} me-2">${est}</span>
            <span>Inicio: <strong>${sesion.inicio || '—'}</strong></span>
            ${sesion.fin ? ` &bull; Cierre: <strong>${sesion.fin}</strong>` : ''}`;
    }

    // ── KPIs ───────────────────────────────────────────────
    const total     = parseInt(resumen.total         || 0);
    const atendidos = parseInt(resumen.atendidos      || 0);
    const enEspera  = parseInt(resumen.en_espera      || 0);
    const ausentes  = parseInt(resumen.ausentes       || 0);
    const cancelados= parseInt(resumen.cancelados     || 0);
    const tEspera   = resumen.tiempo_espera_promedio_min;
    const tServicio = resumen.tiempo_servicio_promedio_min;
    const tTotal    = resumen.tiempo_total_promedio_min;
    const pct       = total > 0 ? Math.round(atendidos / total * 100) : 0;

    document.getElementById('kpiGrid').innerHTML = `
        ${kpiCard(total, '📋 Turnos del día', '',
            'Todos los turnos generados hoy, sin importar cómo terminaron.')}
        ${kpiCard(atendidos, '✅ Atendidos', pct + ' % del día',
            'Ya terminaron su atención, más los que están siendo atendidos en este momento.')}
        ${kpiCard(enEspera, '⏳ Esperando', '',
            'Todavía no los llaman, o ya salieron de recepción y esperan el puesto de toma.')}
        ${kpiCard(ausentes, '🚫 No se presentaron', '',
            'Se les llamó y no llegaron. Recepción registra el motivo al marcarlos.')}
        ${kpiCard(cancelados, '❌ Cancelados', '',
            'Turnos anulados antes de atenderlos.')}
        ${kpiCard(tEspera !== null ? tEspera + ' min' : '—', '⏱ Espera para recepción', 'sacar el turno → lo llaman',
            'Cuánto aguarda el paciente sentado desde que saca el turno hasta que recepción lo atiende.')}
        ${kpiCard(tServicio !== null ? tServicio + ' min' : '—', '⏱ Tiempo en el puesto', 'toma de muestras',
            'Lo que dura la toma. En protocolos prolongados (curvas) se cuenta hasta la primera toma: las horas de espera del examen no son trabajo del puesto.')}
        ${kpiCard(tTotal !== null ? tTotal + ' min' : '—', '⏱ Total en el laboratorio', 'llegada → salida',
            'Todo el recorrido: espera + recepción + espera del puesto + toma. Por eso es mayor que la suma de las dos casillas anteriores.')}
    `;

    // ── Consentimientos ────────────────────────────────────
    const totalConsent = Object.values(consent_stats).reduce((a,b)=>a+(+b),0);
    const secCons = document.getElementById('sectionConsent');
    if (totalConsent > 0) {
        secCons.style.display = '';
        const labels = { pendiente:'Pendientes', enviado:'Enviados', visto:'Vistos', firmado:'Firmados', rechazado:'Rechazados' };
        const colors = { pendiente:'#fef9c3', enviado:'#dbeafe', visto:'#e0f2fe', firmado:'#dcfce7', rechazado:'#fee2e2' };
        const tcolors= { pendiente:'#92400e', enviado:'#1e40af', visto:'#0369a1', firmado:'#166534', rechazado:'#991b1b' };
        document.getElementById('consentKpis').innerHTML =
            Object.entries(consent_stats).map(([est, cnt]) =>
                `<div style="text-align:center">
                    <div style="font-size:1.5rem;font-weight:800;color:${tcolors[est]||'#0f172a'}">${cnt}</div>
                    <div style="font-size:.7rem;color:#64748b;text-transform:uppercase;letter-spacing:.05em">${labels[est]||est}</div>
                </div>`
            ).join('');
    } else {
        secCons.style.display = 'none';
    }

    // ── Barras por prioridad ───────────────────────────────
    const secPri = document.getElementById('sectionPrioridad');
    if (por_prioridad.length) {
        secPri.style.display = '';
        const maxTotal = Math.max(...por_prioridad.map(p => +p.total), 1);
        document.getElementById('barrasPrioridad').innerHTML = por_prioridad.map(p => {
            const pct2 = Math.round(+p.total / maxTotal * 100);
            return `<div class="pri-row">
                <div class="pri-dot" style="background:${p.color}"></div>
                <div class="pri-name">${escHtml(p.codigo + ' – ' + p.nombre)}</div>
                <div class="pri-bar-wrap">
                    <div class="pri-bar-fill" style="width:${pct2}%;background:${p.color}"></div>
                </div>
                <div class="pri-nums">${p.total} (✅${p.atendidos} ⏳${p.pendientes} 🚫${p.ausentes})</div>
            </div>`;
        }).join('');
    } else {
        secPri.style.display = 'none';
    }

    // ── Tarjetas por lugar ─────────────────────────────────
    const secLug = document.getElementById('sectionLugar');
    if (por_lugar.length) {
        secLug.style.display = '';
        document.getElementById('lugarGrid').innerHTML = por_lugar.map(l => `
            <div class="lugar-card">
                <div class="lc-name"><i class="fas fa-map-marker-alt text-primary me-1"></i>${escHtml(l.lugar)}</div>
                <div class="lc-row"><span>Total</span><span>${l.total}</span></div>
                <div class="lc-row"><span>Atendidos</span><span>${l.atendidos}</span></div>
                <div class="lc-row"><span>En espera</span><span>${l.en_espera}</span></div>
                <div class="lc-row"><span>T. servicio prom.</span><span>${l.tiempo_servicio_promedio_min !== null ? l.tiempo_servicio_promedio_min + ' min' : '—'}</span></div>
            </div>`).join('');
    } else {
        secLug.style.display = 'none';
    }

    // ── Tarjetas por persona ───────────────────────────────
    renderPersonas('sectionRecepcionista', 'recepcionistaGrid', por_recepcionista, [
        ['Turnos',            p => p.total],
        ['Atendidos',         p => p.atendidos],
        ['Ausentes',          p => p.ausentes],
        ['T. recepción prom.', p => p.tiempo_promedio_min !== null ? p.tiempo_promedio_min + ' min' : '—'],
    ]);

    renderPersonas('sectionBacteriologo', 'bacteriologoGrid', por_bacteriologo, [
        ['Turnos',           p => p.total],
        ['Finalizados',      p => p.finalizados],
        ['En servicio',      p => p.en_servicio],
        ['T. servicio prom.', p => p.tiempo_promedio_min !== null ? p.tiempo_promedio_min + ' min' : '—'],
    ]);

    // ── Tabla de turnos ────────────────────────────────────
    _turnos = turnos;
    renderTabla(turnos);
}

// Tarjetas "quién atendió a cuántos". Reutiliza el grid de lugares para que
// las tres secciones se vean iguales.
function renderPersonas(sectionId, gridId, filas, columnas) {
    const sec = document.getElementById(sectionId);
    if (!filas || !filas.length) { sec.style.display = 'none'; return; }
    sec.style.display = '';
    document.getElementById(gridId).innerHTML = filas.map(p => `
        <div class="lugar-card">
            <div class="lc-name"><i class="fas fa-user text-primary me-1"></i>${escHtml(p.nombre || '—')}</div>
            ${columnas.map(([lbl, val]) =>
                `<div class="lc-row"><span>${lbl}</span><span>${escHtml(String(val(p) ?? '—'))}</span></div>`
            ).join('')}
        </div>`).join('');
}

function kpiCard(val, lbl, sub, ayuda) {
    // `ayuda` explica de dónde sale el número. Las etiquetas cortas se prestan
    // para malentendidos —«servicio» no es lo mismo que «tiempo en el
    // laboratorio»— y quien lee el tablero no tiene por qué adivinarlo.
    const t = ayuda ? ` title="${escHtml(ayuda)}"` : '';
    return `<div class="kpi-card"${t}>
        <div class="kpi-val">${val !== null && val !== undefined ? escHtml(String(val)) : '—'}</div>
        <div class="kpi-lbl">${lbl}</div>
        ${sub ? `<div class="kpi-sub">${escHtml(sub)}</div>` : ''}
        ${ayuda ? `<div class="kpi-ayuda">${escHtml(ayuda)}</div>` : ''}
    </div>`;
}

// ── Tabla detalle ─────────────────────────────────────────────
function renderTabla(turnos) {
    const tbody = document.getElementById('tbodyTurnos');
    if (!turnos.length) {
        tbody.innerHTML = '<tr><td colspan="8" class="empty-msg">Sin turnos para este día</td></tr>';
        return;
    }
    const mapEstado = {
        espera: 'eb-espera',
        en_recepcion: 'eb-en_recepcion',
        en_espera_lugar: 'eb-en_espera_lugar',
        en_servicio: 'eb-en_servicio',
        finalizado: 'eb-finalizado',
        ausente: 'eb-ausente',
        cancelado: 'eb-cancelado',
    };
    const labelEstado = {
        espera: 'Espera', en_recepcion: 'Recepción', en_espera_lugar: 'Esp. lugar',
        en_servicio: 'En servicio', finalizado: 'Finalizado', ausente: 'Ausente', cancelado: 'Cancelado',
    };
    tbody.innerHTML = turnos.map(t => {
        const nombrePac = escHtml(t.paciente_bd || t.paciente_nombre || '—');
        const docPac    = t.paciente_doc ? `<div class="text-muted" style="font-size:.7rem">${escHtml(t.paciente_tipo_doc||'CC')} ${escHtml(t.paciente_doc)}</div>` : '';
        const estadoCls = mapEstado[t.estado]   || 'eb-finalizado';
        const estadoLbl = labelEstado[t.estado] || t.estado;
        const espMin    = t.espera_min    !== null ? t.espera_min    + ' m' : '—';
        const srvMin    = t.servicio_min  !== null ? t.servicio_min  + ' m' : '—';
        const totMin    = t.total_min     !== null ? t.total_min     + ' m' : '—';
        const rowId     = `dash-det-${t.id}`;

        // Recepción
        const desk  = escHtml(t.recepcion_desk_nombre || '—');
        const recep = escHtml(t.atendido_recepcion_nombre || '—');
        const recepCell = `<div>${desk}</div><div class="text-muted" style="font-size:.7rem">${recep}</div>`;

        // Lugar + bacteriólogo
        const lugar    = escHtml(t.lugar_nombre || '—');
        const bacterio = escHtml(t.atendido_lugar_nombre || '—');
        const lugarCell = `<div>${lugar}</div><div class="text-muted" style="font-size:.7rem">${bacterio}</div>`;

        // Exámenes
        const examsHtml = (t.examenes && t.examenes.length)
            ? t.examenes.map(e => `<span class="badge" style="background:#dcfce7;color:#166534;font-size:.6rem;margin:1px">${escHtml(e.nombre||e.codigo||'')}</span>`).join('')
            : '<span class="text-muted small">—</span>';

        return `<tr class="row-expandible" onclick="toggleDashDetalle('${rowId}', this)">
            <td><span class="fw-bold" style="color:${escHtml(t.prioridad_color || '#333')}">${escHtml(t.codigo)}</span></td>
            <td><span class="estado-badge" style="background:${escHtml(t.prioridad_color+'22'||'#eee')};color:${escHtml(t.prioridad_color||'#333')}">${escHtml(t.prioridad_codigo)}</span></td>
            <td>${nombrePac}${docPac}</td>
            <td>${recepCell}</td>
            <td>${lugarCell}</td>
            <td style="max-width:120px">${examsHtml}</td>
            <td><span class="estado-badge ${estadoCls}">${estadoLbl}</span></td>
            <td>${espMin}</td>
            <td>${srvMin}</td>
            <td>${totMin}</td>
            <td><i class="fas fa-chevron-right" style="font-size:.65rem;color:#94a3b8;transition:transform .2s" id="ico-${t.id}"></i></td>
        </tr>
        <tr id="${rowId}" class="det-row" style="display:none">
            <td colspan="10">
                <div class="det-inner">${renderDashDetalle(t)}</div>
            </td>
        </tr>`;
    }).join('');
}

function toggleDashDetalle(rowId, tr) {
    const det = document.getElementById(rowId);
    if (!det) return;
    const open  = det.style.display !== 'none';
    det.style.display = open ? 'none' : '';
    tr.classList.toggle('det-open', !open);
    // rotar ícono
    const turnoId = rowId.replace('dash-det-', '');
    const ico = document.getElementById(`ico-${turnoId}`);
    if (ico) ico.style.transform = open ? 'rotate(0deg)' : 'rotate(90deg)';
}

function renderDashDetalle(t) {
    const e = s => escHtml(s || '—');
    const fmt = dt => dt ? new Date(dt.replace(' ','T')).toLocaleString('es-CO',{dateStyle:'short',timeStyle:'short'}) : '—';

    const chips = [
        { lbl:'Recepción (desk)',   val: e(t.recepcion_desk_nombre) },
        { lbl:'Atendió recepción',  val: e(t.atendido_recepcion_nombre) },
        { lbl:'Atendió muestras',   val: e(t.atendido_lugar_nombre) },
        { lbl:'Inicio recepción',   val: fmt(t.inicio_recepcion_at) },
        { lbl:'Fin recepción',      val: fmt(t.fin_recepcion_at) },
        { lbl:'Inicio servicio',    val: fmt(t.inicio_lugar_at) },
        { lbl:'Fin servicio',       val: fmt(t.fin_lugar_at) },
    ];

    let grid = `<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:8px;margin-bottom:10px">
        ${chips.map(c=>`<div style="background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:7px 11px">
            <div style="font-size:.63rem;text-transform:uppercase;letter-spacing:.07em;color:#94a3b8">${c.lbl}</div>
            <div style="font-size:.82rem;font-weight:600;color:#1e293b">${c.val}</div>
        </div>`).join('')}
    </div>`;

    // Notas
    if (t.notas) {
        grid += `<div style="margin-bottom:8px;font-size:.82rem"><span style="font-size:.67rem;text-transform:uppercase;letter-spacing:.07em;color:#94a3b8">📝 Notas: </span>${e(t.notas)}</div>`;
    }

    // Exámenes
    if (t.examenes && t.examenes.length) {
        grid += `<div style="margin-bottom:8px">
            <span style="font-size:.67rem;text-transform:uppercase;letter-spacing:.07em;color:#94a3b8"><i class="fas fa-vials me-1"></i>Exámenes (${t.examenes.length}): </span>
            ${t.examenes.map(ex=>`<span class="badge" style="background:#dcfce7;color:#166534;margin:1px 2px">${e(ex.nombre)}</span>`).join('')}
        </div>`;
    }

    // Comentarios
    if (t.comentarios && t.comentarios.length) {
        grid += `<div style="border-top:1px solid #e2e8f0;padding-top:8px">
            <div style="font-size:.67rem;text-transform:uppercase;letter-spacing:.07em;color:#94a3b8;margin-bottom:5px"><i class="fas fa-comments me-1"></i>Notas y observaciones (${t.comentarios.length})</div>
            ${t.comentarios.map(c=>`<div style="font-size:.8rem;padding:4px 0;border-bottom:1px solid #f1f5f9">
                <span class="com-tipo ${e(c.tipo||'general')}">${({recepcion:'Recepción',muestras:'Toma de muestras',general:'General'})[c.tipo]||c.tipo}</span>
                <strong>${e(c.usuario_nombre)}</strong>
                <span style="color:#94a3b8;font-size:.72rem;margin-left:6px">${fmt(c.creado_at)}</span>
                <div style="color:#475569">${e(c.comentario)}</div>
            </div>`).join('')}
        </div>`;
    }

    return grid;
}

function filtrarTabla() {
    const q = document.getElementById('filtroBusqueda').value.toLowerCase().trim();
    if (!q) { renderTabla(_turnos); return; }
    renderTabla(_turnos.filter(t =>
        (t.codigo            || '').toLowerCase().includes(q) ||
        (t.paciente_bd       || '').toLowerCase().includes(q) ||
        (t.paciente_nombre   || '').toLowerCase().includes(q) ||
        (t.paciente_doc      || '').toLowerCase().includes(q)
    ));
}

// ── Asistente IA ──────────────────────────────────────────────
let _aiOpen = false;

// ── LIA helpers ──────────────────────────────────────────────
let _aiMinimized = false;
let _ttsOn       = false;
let _recog       = null;
let _chartProy   = null;
const _LIA_TOKENS_USADOS = <?= (int)$_liaTokensUsados ?>;
const _LIA_TOKENS_MAX    = 1_000_000;

function _actualizarTokens(usados, max) {
    const pct  = Math.min(100, (usados / max) * 100);
    const left = max - usados;
    const fill = document.getElementById('liaFill');
    const fmt  = n => Intl.NumberFormat('es-CO').format(n);
    fill.style.width = pct + '%';
    fill.className   = 'lia-tokens-fill' + (pct > 80 ? ' warn' : '');
    document.getElementById('liaTokensUsed').textContent = fmt(usados) + ' tokens usados';
    document.getElementById('liaTokensLeft').textContent = fmt(left) + ' restantes';
    if (left <= 0) _bloquearLIA();
}

function _bloquearLIA() {
    document.getElementById('aiInput').disabled = true;
    document.getElementById('btnMic').disabled  = true;
    document.getElementById('btnMic').style.opacity = '.4';
    const msgs = document.getElementById('aiMessages');
    const el = document.createElement('div');
    el.className = 'ai-msg bot';
    el.innerHTML = '⚠️ <strong>Se agotaron los tokens de LIA.</strong><br>Solicita tokens a soporte para continuar.';
    msgs.appendChild(el);
    msgs.scrollTop = msgs.scrollHeight;
    hablarIA('Se agotaron los tokens de LIA. Solicita tokens a soporte para continuar.');
}

function mdToHtml(md) {
    let s = md
        .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
        .replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>')
        .replace(/^\* (.+)$/gm,'<li>$1</li>');
    s = s.replace(/((?:<li>[^]*?<\/li>\n?)+)/g,
        m => `<ul style="margin:4px 0 4px 14px;padding:0;list-style:disc">${m.replace(/\n/g,'')}</ul>`);
    return s.replace(/\n/g,'<br>');
}

function _stripMd(text) {
    return text.replace(/\*\*(.+?)\*\*/g,'$1').replace(/^\* /gm,'').replace(/\n/g,' ');
}

function _vozFemenina() {
    const vs = window.speechSynthesis.getVoices();
    return vs.find(v => v.lang.startsWith('es') && /female|mujer|paulina|sabina|monica|helena|lucia|penelope|conchita|paloma|maria|carmen/i.test(v.name))
        || vs.find(v => v.lang.startsWith('es') && !v.name.toLowerCase().includes('male'))
        || vs.find(v => v.lang.startsWith('es'))
        || null;
}

function hablarIA(text) {
    if (!_ttsOn || !window.speechSynthesis) return;
    window.speechSynthesis.cancel();
    const utt = new SpeechSynthesisUtterance(_stripMd(text));
    utt.lang = 'es-CO'; utt.rate = 1.05;
    const v = _vozFemenina(); if (v) utt.voice = v;
    window.speechSynthesis.speak(utt);
}

function toggleTTS() {
    _ttsOn = !_ttsOn;
    document.getElementById('btnTTS').classList.toggle('active', _ttsOn);
    if (!_ttsOn) window.speechSynthesis?.cancel();
}

function iniciarVoz(autoEnviar = true) {
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SR) { alert('Tu navegador no soporta reconocimiento de voz (usa Chrome)'); return; }
    const btn = document.getElementById('btnMic');
    if (_recog) { _recog.stop(); return; }
    _recog = new SR();
    _recog.lang = 'es-CO'; _recog.interimResults = false;
    btn.classList.add('listening');
    document.getElementById('liaListening').style.display = 'block';
    _recog.onresult = e => {
        const texto = e.results[0][0].transcript;
        document.getElementById('aiInput').value = texto;
        if (autoEnviar) enviarIA();
    };
    _recog.onend  = () => {
        btn.classList.remove('listening');
        document.getElementById('liaListening').style.display = 'none';
        _recog = null;
    };
    _recog.onerror= () => {
        btn.classList.remove('listening');
        document.getElementById('liaListening').style.display = 'none';
        _recog = null;
    };
    _recog.start();
}

function enviarRapido(pregunta) {
    document.getElementById('aiInput').value = pregunta;
    document.getElementById('aiQuick').style.display = 'none';
    enviarIA();
}

function minimizarIA(e) {
    if (e && e.target && e.target.closest && e.target.closest('button:not(#btnMin)')) return;
    _aiMinimized = !_aiMinimized;
    document.getElementById('aiPanel').classList.toggle('minimized', _aiMinimized);
    const icon = document.getElementById('iconMin');
    if (icon) icon.className = _aiMinimized ? 'fas fa-chevron-up' : 'fas fa-minus';
}

function _liaGreet() {
    const hoy   = new Date().toISOString().slice(0,10);
    const llave = 'lia_greeted_' + hoy;
    if (localStorage.getItem(llave)) return;
    localStorage.setItem(llave, '1');
    const msg = 'Hola, soy LIA. ¿En qué te puedo asistir hoy?';
    const msgs = document.getElementById('aiMessages');
    const el = document.createElement('div');
    el.className = 'ai-msg bot';
    el.textContent = msg;
    msgs.appendChild(el);
    msgs.scrollTop = msgs.scrollHeight;
    document.getElementById('liaLogo').classList.add('speaking');
    hablarIA(msg);
    // Auto-escuchar 3 segundos después del saludo
    setTimeout(() => {
        document.getElementById('liaLogo').classList.remove('speaking');
        const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
        if (SR) {
            const btn = document.getElementById('btnMic');
            btn.classList.add('listening');
            document.getElementById('liaListening').style.display = 'block';
            const r = new SR();
            r.lang = 'es-CO'; r.interimResults = false;
            let oyo = false;
            r.onresult = e => {
                oyo = true;
                document.getElementById('aiInput').value = e.results[0][0].transcript;
                enviarIA();
            };
            r.onend = () => {
                btn.classList.remove('listening');
                document.getElementById('liaListening').style.display = 'none';
                if (!oyo) {
                    // no habló — mostrar hint
                    const h = document.createElement('div');
                    h.className = 'ai-msg bot';
                    h.innerHTML = 'Toca 🎤 para hablar o escribe tu pregunta.';
                    document.getElementById('aiMessages').appendChild(h);
                    document.getElementById('aiMessages').scrollTop = 99999;
                }
            };
            r.onerror = () => { btn.classList.remove('listening'); document.getElementById('liaListening').style.display = 'none'; };
            setTimeout(() => r.start(), 3000); // esperar que el TTS termine
            setTimeout(() => { try { r.stop(); } catch(_){} }, 9000); // max 6s de escucha
        }
    }, 100);
}

function toggleAI() {
    _aiOpen = !_aiOpen;
    if (!_aiOpen) { _aiMinimized = false; document.getElementById('aiPanel').classList.remove('minimized'); }
    document.getElementById('aiPanel').classList.toggle('open', _aiOpen);
    document.getElementById('btnAI').classList.toggle('hidden', _aiOpen);
    if (_aiOpen && !_aiMinimized) {
        document.getElementById('aiInput').focus();
        setTimeout(_liaGreet, 400);
        _actualizarTokens(_LIA_TOKENS_USADOS, _LIA_TOKENS_MAX);
    }
}

async function enviarIA() {
    const input = document.getElementById('aiInput');
    const pregunta = input.value.trim();
    if (!pregunta) return;

    const msgs = document.getElementById('aiMessages');
    msgs.insertAdjacentHTML('beforeend',
        `<div class="ai-msg user">${escHtml(pregunta)}</div>`);
    const typing = document.createElement('div');
    typing.className = 'ai-msg bot typing';
    typing.textContent = 'Pensando…';
    msgs.appendChild(typing);
    msgs.scrollTop = msgs.scrollHeight;
    input.value = '';
    input.disabled = true;

    try {
        const res = await fetch(`${API}ai_chat.php`, {
            method: 'POST',
            headers: {'Content-Type':'application/json'},
            body: JSON.stringify({ pregunta, historial: _liaHistorial }),
        });
        const d = await res.json();
        typing.className = 'ai-msg bot';
        if (d.ok) {
            typing.innerHTML = mdToHtml(d.respuesta);
            hablarIA(d.respuesta);
            // Guardar el intercambio para que las preguntas de seguimiento tengan contexto
            _liaHistorial.push({ rol: 'user', texto: pregunta });
            _liaHistorial.push({ rol: 'model', texto: d.respuesta });
            if (_liaHistorial.length > 8) _liaHistorial = _liaHistorial.slice(-8);
            if (d.tokens_max) _actualizarTokens(d.tokens_usados, d.tokens_max);
        } else {
            typing.textContent = d.error || 'Error al conectar con la IA';
            if (d.status === 402 || (d.error && d.error.includes('agotaron'))) _bloquearLIA();
        }
    } catch(_) {
        typing.className = 'ai-msg bot';
        typing.textContent = 'Error de conexión';
    } finally {
        input.disabled = false;
        input.focus();
        msgs.scrollTop = msgs.scrollHeight;
    }
}

// ── Exportar CSV / Excel ──────────────────────────────────────
function exportarCSV() {
    const fecha = document.getElementById('fechaInput').value;
    window.location.href = `${API}export_csv.php?fecha=${fecha}`;
}
function exportarExcel() {
    const fecha = document.getElementById('fechaInput').value;
    window.location.href = `${API}export_excel.php?fecha=${fecha}`;
}

// ── Informe por WhatsApp ──────────────────────────────────────
async function enviarInformeWA() {
    const phone = (document.getElementById('waInformePhone').value || '').replace(/\D/g,'');
    const msg   = document.getElementById('waInformeMsg');
    if (!phone || phone.length < 7) { msg.innerHTML = '<span class="text-danger">Número inválido</span>'; return; }
    msg.innerHTML = '<span class="text-muted"><i class="fas fa-spinner fa-spin me-1"></i>Enviando…</span>';
    try {
        const res  = await fetch(`${API}enviar_informe_dia.php`, {
            method:'POST', headers:{'Content-Type':'application/json'},
            body: JSON.stringify({ phone })
        });
        const d = await res.json();
        msg.innerHTML = d.ok
            ? `<span class="text-success"><i class="fas fa-check me-1"></i>${d.mensaje}</span>`
            : `<span class="text-danger">${d.error}</span>`;
    } catch(_) { msg.innerHTML = '<span class="text-danger">Error de conexión</span>'; }
}

// ── Gráfica proyección ─────────────────────────────────────────
async function cargarProyeccion(fecha) {
    const sec = document.getElementById('sectionProyeccion');
    try {
        const r = await fetch(`${API}get_proyeccion.php?fecha=${fecha}`);
        const d = await r.json();
        if (!d.ok || !d.labels.length) { sec.style.display = 'none'; return; }
        sec.style.display = '';
        const fmt = v => v == null ? null : '$' + Intl.NumberFormat('es-CO').format(v);
        document.getElementById('proyeccionResumen').textContent =
            `Facturado: ${fmt(d.total_real)} (${d.turnos_finalizados} finalizados)`
            + `  ·  En proceso: ${fmt(d.total_en_proceso)} (${d.turnos_en_proceso})`
            + `  ·  Total estimado: ${fmt(d.total_proyectado)}`;
        const ctx = document.getElementById('chartProyeccion').getContext('2d');
        if (_chartProy) _chartProy.destroy();
        _chartProy = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: d.labels,
                datasets: [
                    {
                        label: 'Facturado',
                        data: d.real,
                        backgroundColor: 'rgba(21,101,192,.75)',
                        borderRadius: 6,
                    },
                    {
                        label: 'En proceso',
                        data: d.proyectado,
                        backgroundColor: 'rgba(245,158,11,.55)',
                        borderRadius: 6,
                    }
                ]
            },
            options: {
                responsive: true,
                plugins: {
                    legend: { position:'top', labels:{ font:{size:12} } },
                    tooltip: {
                        callbacks: { label: ctx => ' $' + Intl.NumberFormat('es-CO').format(ctx.raw ?? 0) }
                    }
                },
                scales: {
                    y: {
                        ticks: { callback: v => '$' + Intl.NumberFormat('es-CO',{notation:'compact'}).format(v) }
                    }
                }
            }
        });
    } catch(_) { sec.style.display = 'none'; }
}

// ── Helper ───────────────────────────────────────────────────
function escHtml(str) {
    const d = document.createElement('div');
    d.appendChild(document.createTextNode(String(str ?? '')));
    return d.innerHTML;
}
</script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<?php Layout::close(); ?>
