<?php
declare(strict_types=1);

require_once __DIR__ . '/../../app/bootstrap.php';
require_login();

function h($v): string {
    return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8');
}

$title = 'Monitor de asistencia';
include __DIR__ . '/../../app/views/header.php';
?>

<style>
  :root{
    --bg:#07111f;
    --bg2:#0a1527;
    --card:rgba(255,255,255,.05);
    --card2:rgba(255,255,255,.03);
    --line:rgba(255,255,255,.08);
    --text:#eff6ff;
    --muted:#9fb3c8;
    --brand:#4da3ff;
    --brand2:#1b6fff;
    --ok-bg:rgba(34,197,94,.18);
    --ok-tx:#bbf7d0;
    --bad-bg:rgba(239,68,68,.16);
    --bad-tx:#fecaca;
    --doc-bg:rgba(168,85,247,.18);
    --doc-tx:#e9d5ff;
    --shadow:0 20px 50px rgba(0,0,0,.28);
  }

  html, body{
    background:
      radial-gradient(1000px 500px at 10% 0%, rgba(77,163,255,.15), transparent 55%),
      radial-gradient(800px 420px at 90% 0%, rgba(27,111,255,.16), transparent 50%),
      linear-gradient(180deg,#06101d,#081321 45%,#06101d);
  }

  header, nav, .navbar, footer{
    display:none !important;
  }

  main, .container, .container-fluid{
    max-width:none !important;
    width:100% !important;
    padding:0 !important;
    margin:0 !important;
  }

  body{
    color:var(--text);
    overflow:hidden;
  }

  .monitor-root{
    width:100vw;
    height:100vh;
    padding:8px;
    display:grid;
    grid-template-rows:auto auto auto 1fr;
    gap:8px;
  }

  .monitor-controls{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    flex-wrap:wrap;
    padding:8px 10px;
    border:1px solid var(--line);
    border-radius:16px;
    background:linear-gradient(180deg,var(--card),var(--card2));
    box-shadow:var(--shadow);
  }

  .monitor-controls-left,
  .monitor-controls-right{
    display:flex;
    align-items:center;
    gap:8px;
    flex-wrap:wrap;
  }

  .monitor-controls label{
    color:var(--muted);
    font-size:.72rem;
    font-weight:900;
    margin-bottom:3px;
    display:block;
  }

  .monitor-mini-field{
    min-width:135px;
  }

  .monitor-top{
    display:grid;
    grid-template-columns:1.2fr .8fr;
    gap:8px;
  }

  .hero,
  .clock-panel,
  .board,
  .col,
  .ticker-shell{
    border:1px solid var(--line);
    border-radius:18px;
    background:linear-gradient(180deg,var(--card),var(--card2));
    box-shadow:var(--shadow);
    backdrop-filter: blur(8px);
  }

  .hero{
    padding:10px 12px;
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:12px;
    min-width:0;
  }

  .hero-copy{
    min-width:0;
  }

  .hero-title{
    margin:0;
    font-size:clamp(1.7rem,2.5vw,3rem);
    line-height:1;
    font-weight:1000;
    letter-spacing:-.04em;
    color:var(--text);
  }

  .hero-sub{
    margin-top:4px;
    color:var(--muted);
    font-size:.82rem;
    font-weight:800;
  }

  .hero-badge{
    min-width:74px;
    height:74px;
    padding:0 12px;
    border-radius:18px;
    background:linear-gradient(135deg,var(--brand),var(--brand2));
    color:#fff;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:1.45rem;
    font-weight:1000;
    box-shadow:0 14px 30px rgba(27,111,255,.28);
    flex-shrink:0;
  }

  .clock-panel{
    padding:8px 10px;
    display:flex;
    align-items:center;
    justify-content:center;
    min-height:94px;
  }

  .clock-big{
    font-size:clamp(2rem,3.6vw,4rem);
    font-weight:1000;
    letter-spacing:-.04em;
    color:#fff;
    text-shadow:0 8px 18px rgba(0,0,0,.22);
    line-height:1;
  }

  .ticker-shell{
    padding:0;
    overflow:hidden;
    min-height:40px;
    display:flex;
    align-items:center;
  }

  .ticker-track{
    white-space:nowrap;
    display:inline-block;
    padding-left:100%;
    animation:tickerMove 24s linear infinite;
    font-size:.82rem;
    font-weight:900;
    color:#fff;
  }

  .ticker-item{
    display:inline-flex;
    align-items:center;
    gap:8px;
    margin-right:18px;
  }

  .ticker-sep{
    color:var(--muted);
    opacity:.9;
  }

  .ticker-pill{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    padding:5px 9px;
    border-radius:999px;
    background:rgba(255,255,255,.06);
    border:1px solid rgba(255,255,255,.08);
    color:#fff;
    font-size:.76rem;
    font-weight:1000;
  }

  .ticker-pill.ok{
    background:var(--ok-bg);
    color:var(--ok-tx);
  }

  .ticker-pill.bad{
    background:var(--bad-bg);
    color:var(--bad-tx);
  }

  .ticker-pill.doc{
    background:var(--doc-bg);
    color:var(--doc-tx);
  }

  @keyframes tickerMove{
    0%{ transform:translateX(0); }
    100%{ transform:translateX(-100%); }
  }

  .board{
    padding:8px;
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:8px;
    min-height:0;
    height:100%;
  }

  .col{
    min-height:0;
    display:flex;
    flex-direction:column;
    overflow:hidden;
  }

  .col-head{
    padding:8px 10px;
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:8px;
    font-size:.86rem;
    font-weight:1000;
    border-bottom:1px solid var(--line);
    letter-spacing:.01em;
  }

  .col-head.present{
    background:var(--ok-bg);
    color:var(--ok-tx);
  }

  .col-head.absent{
    background:var(--bad-bg);
    color:var(--bad-tx);
  }

  .col-head.docente{
    background:var(--doc-bg);
    color:var(--doc-tx);
  }

  .list{
    --cols:2;
    padding:8px;
    min-height:0;
    height:100%;
    display:grid;
    grid-template-columns:repeat(var(--cols), minmax(0,1fr));
    gap:6px;
    align-content:start;
    overflow:hidden;
  }

  .list.cols-1{ --cols:1; }
  .list.cols-2{ --cols:2; }
  .list.cols-3{ --cols:3; }
  .list.cols-4{ --cols:4; }
  .list.cols-5{ --cols:5; }
  .list.cols-6{ --cols:6; }

  .person-card{
    border:1px solid rgba(255,255,255,.08);
    border-radius:12px;
    background:rgba(255,255,255,.04);
    padding:8px 9px;
    min-height:70px;
    display:flex;
    flex-direction:column;
    justify-content:center;
  }

  .person-card.compact{
    min-height:60px;
    padding:7px 8px;
  }

  .person-card.ultra{
    min-height:52px;
    padding:6px 7px;
  }

  .person-name{
    font-size:.84rem;
    line-height:1.08;
    font-weight:1000;
    color:var(--text);
    letter-spacing:-.01em;
  }

  .person-meta{
    margin-top:4px;
    color:var(--muted);
    font-size:.67rem;
    line-height:1.18;
    font-weight:800;
  }

  .person-card.compact .person-name{ font-size:.78rem; }
  .person-card.compact .person-meta{ font-size:.63rem; }

  .person-card.ultra .person-name{ font-size:.72rem; }
  .person-card.ultra .person-meta{ font-size:.58rem; line-height:1.12; }

  .empty-state{
    color:var(--muted);
    font-size:.85rem;
    font-weight:900;
    padding:6px 4px;
  }

  .tv-mode .monitor-controls{
    display:none;
  }

  .fullscreen-tv .monitor-root{
    padding:6px;
    gap:6px;
  }

  .fullscreen-tv .hero-title{
    font-size:clamp(1.8rem,2.6vw,3.2rem);
  }

  .fullscreen-tv .clock-big{
    font-size:clamp(2.2rem,4vw,4.4rem);
  }

  @media (max-width: 1600px){
    .monitor-top{
      grid-template-columns:1fr;
    }
    .hero-badge{
      min-width:64px;
      height:64px;
      font-size:1.2rem;
    }
  }

  @media (max-width: 1100px){
    .board{
      grid-template-columns:1fr;
    }
    .list{
      --cols:2 !important;
    }
  }
</style>

<div class="monitor-root" id="monitorRoot">
  <div class="monitor-controls" id="monitorControls">
    <div class="monitor-controls-left">
      <div class="monitor-mini-field">
        <label>Periodo</label>
        <select id="filtroPeriodo" class="form-select form-select-sm">
          <option value="hoy" selected>Hoy</option>
          <option value="ayer">Ayer</option>
          <option value="semana">Semana</option>
          <option value="mes">Mes</option>
        </select>
      </div>

      <div class="monitor-mini-field">
        <label>Institución</label>
        <select id="filtroInstitucion" class="form-select form-select-sm">
          <option value="">Todas</option>
          <option value="ENC">ENC</option>
          <option value="CARF">CARF</option>
        </select>
      </div>

      <div class="monitor-mini-field">
        <label>Nivel</label>
        <select id="filtroNivel" class="form-select form-select-sm">
          <option value="">Auto</option>
          <option value="EEB">EEB</option>
          <option value="BTC">BTC</option>
          <option value="BC">BC</option>
        </select>
      </div>

      <div class="monitor-mini-field">
        <label>Buscar</label>
        <input id="buscarTexto" class="form-control form-control-sm" placeholder="CI o nombre">
      </div>
    </div>

    <div class="monitor-controls-right">
      <button class="btn btn-outline-light btn-sm" type="button" id="btnTvMode">Modo TV</button>
      <button class="btn btn-primary btn-sm" type="button" id="btnFullscreenAuto">Pantalla completa</button>
    </div>
  </div>

  <div class="monitor-top">
    <div class="hero">
      <div class="hero-copy">
        <h1 class="hero-title" id="screenTitle">Asistencia 7º</h1>
        <div class="hero-sub" id="screenSubtitle">Presentes y ausentes del día</div>
      </div>
      <div class="hero-badge" id="screenBadge">7º</div>
    </div>

    <div class="clock-panel">
      <div class="clock-big" id="bigClock">--:--:--</div>
    </div>
  </div>

  <div class="ticker-shell">
    <div class="ticker-track" id="tickerTrack">
      <span class="ticker-item">Cargando resumen...</span>
    </div>
  </div>

  <div class="board">
    <div class="col">
      <div class="col-head present">
        <span id="leftHeadLabel">Presentes</span>
        <span id="presentCount">0</span>
      </div>
      <div class="list cols-2" id="presentList">
        <div class="empty-state">Cargando...</div>
      </div>
    </div>

    <div class="col">
      <div class="col-head absent" id="rightHead">
        <span id="rightHeadLabel">Ausentes</span>
        <span id="absentCount">0</span>
      </div>
      <div class="list cols-2" id="absentList">
        <div class="empty-state">Cargando...</div>
      </div>
    </div>
  </div>
</div>

<script>
const API_URL = '/Comercio/public/asistencia/api_monitor_asistencia.php';
const REFRESH_MS = 30000;
const ROTATE_MS = 15000;

const ORDER = [
  { key: '7°', type: 'grupo', title: 'Asistencia 7º', badge: '7º' },
  { key: '8°', type: 'grupo', title: 'Asistencia 8º', badge: '8º' },
  { key: '9°', type: 'grupo', title: 'Asistencia 9º', badge: '9º' },
  { key: '1°', type: 'grupo', title: 'Asistencia 1º', badge: '1º' },
  { key: '2°', type: 'grupo', title: 'Asistencia 2º', badge: '2º' },
  { key: '3°', type: 'grupo', title: 'Asistencia 3º', badge: '3º' },
  { key: 'DOCENTES', type: 'docentes', title: 'Docentes presentes', badge: 'DOC' }
];

let monitorRows = [];
let currentIndex = 0;

function escapeHtml(value) {
  return String(value ?? '')
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#039;');
}

function esDocente(row) {
  const tipo = String(row.tipo_persona || row.tipo || row.rol || '').toUpperCase();
  return tipo === 'DOCENTE' || tipo === 'PROFESOR' || Number(row.es_docente || 0) === 1;
}

function nombrePersona(row) {
  return row.nombre || row.nombres_completos || row.persona || '-';
}

function valorGrupo(row) {
  return String(row.grupo_academico || row.grado || row.curso || '').trim();
}

function valorCursoDetalle(row) {
  const grado = String(row.grado || '').trim();
  const curso = String(row.curso || '').trim();
  const seccion = String(row.seccion || '').trim();
  const turno = String(row.turno || '').trim();
  return [grado, curso, seccion, turno].filter(Boolean).join(' / ') || 'Sin grupo';
}

function formatTime(v) {
  const s = String(v || '').trim();
  return s !== '' ? s : '-';
}

function construirParams() {
  const p = new URLSearchParams();
  p.set('periodo', document.getElementById('filtroPeriodo').value);
  p.set('institucion', document.getElementById('filtroInstitucion').value);
  p.set('nivel', document.getElementById('filtroNivel').value);
  p.set('q', document.getElementById('buscarTexto').value.trim());
  p.set('limit', '2500');
  p.set('_', Date.now().toString());
  return p;
}

function personCardAlumno(row, presente, sizeClass = '') {
  const primera = formatTime(row.primera_marcacion);
  const ultima = formatTime(row.ultima_marcacion);

  return `
    <div class="person-card ${sizeClass}">
      <div class="person-name">${escapeHtml(nombrePersona(row))}</div>
      <div class="person-meta">
        CI: ${escapeHtml(row.cedula || row.ci || '-')}<br>
        ${escapeHtml(valorCursoDetalle(row))}<br>
        ${
          presente
            ? `Entrada: ${escapeHtml(primera)} · Última: ${escapeHtml(ultima)}`
            : `Sin marcación registrada`
        }
      </div>
    </div>
  `;
}

function personCardDocente(row, sizeClass = '') {
  const primera = formatTime(row.primera_marcacion);
  const ultima = formatTime(row.ultima_marcacion);

  return `
    <div class="person-card ${sizeClass}">
      <div class="person-name">${escapeHtml(nombrePersona(row))}</div>
      <div class="person-meta">
        CI: ${escapeHtml(row.cedula || row.ci || '-')}<br>
        Entrada: ${escapeHtml(primera)}<br>
        Salida / última: ${escapeHtml(ultima)}
      </div>
    </div>
  `;
}

function calcLayoutClass(count) {
  if (count <= 10) return { cols: 'cols-2', size: '' };
  if (count <= 18) return { cols: 'cols-3', size: '' };
  if (count <= 28) return { cols: 'cols-4', size: 'compact' };
  if (count <= 40) return { cols: 'cols-5', size: 'compact' };
  return { cols: 'cols-6', size: 'ultra' };
}

function renderList(containerId, itemsHtml, emptyText, count = 0) {
  const el = document.getElementById(containerId);

  if (!itemsHtml.length) {
    el.className = 'list cols-2';
    el.innerHTML = `<div class="empty-state">${escapeHtml(emptyText)}</div>`;
    return;
  }

  const layout = calcLayoutClass(count);
  el.className = `list ${layout.cols}`;
  el.innerHTML = itemsHtml.join('');
}

function buildTicker(htmlParts) {
  document.getElementById('tickerTrack').innerHTML =
    htmlParts.join('<span class="ticker-sep">•</span>');
}

function updateClock() {
  const now = new Date();
  const hh = String(now.getHours()).padStart(2, '0');
  const mm = String(now.getMinutes()).padStart(2, '0');
  const ss = String(now.getSeconds()).padStart(2, '0');
  document.getElementById('bigClock').textContent = `${hh}:${mm}:${ss}`;
}

function renderGrupoSlide(slide) {
  const rows = monitorRows.filter(r => !esDocente(r) && valorGrupo(r) === slide.key);
  const presentes = rows.filter(r => String(r.estado_asistencia || '') === 'presente');
  const ausentes = rows.filter(r => String(r.estado_asistencia || '') !== 'presente');

  const total = rows.length;
  const pct = total > 0 ? Math.round((presentes.length / total) * 100) : 0;

  document.getElementById('screenTitle').textContent = slide.title;
  document.getElementById('screenSubtitle').textContent = 'Presentes y ausentes del día';
  document.getElementById('screenBadge').textContent = slide.badge;

  document.getElementById('leftHeadLabel').textContent = 'Presentes';
  document.getElementById('presentCount').textContent = presentes.length;
  document.getElementById('absentCount').textContent = ausentes.length;
  document.getElementById('rightHeadLabel').textContent = 'Ausentes';
  document.getElementById('rightHead').className = 'col-head absent';

  const lp = calcLayoutClass(presentes.length);
  const la = calcLayoutClass(ausentes.length);

  renderList(
    'presentList',
    presentes.map(r => personCardAlumno(r, true, lp.size)),
    'Sin presentes en este grupo.',
    presentes.length
  );

  renderList(
    'absentList',
    ausentes.map(r => personCardAlumno(r, false, la.size)),
    'Sin ausentes en este grupo.',
    ausentes.length
  );

  buildTicker([
    `<span class="ticker-item"><span class="ticker-pill">${escapeHtml(slide.title)}</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill ok">Presentes: ${presentes.length}</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill bad">Ausentes: ${ausentes.length}</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill">Total: ${total}</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill">Asistencia: ${pct}%</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill">Hora: ${escapeHtml(document.getElementById('bigClock').textContent)}</span></span>`
  ]);
}

function renderDocentesSlide(slide) {
  const docentes = monitorRows
    .filter(r => esDocente(r) && String(r.estado_asistencia || '') === 'presente')
    .sort((a, b) => String(nombrePersona(a)).localeCompare(String(nombrePersona(b))));

  document.getElementById('screenTitle').textContent = slide.title;
  document.getElementById('screenSubtitle').textContent = 'Primera marcación = entrada · Última = salida';
  document.getElementById('screenBadge').textContent = slide.badge;

  document.getElementById('leftHeadLabel').textContent = 'Docentes presentes';
  document.getElementById('presentCount').textContent = docentes.length;
  document.getElementById('absentCount').textContent = 0;
  document.getElementById('rightHeadLabel').textContent = 'Resumen';
  document.getElementById('rightHead').className = 'col-head docente';

  const ld = calcLayoutClass(docentes.length);

  renderList(
    'presentList',
    docentes.map(r => personCardDocente(r, ld.size)),
    'Sin docentes presentes hoy.',
    docentes.length
  );

  let summaryCards = [];
  let earliest = '-';
  let latest = '-';

  if (docentes.length) {
    earliest = docentes.map(r => String(r.primera_marcacion || '').trim()).filter(Boolean).sort()[0] || '-';
    latest = docentes.map(r => String(r.ultima_marcacion || '').trim()).filter(Boolean).sort().slice(-1)[0] || '-';

    summaryCards = [
      `
      <div class="person-card">
        <div class="person-name">Resumen docentes</div>
        <div class="person-meta">
          Presentes hoy: ${docentes.length}<br>
          Primera entrada global: ${escapeHtml(earliest)}<br>
          Última salida global: ${escapeHtml(latest)}
        </div>
      </div>
      `
    ];
  }

  renderList(
    'absentList',
    summaryCards,
    'Sin resumen disponible.',
    summaryCards.length
  );

  buildTicker([
    `<span class="ticker-item"><span class="ticker-pill doc">Docentes presentes: ${docentes.length}</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill">Primera entrada: ${escapeHtml(earliest)}</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill">Última salida: ${escapeHtml(latest)}</span></span>`,
    `<span class="ticker-item"><span class="ticker-pill">Hora: ${escapeHtml(document.getElementById('bigClock').textContent)}</span></span>`
  ]);
}

function renderCurrent() {
  const slide = ORDER[currentIndex];
  if (!slide) return;
  if (slide.type === 'grupo') renderGrupoSlide(slide);
  else renderDocentesSlide(slide);
}

function nextSlide() {
  currentIndex = (currentIndex + 1) % ORDER.length;
  renderCurrent();
}

async function loadData() {
  try {
    const res = await fetch(API_URL + '?' + construirParams().toString(), { cache: 'no-store' });
    const data = await res.json();
    if (!data.ok) return;
    monitorRows = Array.isArray(data.rows) ? data.rows : [];
    renderCurrent();
  } catch (e) {}
}

async function entrarPantallaCompleta() {
  try {
    if (!document.fullscreenElement) await document.documentElement.requestFullscreen();
    document.body.classList.add('fullscreen-tv');
  } catch (e) {}
}

async function salirPantallaCompleta() {
  try {
    if (document.fullscreenElement) await document.exitFullscreen();
  } catch (e) {
  } finally {
    document.body.classList.remove('fullscreen-tv');
  }
}

document.getElementById('btnTvMode').addEventListener('click', () => {
  document.getElementById('monitorRoot').classList.toggle('tv-mode');
});

document.getElementById('btnFullscreenAuto').addEventListener('click', async () => {
  if (!document.fullscreenElement) await entrarPantallaCompleta();
  else await salirPantallaCompleta();
});

document.addEventListener('fullscreenchange', () => {
  if (document.fullscreenElement) document.body.classList.add('fullscreen-tv');
  else document.body.classList.remove('fullscreen-tv');
});

document.addEventListener('keydown', async (e) => {
  if (e.key === 'ArrowRight') nextSlide();
  if (e.key === 'ArrowLeft') {
    currentIndex = (currentIndex - 1 + ORDER.length) % ORDER.length;
    renderCurrent();
  }
  if (e.key.toLowerCase() === 'f') {
    if (!document.fullscreenElement) await entrarPantallaCompleta();
    else await salirPantallaCompleta();
  }
  if (e.key === 'Escape') await salirPantallaCompleta();
});

document.querySelectorAll('#filtroPeriodo,#filtroInstitucion,#filtroNivel')
  .forEach(el => el.addEventListener('change', loadData));

document.getElementById('buscarTexto').addEventListener('input', () => {
  clearTimeout(window._timerBusquedaMonitor);
  window._timerBusquedaMonitor = setTimeout(loadData, 250);
});

updateClock();
setInterval(() => {
  updateClock();
  renderCurrent();
}, 1000);

loadData();
setInterval(loadData, REFRESH_MS);
setInterval(nextSlide, ROTATE_MS);
</script>

<?php include __DIR__ . '/../../app/views/footer.php'; ?>