<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>Cuentas Canceladas — ARKHON</title>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
<style>
:root{
  --bg:#f7f8fc;--surface:#fff;--border:#eaecf4;
  --text:#111827;--text-2:#4b5563;--text-3:#9ca3af;
  --orange:#f97316;--orange-lt:rgba(249,115,22,.10);
  --green:#10b981;--green-lt:rgba(16,185,129,.10);
  --red:#ef4444;--red-lt:rgba(239,68,68,.10);
  --shadow-sm:0 1px 3px rgba(17,24,39,.06);--r:10px;
}
*{margin:0;padding:0;box-sizing:border-box;}
html,body{font-family:'Plus Jakarta Sans',sans-serif;background:var(--bg);color:var(--text);min-height:100vh;font-size:13px;-webkit-font-smoothing:antialiased;}
button,input,select{font-family:'Plus Jakarta Sans',sans-serif;}
::-webkit-scrollbar{width:4px;}::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:8px;}
@keyframes spin{to{transform:rotate(360deg);}}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:translateY(0);}}
@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.4;}}

.topbar{background:var(--surface);border-bottom:1px solid var(--border);height:58px;padding:0 20px;display:flex;align-items:center;gap:12px;box-shadow:var(--shadow-sm);position:sticky;top:0;z-index:20;}
.topbar-icon{width:34px;height:34px;border-radius:9px;flex-shrink:0;background:var(--red);display:flex;align-items:center;justify-content:center;box-shadow:0 3px 10px rgba(239,68,68,.28);}
.topbar-icon svg{width:16px;height:16px;stroke:#fff;stroke-width:2.2;fill:none;}
.topbar h1{font-size:15px;font-weight:800;color:var(--text);letter-spacing:-.3px;flex:1;}
.live-chip{display:none;align-items:center;gap:5px;padding:4px 10px;background:var(--green-lt);border-radius:20px;font-size:10px;font-weight:700;color:var(--green);}
.live-chip.show{display:flex;}
.live-dot{width:6px;height:6px;border-radius:50%;background:var(--green);animation:pulse 1.5s infinite;}

.container{max-width:1000px;margin:0 auto;padding:18px 18px 40px;}

#live-banner{display:none;background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--green);border-radius:var(--r);padding:12px 16px;margin-bottom:12px;box-shadow:var(--shadow-sm);animation:fadeUp .2s ease;}
#live-banner.show{display:flex;align-items:center;gap:10px;}
.live-banner-dot{width:8px;height:8px;border-radius:50%;background:var(--green);animation:pulse 1.5s infinite;flex-shrink:0;}

.mode-tabs{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap;}
.mode-tab{padding:7px 16px;border-radius:8px;border:1.5px solid var(--border);font-size:12px;font-weight:700;cursor:pointer;background:var(--surface);color:var(--text-2);transition:.15s;}
.mode-tab.active{background:var(--orange);border-color:var(--orange);color:#fff;}
.mode-tab.live-tab{border-color:var(--green);color:var(--green);}
.mode-tab.live-tab.active{background:var(--green);border-color:var(--green);color:#fff;}

.filters-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow-sm);padding:14px 18px;margin-bottom:14px;display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;}
.fg{display:flex;flex-direction:column;gap:3px;}
.fl{font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);}
input[type=date]{padding:7px 10px;border:1px solid var(--border);border-radius:8px;font-size:12px;font-weight:600;color:var(--text);outline:none;transition:.15s;background:var(--surface);}
input:focus{border-color:var(--orange);}
.btn-primary{display:flex;align-items:center;gap:6px;padding:8px 18px;background:var(--orange);color:#fff;border:none;border-radius:8px;font-size:12px;font-weight:700;cursor:pointer;box-shadow:0 2px 8px rgba(249,115,22,.28);transition:.15s;}
.btn-primary:hover{transform:translateY(-1px);}
.btn-primary svg{width:13px;height:13px;stroke:#fff;stroke-width:2.2;fill:none;}

.stats-row{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-bottom:12px;}
@media(min-width:600px){.stats-row{grid-template-columns:repeat(4,1fr);}}
.stat-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;box-shadow:var(--shadow-sm);}
.stat-label{font-size:10px;color:var(--text-3);font-weight:600;margin-bottom:4px;text-transform:uppercase;letter-spacing:.06em;}
.stat-val{font-size:20px;font-weight:800;letter-spacing:-.4px;color:var(--text);}
.stat-val.red{color:var(--red);}

.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow-sm);overflow:hidden;margin-bottom:12px;animation:fadeUp .2s ease;}
.card-head{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);}
.card-title{font-size:12px;font-weight:800;color:var(--text);}
.card-badge{font-size:10px;font-weight:700;padding:2px 8px;border-radius:20px;background:var(--red-lt);color:var(--red);}

table{width:100%;border-collapse:collapse;font-size:12px;}
th{padding:9px 14px;text-align:left;font-size:10px;font-weight:700;color:var(--text-3);text-transform:uppercase;letter-spacing:.08em;border-bottom:1px solid var(--border);background:var(--bg);}
td{padding:9px 14px;border-bottom:1px solid var(--border);color:var(--text-2);}
tr:last-child td{border-bottom:none;}
tr:hover td{background:var(--bg);}
td.num{text-align:right;font-weight:700;color:var(--red);}
td.r{text-align:right;font-weight:700;}

.grid2{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px;}
@media(max-width:640px){.grid2{grid-template-columns:1fr;}}

.empty{padding:32px;text-align:center;color:var(--text-3);font-size:12px;font-weight:600;}
.spinner{width:22px;height:22px;border:2.5px solid var(--border);border-top-color:var(--orange);border-radius:50%;animation:spin .7s linear infinite;margin:28px auto;display:block;}
.error-box{padding:16px 18px;background:var(--red-lt);border-radius:var(--r);color:var(--red);font-size:12px;font-weight:600;margin-bottom:12px;}
.ovwrap{overflow-x:auto;}

/* ── Header de resumen tipo mesas ── */
.mu-header{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-bottom:14px;}
.mu-stat{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;box-shadow:var(--shadow-sm);}
.mu-stat-label{font-size:9.5px;font-weight:700;color:var(--text-3);text-transform:uppercase;letter-spacing:.08em;margin-bottom:5px;}
.mu-stat-val{font-size:20px;font-weight:800;letter-spacing:-.5px;}
.mu-occ-bar{height:3px;background:var(--border);border-radius:4px;margin-top:8px;}
.mu-occ-fill{height:100%;border-radius:4px;background:var(--red);transition:width .6s ease;}

/* ── Grid de tarjetas tipo mesas ── */
.cancel-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:9px;margin-bottom:14px;}
@media(min-width:500px){.cancel-grid{grid-template-columns:repeat(3,1fr);}}
@media(min-width:800px){.cancel-grid{grid-template-columns:repeat(4,1fr);}}
@media(min-width:1100px){.cancel-grid{grid-template-columns:repeat(6,1fr);}}

.cancel-card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r);padding:13px;box-shadow:var(--shadow-sm);
  position:relative;overflow:hidden;transition:all .18s;
}
.cancel-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--red);}
.cancel-card-folio{font-size:10px;font-weight:800;color:var(--text-3);text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px;margin-top:4px;}
.cancel-card-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:20px;font-size:9.5px;font-weight:700;margin-bottom:8px;background:var(--red-lt);color:var(--red);}
.cancel-card-chip-dot{width:5px;height:5px;border-radius:50%;background:currentColor;}
.cancel-card-total{font-size:19px;font-weight:800;color:var(--text);letter-spacing:-.5px;margin-bottom:5px;}
.cancel-card-mesa{font-size:11px;color:var(--text-2);font-weight:600;margin-bottom:3px;}
.cancel-card-badge{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:20px;font-size:10px;font-weight:700;margin-top:4px;background:var(--red-lt);color:var(--red);}

/* ── Tablas auxiliares (usuarios, motivos) ── */
@keyframes pulse-ring{0%,100%{box-shadow:0 0 0 0 rgba(239,68,68,.4);}50%{box-shadow:0 0 0 6px rgba(239,68,68,.0);}}
</style>
<link rel="stylesheet" href="/css/responsive.css?v=406r"/>
</head>
<body>
<div class="topbar">
  <div class="topbar-icon"><svg viewBox="0 0 24 24"><path d="M20 7H4a2 2 0 00-2 2v10a2 2 0 002 2h16a2 2 0 002-2V9a2 2 0 00-2-2z"/><path d="M16 7V5a2 2 0 00-2-2h-4a2 2 0 00-2 2v2"/><line x1="9" y1="14" x2="15" y2="14"/></svg></div>
  <h1>Cuentas Canceladas</h1>
  <div class="live-chip" id="live-chip"><div class="live-dot"></div>En vivo</div>
</div>

<div class="container">
  <div id="live-banner">
    <div class="live-banner-dot"></div>
    <div>
      <div style="font-size:12px;font-weight:700;color:var(--text)" id="live-banner-txt">Turno activo</div>
      <div style="font-size:10px;color:var(--text-3);font-weight:600;margin-top:1px" id="live-banner-sub">Actualizando automáticamente</div>
    </div>
  </div>

  <div class="mode-tabs">
    <button class="mode-tab active" id="tab-fecha" onclick="setMode('fecha')">Por período</button>
    <button class="mode-tab" id="tab-turno" onclick="setMode('turno')">Por turno</button>
    <button class="mode-tab live-tab" id="tab-live" onclick="setMode('live')">● Turno actual</button>
  </div>

  <div id="filters-fecha" class="filters-card">
    <div class="fg"><div class="fl">Fecha inicio</div><input type="date" id="f-ini"/></div>
    <div class="fg"><div class="fl">Fecha fin</div><input type="date" id="f-fin"/></div>
    <button class="btn-primary" onclick="cargar()"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>Consultar</button>
  </div>
  <div id="filters-turno" class="filters-card" style="display:none;">
    <div class="fg"><div class="fl">Turno del día</div>
      <select id="f-turno" style="padding:8px 10px;border:1px solid var(--border);border-radius:var(--r);font-size:13px;background:var(--surface);color:var(--text);">
        <option value="">Cargando turnos...</option>
      </select>
    </div>
    <button class="btn-primary" onclick="cargar()"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>Consultar</button>
  </div>
  <div id="filters-live" style="display:none;"></div>

  <div id="error-box" class="error-box" style="display:none;"></div>
  <div id="spinner" class="spinner" style="display:none;"></div>
  <div id="resultado"></div>
</div>

<script src="/js/arkhon-utils.js"></script>
<script>
var LOCAL_API_KEY = '';
// token loaded via _initAuth()
const fmtDate = s => { if(!s) return '—'; try{ return new Date(s).toLocaleString('es-MX',{dateStyle:'short',timeStyle:'short'}); }catch{ return s; }};
let mode = 'fecha';
let liveRefreshTimer = null;

document.getElementById('f-ini').value = hoy();
document.getElementById('f-fin').value = hoy();

async function cargarTurnos(){
  const sel = document.getElementById('f-turno');
  try{
    const turnos = await api('/turnos/hoy');
    if(!(turnos||[]).length){ sel.innerHTML='<option value="">Sin turnos hoy</option>'; return; }
    sel.innerHTML = (turnos||[]).map(t=>{
      const estado = t.cierre ? 'Cerrado' : 'Activo';
      const hora = t.apertura ? new Date(t.apertura).toLocaleTimeString('es-MX',{hour:'2-digit',minute:'2-digit'}) : '';
      return `<option value="${t.idturno}">${t.nombre_turno||'Turno'} #${t.idturno} — ${hora} (${estado})</option>`;
    }).join('');
    // Auto-seleccionar turno activo
    const activo = (turnos||[]).find(t=>!t.cierre);
    if(activo) sel.value = activo.idturno;
  }catch(e){ sel.innerHTML='<option value="">Error al cargar turnos</option>'; }
}

function setMode(m){
  mode = m;
  if(liveRefreshTimer){ clearInterval(liveRefreshTimer); liveRefreshTimer=null; }
  document.querySelectorAll('.mode-tab').forEach(t=>t.classList.remove('active'));
  document.getElementById('tab-'+m).classList.add('active');
  document.getElementById('filters-fecha').style.display = m==='fecha' ? 'flex' : 'none';
  document.getElementById('filters-turno').style.display = m==='turno' ? 'flex' : 'none';
  document.getElementById('filters-live').style.display  = m==='live'  ? 'block': 'none';
  document.getElementById('resultado').innerHTML = '';
  document.getElementById('error-box').style.display = 'none';
  document.getElementById('live-banner').classList.remove('show');
  if(m === 'turno') cargarTurnos();
  if(m === 'live'){
    cargarTurnoActivo();
    // Fallback polling cada 10s por si el socket no está disponible
    liveRefreshTimer = setInterval(cargarTurnoActivo, 10000);
  }
}

// Actualización en tiempo real del turno seleccionado cuando llega socket
function actualizarTurnoSocket(cancelaciones_turno){
  if(mode !== 'turno') return;
  const sel = document.getElementById('f-turno');
  const idturnoSel = sel ? sel.value : '';
  if(!idturnoSel) return;
  // Solo refrescar si el socket trae datos del turno actual (hoy)
  // y el turno seleccionado no tiene cierre (activo)
  const selectedOption = sel.options[sel.selectedIndex];
  if(!selectedOption) return;
  const esActivo = selectedOption.textContent.includes('Activo');
  if(!esActivo) return;
  // Usar los datos del socket directamente — son del turno activo de hoy
  renderDesdeSocket(cancelaciones_turno);
}

// Renderiza directo desde payload del socket — sin fetch extra
function renderDesdeSocket(cancelaciones_turno) {
  if(!cancelaciones_turno) return;
  const banner = document.getElementById('live-banner');
  const numCuentas = Array.isArray(cancelaciones_turno.cuentas_canceladas)
    ? cancelaciones_turno.cuentas_canceladas.length
    : (cancelaciones_turno.cuentas_afectadas || 0);
  const numProductos = cancelaciones_turno.total_cancelaciones || 0;

  document.getElementById('live-banner-txt').textContent =
    `En vivo — hoy · ${numCuentas} cuentas canceladas · ${numProductos} productos cancelados`;
  document.getElementById('live-banner-sub').textContent =
    `Actualizado vía WebSocket · ${new Date().toLocaleTimeString('es-MX',{hour:'2-digit',minute:'2-digit',second:'2-digit'})}`;
  banner.classList.add('show');

  const listaCuentas = Array.isArray(cancelaciones_turno.cuentas_canceladas)
    ? cancelaciones_turno.cuentas_canceladas
    : [];

  const data = {
    resumen: {
      cuentas_canceladas:    numCuentas,
      importe_cancelado:     cancelaciones_turno.importe_cancelado  || 0,
      meseros_involucrados:  [...new Set(listaCuentas.map(c=>c.idmesero).filter(Boolean))].length,
      dias:                  1,
    },
    cuentas:    listaCuentas,
    porUsuario: cancelaciones_turno.por_usuario || [],
    motivos:    cancelaciones_turno.motivos     || [],
  };
  renderResultado(data);
}


async function cargar(){
  document.getElementById('error-box').style.display='none';
  document.getElementById('resultado').innerHTML='';
  document.getElementById('spinner').style.display='block';
  try{
    let ep;
    if(mode==='turno'){
      const id = document.getElementById('f-turno').value;
      if(!id) throw new Error('Selecciona un turno');
      ep = `/reportes/productos-cancelados?idturno=${id}`;
    } else {
      const ini = document.getElementById('f-ini').value;
      const fin = document.getElementById('f-fin').value;
      if(!ini||!fin) throw new Error('Selecciona un período');
      ep = `/reportes/productos-cancelados?inicio=${ini}&fin=${fin}`;
    }
    const d = await api(ep);
    renderResultado(d);
  }catch(e){ showError('Error: '+e.message); }
  finally{ document.getElementById('spinner').style.display='none'; }
}

async function cargarTurnoActivo(){
  const primeraCarga = !document.getElementById('resultado').innerHTML.trim();
  if(primeraCarga) document.getElementById('spinner').style.display='block';
  try{
    // Prioridad 1: datos frescos del socket (ya tienen el turno activo)
    if(window._lastSocketPayload && window._lastSocketPayload.cancelaciones_turno){
      renderDesdeSocket(window._lastSocketPayload.cancelaciones_turno);
      // Aun así hacer fetch en background para tener datos completos
      _fetchTurnoActivoBackground();
      return;
    }
    // Prioridad 2: fetch directo
    await _fetchTurnoActivoBackground();
  }catch(e){ showError('Error: '+e.message); }
  finally{ if(primeraCarga) document.getElementById('spinner').style.display='none'; }
}

async function _fetchTurnoActivoBackground(){
  try{
    let ep;
    try{
      const turnos = await api('/turnos/hoy');
      const activo = (turnos||[]).find(t => !t.cierre);
      if(activo && activo.idturno){
        ep = `/reportes/productos-cancelados?idturno=${activo.idturno}&pageSize=200`;
      }
    }catch(_){}
    if(!ep) ep = `/reportes/productos-cancelados?inicio=${hoy()}&fin=${hoy()}&pageSize=200`;
    const d = await api(ep);
    const banner = document.getElementById('live-banner');
    document.getElementById('live-banner-txt').textContent = `En vivo — Turno actual`;
    document.getElementById('live-banner-sub').textContent =
      `${Array.isArray(d.resumen?.cuentas_canceladas) ? d.resumen.cuentas_canceladas.length : (d.resumen?.cuentas_canceladas||0)} cuentas canceladas · Actualiza cada 10s`;
    banner.classList.add('show');
    renderResultado(d);
    document.getElementById('spinner').style.display='none';
  }catch(e){
    // Solo mostrar error si no hay nada renderizado todavía
    if(!document.getElementById('resultado').innerHTML.trim()){
      showError('Error al cargar: '+e.message);
    }
  }
}

function showError(msg){
  document.getElementById('spinner').style.display='none';
  const eb = document.getElementById('error-box');
  eb.textContent = msg;
  eb.style.display = 'block';
}

function renderResultado(d){
  const res = document.getElementById('resultado');
  if(!d){ res.innerHTML='<div class="empty">Sin datos</div>'; return; }

  const cuentas  = d.cuentas    || [];
  const porUser  = d.porUsuario || [];
  const motivos  = d.motivos    || [];
  const resumen  = d.resumen    || {};

  if(!cuentas.length){
    res.innerHTML = '<div class="empty">Sin cuentas canceladas en este período</div>';
    return;
  }

  const totalCuentas = Array.isArray(resumen.cuentas_canceladas)
    ? resumen.cuentas_canceladas.length
    : (resumen.cuentas_canceladas || cuentas.length);
  const totalImporte = resumen.importe_cancelado    || cuentas.reduce((a,c)=>a+(c.total||0),0);
  const meseros      = resumen.meseros_involucrados || 0;

  // ── Header tipo mu-header del monitor de mesas ────────────────
  let html = `<div class="mu-header">
    <div class="mu-stat">
      <div class="mu-stat-label">Cuentas canceladas</div>
      <div class="mu-stat-val" style="color:var(--red)">${totalCuentas}</div>
      <div class="mu-occ-bar"><div class="mu-occ-fill" style="width:100%"></div></div>
    </div>
    <div class="mu-stat">
      <div class="mu-stat-label">Importe cancelado</div>
      <div class="mu-stat-val" style="color:var(--red)">${fmt(totalImporte)}</div>
    </div>
    <div class="mu-stat">
      <div class="mu-stat-label">Meseros involucrados</div>
      <div class="mu-stat-val" style="color:${meseros>0?'var(--red)':'var(--text-3)'}">${meseros > 0 ? meseros : 'Ninguno'}</div>
    </div>
  </div>`;

  // ── Grid de tarjetas tipo mesa-card ───────────────────────────
  const cards = cuentas.map(c => {
    const folio  = c.folio  || '—';
    const mesa   = c.mesa   || 'Sin mesa';
    const motivo = c.razoncancelado || 'Sin motivo';
    const usuario= c.usuariocancelo || '—';
    const total  = c.total  || 0;
    const fechaCan = c.fechacancelado || c.fecha;
    let horaTxt = '—';
    if(fechaCan){ try{ horaTxt = new Date(fechaCan).toLocaleTimeString('es-MX',{hour:'2-digit',minute:'2-digit'}); }catch(_){} }

    return `<div class="cancel-card">
      <div class="cancel-card-folio">Folio #${folio}</div>
      <div class="cancel-card-chip"><div class="cancel-card-chip-dot"></div>Cancelado</div>
      <div class="cancel-card-total">${fmt(total)}</div>
      <div class="cancel-card-mesa">${mesa}</div>
      <div class="cancel-card-mesa" style="color:var(--text-3);font-size:10px">${usuario}</div>
      <div class="cancel-card-badge">${horaTxt} · ${motivo.length>18?motivo.slice(0,18)+'…':motivo}</div>
    </div>`;
  }).join('');

  html += `<div class="cancel-grid">${cards}</div>`;

  // ── Tablas auxiliares (usuarios y motivos) ────────────────────
  if(porUser.length || motivos.length){
    html += `<div class="grid2">`;
    if(porUser.length){
      html += `<div class="card">
        <div class="card-head"><span class="card-title">Por usuario</span></div>
        <div class="ovwrap"><table>
          <thead><tr><th>Usuario</th><th style="text-align:right">Cant.</th><th style="text-align:right">Importe</th></tr></thead>
          <tbody>${porUser.map(u=>`<tr>
            <td style="font-weight:700;color:var(--text)">${u.usuario||'—'}</td>
            <td class="r" style="color:var(--text-2)">${u.cantidad}</td>
            <td class="num">${fmt(u.importe||0)}</td>
          </tr>`).join('')}</tbody>
        </table></div>
      </div>`;
    }
    if(motivos.length){
      html += `<div class="card">
        <div class="card-head"><span class="card-title">Por motivo</span></div>
        <div class="ovwrap"><table>
          <thead><tr><th>Motivo</th><th style="text-align:right">Cantidad</th></tr></thead>
          <tbody>${motivos.map(m=>`<tr>
            <td style="font-weight:600;color:var(--text)">${m.motivo||'Sin motivo'}</td>
            <td class="r">${m.cantidad}</td>
          </tr>`).join('')}</tbody>
        </table></div>
      </div>`;
    }
    html += `</div>`;
  }

  res.innerHTML = html;
}

const _s = document.createElement('script');
_s.src = '/socket.io/socket.io.js';
_s.onload = () => {
  const socket = io(window.location.origin,{auth:{token:LOCAL_API_KEY}});
  socket.on('connect',    () => {
    document.getElementById('live-chip').classList.add('show');
    // Pedir snapshot inmediato al conectar en modo live
    if(mode === 'live') cargarTurnoActivo();
  });
  socket.on('disconnect', () => document.getElementById('live-chip').classList.remove('show'));
  socket.on('actualizacion', (data) => {
    window._lastSocketPayload = data;
    if(data.cancelaciones_turno){
      if(mode === 'live'){
        // Cancelar el timer de fallback — el socket está activo
        if(liveRefreshTimer){ clearInterval(liveRefreshTimer); liveRefreshTimer=null; }
        renderDesdeSocket(data.cancelaciones_turno);
      } else if(mode === 'turno'){
        // Actualizar en tiempo real si el turno seleccionado está activo
        actualizarTurnoSocket(data.cancelaciones_turno);
      }
    }
  });
};

  // Ocultar topbar si corre dentro de un iframe
  if (window.self !== window.top) {
    const tb = document.querySelector('.topbar');
    if (tb) tb.style.display = 'none';
  }
(async()=>{ 
  try {
    await _initAuth();
    await cargarTurnos();
    document.head.appendChild(_s);
  } catch(e) {
    const msg = e.message || 'Error de autenticación';
    const esToken = msg.includes('expirada') || msg.toLowerCase().includes('token') || msg.includes('401') || msg.includes('sesión');
    const eb = document.getElementById('error-box');
    eb.innerHTML = esToken
      ? '🔒 Sesión expirada — <a href="javascript:location.reload()" style="color:var(--red);text-decoration:underline;font-weight:800">Recargar página</a>'
      : '⚠️ Error al iniciar: ' + msg;
    eb.style.display = 'block';
  }
})();
</script>
</body>
</html>
