<?php
/**
 * Módulo de Sorteos — Sprint 16S
 * Fuente configurable, filtro horario, pantalla completa, audio mejorado
 */
ini_set("session.gc_maxlifetime", 86400);
session_set_cookie_params(86400);
session_save_path("/home/evolucionamos/public_html/mejora/sessions");
session_start();
require_once '../env_loader.php';
require_once '../app/models/conexion.php';
require_once '../app/models/datos.php';

if (empty($_SESSION['adm'])) { header('Location: index.php'); exit; }
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrf = $_SESSION['csrf_token'];

try {
    $cfg     = (new \app\models\datos())->obtenerDatos();
    $titulo  = $cfg->titulo ?? 'Asamblea';
    $entidad = $cfg->app    ?? 'Brújula Virtual';
} catch (Exception $e) { $titulo = 'Asamblea'; $entidad = 'Brújula Virtual'; }
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>🎲 Sorteos — <?= htmlspecialchars($titulo) ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/dist/confetti.browser.min.js"></script>
<style>
/* ── Base ───────────────────────────────────────────────────────── */
body {
  background: #f8f9fa;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  min-height: 100vh;
}

/* ── Navbar ─────────────────────────────────────────────────────── */
.navbar-sorteos {
  background: #ffffff;
  border-bottom: 2px solid #17c1e8;
  padding: 12px 24px;
  display: flex;
  align-items: center;
  gap: 16px;
  box-shadow: 0 2px 10px rgba(0,0,0,.06);
  position: sticky; top: 0; z-index: 100;
}
.navbar-sorteos h1 {
  font-size: 1.15rem;
  font-weight: 700;
  color: #1F4E79;
  margin: 0;
}
.navbar-sorteos small { color: #888; font-size: .78em; }

/* Badge quórum */
.quorum-badge {
  margin-left: auto;
  background: linear-gradient(310deg, #2b5a9e 0%, #17c1e8 100%);
  color: #fff;
  border-radius: 20px;
  padding: 6px 18px;
  font-size: .82rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  transition: opacity .2s;
  user-select: none;
}
.quorum-badge:hover { opacity: .88; }
.qdot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #4ade80;
  box-shadow: 0 0 6px #4ade80;
  animation: qdot 1.8s ease-in-out infinite;
}
@keyframes qdot { 0%,100%{transform:scale(1)} 50%{transform:scale(1.6)} }
.btn-volver {
  color: #666;
  font-size: .82rem;
  text-decoration: none;
  padding: 6px 14px;
  border-radius: 20px;
  border: 1px solid #e0e0e0;
  background: #fff;
  transition: all .2s;
}
.btn-volver:hover { background: #f0f0f0; color: #333; }

/* ── Layout ─────────────────────────────────────────────────────── */
.main { padding: 24px; max-width: 1280px; margin: 0 auto; }

/* ── Cards ───────────────────────────────────────────────────────── */
.card-s {
  background: #fff;
  border-radius: 15px;
  border: none;
  box-shadow: 0 4px 15px rgba(0,0,0,.05);
  padding: 20px;
}
.card-title-s {
  font-size: .72em;
  font-weight: 700;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: #aaa;
  border-bottom: 2px solid #f0f0f0;
  padding-bottom: 10px;
  margin-bottom: 16px;
}

/* ── Configuración fuente ────────────────────────────────────────── */
.fuente-toggle {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
}
.btn-fuente {
  flex: 1;
  padding: 7px 10px;
  border: 1.5px solid #e0e6ed;
  border-radius: 10px;
  background: #fafafa;
  color: #666;
  font-size: .8rem;
  font-weight: 600;
  cursor: pointer;
  transition: all .18s;
  text-align: center;
}
.btn-fuente:hover  { border-color: #17c1e8; background: #f0fbff; color: #0ea8cc; }
.btn-fuente.activo { border-color: #2b5a9e; background: #eef3fa; color: #2b5a9e; }

/* ── Filtro horario ──────────────────────────────────────────────── */
#filtro-hora {
  background: #f8fbff;
  border: 1.5px solid #e0e6ed;
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 14px;
  font-size: .82rem;
}
#filtro-hora label { color: #888; font-weight: 600; font-size: .75em; letter-spacing: 1px; text-transform: uppercase; display: block; margin-bottom: 7px; }
.hora-inputs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hora-inputs input[type=time] {
  flex: 1; min-width: 100px;
  border: 1.5px solid #e0e6ed;
  border-radius: 8px;
  padding: 5px 8px;
  font-size: .85rem;
  outline: none;
}
.hora-inputs input[type=time]:focus { border-color: #17c1e8; }
.hora-inputs span { color: #bbb; font-weight: 700; }
.btn-limpiar-hora {
  background: none;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 4px 10px;
  font-size: .78rem;
  color: #999;
  cursor: pointer;
  transition: all .15s;
}
.btn-limpiar-hora:hover { background: #fee; color: #dc3545; border-color: #dc3545; }

/* ── Form agregar premio ─────────────────────────────────────────── */
.form-add {
  display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px;
}
.form-add input[type=text] {
  flex: 1; min-width: 130px;
  border: 1.5px solid #e0e6ed;
  border-radius: 10px;
  padding: 8px 13px;
  font-size: .9rem;
  transition: border-color .2s;
  outline: none;
}
.form-add input[type=text]:focus { border-color: #17c1e8; }
.form-add input[type=number] {
  width: 62px;
  border: 1.5px solid #e0e6ed;
  border-radius: 10px;
  padding: 8px 8px;
  font-size: .9rem;
  text-align: center;
}
.btn-add {
  background: linear-gradient(310deg, #2b5a9e 0%, #17c1e8 100%);
  color: #fff; border: none; border-radius: 10px;
  padding: 8px 18px; font-size: .9rem; font-weight: 700;
  cursor: pointer; transition: opacity .2s;
}
.btn-add:hover { opacity: .88; }

/* ── Lista de premios ────────────────────────────────────────────── */
.lista-premios { list-style: none; padding: 0; margin: 0; }
.item-p {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 13px;
  border-radius: 10px;
  border: 1.5px solid #f0f0f0;
  background: #fafafa;
  margin-bottom: 7px;
  cursor: pointer;
  transition: all .18s;
}
.item-p:hover         { border-color: #17c1e8; background: #f0fbff; }
.item-p.activo        { border-color: #1F4E79; background: #eef3fa; }
.item-p.ejecutado     { opacity: .45; pointer-events: none; }
.pnum {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: linear-gradient(310deg, #2b5a9e, #17c1e8);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: .7em; font-weight: 700; flex-shrink: 0;
}
.item-p.activo .pnum  { background: #1F4E79; }
.pnombre { font-weight: 600; font-size: .88rem; color: #333; }
.pcant   { font-size: .72em; color: #999; }
.btn-rm  {
  margin-left: auto;
  background: none; border: none;
  color: #ccc; font-size: 1rem;
  cursor: pointer; line-height: 1;
  transition: color .15s;
}
.btn-rm:hover { color: #dc3545; }

/* ── Panel sorteo ────────────────────────────────────────────────── */
.panel-sorteo {
  background: #fff;
  border-radius: 15px;
  box-shadow: 0 4px 15px rgba(0,0,0,.05);
  min-height: 420px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center; padding: 32px 24px;
  position: relative; overflow: hidden;
}
.panel-sorteo::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, #17c1e8, #1F4E79);
}

/* ── Fullscreen — paleta corporativa clara ───────────────────────── */
#panel-sorteo:-webkit-full-screen,
#panel-sorteo:fullscreen {
  width: 100vw; height: 100vh; max-width: none;
  border-radius: 0; background: #f0f2f5;
  display: flex; align-items: center; justify-content: center;
  overflow: auto;
}
#panel-sorteo:-webkit-full-screen .premio-tag,
#panel-sorteo:fullscreen .premio-tag             { font-size: 1rem; padding: 7px 28px; }
#panel-sorteo:-webkit-full-screen .premio-nombre-grande,
#panel-sorteo:fullscreen .premio-nombre-grande   { font-size: clamp(2.5rem, 7vw, 5rem); color: #1F4E79; }
#panel-sorteo:-webkit-full-screen .premio-sub,
#panel-sorteo:fullscreen .premio-sub             { font-size: 1.1rem; color: #666; }
#panel-sorteo:-webkit-full-screen .cd-num,
#panel-sorteo:fullscreen .cd-num                 { font-size: clamp(8rem, 25vw, 16rem); color: #1F4E79; }
#panel-sorteo:-webkit-full-screen .ganador-card,
#panel-sorteo:fullscreen .ganador-card           { min-width: 220px; padding: 22px 28px; }
#panel-sorteo:-webkit-full-screen .ganador-nombre,
#panel-sorteo:fullscreen .ganador-nombre         { font-size: 1.25rem; }
#panel-sorteo:-webkit-full-screen .ganador-cc,
#panel-sorteo:fullscreen .ganador-cc             { font-size: .95rem; }
#panel-sorteo:-webkit-full-screen .ganador-zona,
#panel-sorteo:fullscreen .ganador-zona           { font-size: .95rem; }
#panel-sorteo:-webkit-full-screen .ganador-trophy,
#panel-sorteo:fullscreen .ganador-trophy         { font-size: 3rem; }
#panel-sorteo:-webkit-full-screen .ganador-premio,
#panel-sorteo:fullscreen .ganador-premio         { font-size: 1rem; padding: 4px 16px; }
#panel-sorteo:-webkit-full-screen .ganadores-titulo,
#panel-sorteo:fullscreen .ganadores-titulo       { font-size: 1.6rem; }

.btn-exit-fs {
  position: absolute; top: 16px; right: 16px;
  background: rgba(255,255,255,.15);
  color: #fff;
  border: 1.5px solid rgba(255,255,255,.3);
  border-radius: 20px;
  padding: 6px 14px;
  font-size: .78rem;
  font-weight: 600;
  cursor: pointer;
  display: none;
  transition: background .15s;
  z-index: 10;
}
.btn-exit-fs:hover { background: rgba(255,255,255,.25); }

/* Espera */
.espera-icon {
  width: 72px; height: 72px;
  border-radius: 50%;
  background: linear-gradient(310deg, #2b5a9e 0%, #17c1e8 100%);
  display: flex; align-items: center; justify-content: center;
  font-size: 2rem; margin: 0 auto 16px;
  box-shadow: 0 6px 20px rgba(23,193,232,.3);
}
.espera-txt { color: #aaa; font-size: .95rem; }

/* Premio activo */
.premio-tag {
  display: inline-block;
  background: linear-gradient(310deg, #2b5a9e 0%, #17c1e8 100%);
  color: #fff;
  border-radius: 20px;
  padding: 5px 20px;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .5px;
  margin-bottom: 8px;
}
.premio-nombre-grande {
  font-size: clamp(1.4rem, 4vw, 2rem);
  font-weight: 800;
  color: #1F4E79;
  margin-bottom: 4px;
}
.premio-sub { color: #aaa; font-size: .85rem; margin-bottom: 24px; }

/* Ruleta */
.slot-wrap {
  background: linear-gradient(135deg, #0d2444, #1a3a6e);
  border: 2px solid #17c1e8;
  border-radius: 18px;
  padding: 18px 20px 16px;
  display: inline-block;
  margin-bottom: 20px;
  position: relative;
}
.slot-reels { display: flex; gap: 8px; justify-content: center; }
.reel {
  width: 58px; height: 70px;
  background: rgba(0,0,0,.35);
  border: 1.5px solid rgba(255,255,255,.15);
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-size: 2.2rem; overflow: hidden;
}
.reel-txt { transition: none; display: block; line-height: 1; }
.slot-label {
  text-align: center;
  color: rgba(255,255,255,.5);
  font-size: .7em;
  letter-spacing: 2px;
  text-transform: uppercase;
  margin-top: 8px;
}

/* Cuenta regresiva */
.cd-num {
  font-size: clamp(5rem, 15vw, 8rem);
  font-weight: 900;
  color: #1F4E79;
  line-height: 1;
  min-height: 100px;
  display: flex; align-items: center; justify-content: center;
  transition: color .3s;
}
.cd-num.bounce { animation: bounce .25s cubic-bezier(.17,.67,.35,1.4); }
@keyframes bounce { 0%{transform:scale(.5)} 60%{transform:scale(1.15)} 100%{transform:scale(1)} }

/* Ganadores */
.ganadores-wrap { width: 100%; margin-top: 4px; }
.ganadores-titulo {
  font-size: 1.1rem; font-weight: 800; color: #1F4E79;
  margin-bottom: 14px;
}
.ganadores-grid {
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: center;
}
.ganador-card {
  background: #fff;
  border: 2px solid #17c1e8;
  border-radius: 14px;
  padding: 16px 20px;
  min-width: 165px;
  box-shadow: 0 4px 15px rgba(23,193,232,.15);
  animation: card-in .5s cubic-bezier(.17,.67,.35,1.3) both;
}
@keyframes card-in {
  from { opacity:0; transform:scale(.7) translateY(20px); }
  to   { opacity:1; transform:scale(1) translateY(0); }
}
.ganador-trophy { font-size: 2rem; margin-bottom: 6px; }
.ganador-nombre { font-weight: 700; font-size: .95rem; color: #1F4E79; }
.ganador-cc     { font-size: .75rem; color: #888; margin-top: 3px; }
.ganador-zona   { font-size: .75rem; color: #888; }
.ganador-premio {
  margin-top: 6px;
  font-size: .78rem;
  font-weight: 700;
  color: #17c1e8;
  background: #f0fbff;
  border-radius: 20px;
  padding: 2px 10px;
  display: inline-block;
}

/* Botones sorteo */
.btn-sortear {
  background: linear-gradient(310deg, #1F4E79 0%, #17c1e8 100%);
  color: #fff; border: none; border-radius: 25px;
  padding: 13px 44px; font-size: 1rem; font-weight: 700;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(23,193,232,.35);
  transition: all .2s;
}
.btn-sortear:hover   { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(23,193,232,.5); }
.btn-sortear:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn-sig {
  background: #fff;
  color: #1F4E79;
  border: 1.5px solid #1F4E79;
  border-radius: 25px;
  padding: 12px 28px;
  font-size: .9rem;
  font-weight: 600;
  cursor: pointer;
  display: none;
  transition: all .2s;
}
.btn-sig:hover    { background: #eef3fa; }
.btn-sig:disabled { opacity: .4; cursor: not-allowed; }

/* ── Historial ───────────────────────────────────────────────────── */
.card-hist { margin-top: 20px; }
.htable    { width: 100%; border-collapse: collapse; }
.htable th {
  font-size: .72em; letter-spacing: 1.5px; text-transform: uppercase;
  color: #bbb; padding: 8px 12px;
  border-bottom: 2px solid #f0f0f0;
}
.htable td { font-size: .88rem; padding: 10px 12px; border-bottom: 1px solid #f8f9fa; }
.badge-p {
  background: #f0fbff; color: #0ea5e9;
  border: 1px solid #bae6fd;
  border-radius: 20px; padding: 2px 11px; font-size: .75em; font-weight: 600;
}
.btn-csv {
  background: #fff; color: #28a745;
  border: 1.5px solid #28a745;
  border-radius: 20px; padding: 4px 16px;
  font-size: .78rem; font-weight: 600;
  text-decoration: none; transition: all .2s;
  display: inline-block;
}
.btn-csv:hover { background: #f0fff4; color: #28a745; }

/* ── Toast ───────────────────────────────────────────────────────── */
.toast-msg {
  position: fixed; bottom: 24px; left: 50%;
  transform: translateX(-50%) translateY(80px);
  border-radius: 12px; padding: 11px 22px;
  font-weight: 600; font-size: .88rem;
  box-shadow: 0 6px 24px rgba(0,0,0,.15);
  transition: transform .35s cubic-bezier(.17,.67,.35,1.2);
  z-index: 9999; pointer-events: none;
}
.toast-msg.err  { background: #dc3545; color: #fff; }
.toast-msg.ok   { background: #28a745; color: #fff; }
.toast-msg.show { transform: translateX(-50%) translateY(0); }

@media(max-width:640px) {
  .row-layout { flex-direction: column !important; }
  .col-izq    { width: 100% !important; }
}
</style>
</head>
<body>

<!-- Navbar -->
<div class="navbar-sorteos">
  <div>
    <h1>🎲 Módulo de Sorteos</h1>
    <small><?= htmlspecialchars($entidad) ?> · <?= htmlspecialchars($titulo) ?></small>
  </div>
  <div class="quorum-badge" onclick="refrescarQuorum()" title="Clic para refrescar">
    <div class="qdot"></div>
    <span>👥 <strong id="q-num">…</strong> disponibles</span>
  </div>
  <a href="admin.php" class="btn-volver">← Panel</a>
</div>

<!-- Main -->
<div class="main">
  <div class="row-layout" style="display:flex;gap:20px;align-items:flex-start;flex-wrap:wrap;">

    <!-- Izquierda: configuración + cola de premios -->
    <div class="col-izq" style="flex:0 0 320px;min-width:280px;">

      <!-- Configuración de participantes -->
      <div class="card-s mb-3">
        <div class="card-title-s">⚙️ Configuración del Sorteo</div>

        <div style="font-size:.78em;font-weight:700;color:#888;letter-spacing:.5px;margin-bottom:7px;">PARTICIPANTES</div>
        <div class="fuente-toggle">
          <button class="btn-fuente activo" id="btn-f-quorum" onclick="setFuente('quorum')">🎯 Quórum activo</button>
          <button class="btn-fuente"        id="btn-f-todos"  onclick="setFuente('todos')">👥 Todos los activos</button>
        </div>

        <div id="filtro-hora">
          <label>⏱ Filtrar por hora de ingreso</label>
          <div class="hora-inputs">
            <input type="time" id="hora-desde" onchange="actualizarFiltroHora()" title="Desde">
            <span>–</span>
            <input type="time" id="hora-hasta" onchange="actualizarFiltroHora()" title="Hasta">
            <button class="btn-limpiar-hora" onclick="limpiarFiltroHora()">✕ Limpiar</button>
          </div>
        </div>
      </div>

      <!-- Cola de premios -->
      <div class="card-s">
        <div class="card-title-s">📦 Cola de Premios</div>

        <div class="form-add">
          <input type="text" id="inp-regalo" placeholder="Nombre del premio…" maxlength="255">
          <input type="number" id="inp-cant" value="1" min="1" max="50" title="Nº ganadores">
          <button class="btn-add" onclick="agregarPremio()" title="Agregar">＋</button>
        </div>

        <ul class="lista-premios" id="lista-premios">
          <li style="text-align:center;color:#ccc;font-size:.85em;padding:12px 0;">
            Agrega premios para comenzar
          </li>
        </ul>
      </div>
    </div>

    <!-- Derecha: panel sorteo -->
    <div style="flex:1;min-width:300px;">
      <div class="panel-sorteo" id="panel-sorteo">

        <!-- Canvas confeti (fullscreen) -->
        <canvas id="confeti-canvas" style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:50;display:none;"></canvas>

        <!-- Botón salir pantalla completa (visible solo en fullscreen) -->
        <button class="btn-exit-fs" id="btn-exit-fs" onclick="salirPantallaCompleta()">⬜ Salir pantalla completa</button>

        <!-- Estado espera -->
        <div id="est-espera">
          <div class="espera-icon">🎲</div>
          <div class="espera-txt">
            Agrega premios a la cola<br>y selecciona uno para comenzar
          </div>
        </div>

        <!-- Estado activo -->
        <div id="est-activo" style="display:none;width:100%;">
          <div class="premio-tag">PREMIO</div>
          <div class="premio-nombre-grande" id="p-nombre">—</div>
          <div class="premio-sub" id="p-sub">Listo para sortear</div>

          <!-- Ruleta -->
          <div id="slot-wrap" class="slot-wrap">
            <div class="slot-reels">
              <div class="reel"><span class="reel-txt" id="r0">🎰</span></div>
              <div class="reel"><span class="reel-txt" id="r1">🎲</span></div>
              <div class="reel"><span class="reel-txt" id="r2">🍀</span></div>
            </div>
            <div class="slot-label">SORTEO EN VIVO</div>
          </div>

          <!-- Cuenta regresiva -->
          <div id="cd-wrap" style="display:none;">
            <div class="cd-num" id="cd-num">5</div>
          </div>

          <!-- Ganadores -->
          <div id="g-wrap" class="ganadores-wrap" style="display:none;">
            <div class="ganadores-titulo">🎉 ¡Felicidades!</div>
            <div class="ganadores-grid" id="g-grid"></div>
          </div>

          <!-- Botones -->
          <div style="display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:22px;">
            <button class="btn-sortear" id="btn-s"   onclick="ejecutar()">🎲 ¡Sortear!</button>
            <button class="btn-sig"     id="btn-sig" onclick="siguiente()">⏭ Siguiente premio</button>
          </div>
        </div>

      </div>
    </div>

  </div><!-- /row -->

  <!-- Historial -->
  <div class="card-s card-hist">
    <div class="card-title-s" style="display:flex;justify-content:space-between;align-items:center;">
      <span>🏆 Historial de Ganadores</span>
      <a href="../app/controllers/administradores/sorteoController.php?accion=csv"
         class="btn-csv">📥 Descargar CSV</a>
    </div>
    <div class="table-responsive">
      <table class="htable">
        <thead>
          <tr><th>#</th><th>Nombre</th><th>Cédula</th><th>Zona</th><th>Premio</th><th>Hora</th></tr>
        </thead>
        <tbody id="t-hist">
          <tr><td colspan="6" style="text-align:center;color:#ccc;padding:18px;">Sin ganadores aún</td></tr>
        </tbody>
      </table>
    </div>
  </div>

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

<div class="toast-msg" id="toast"></div>

<script>
// ── Config ─────────────────────────────────────────────────────────
const CSRF   = <?= json_encode($csrf) ?>;
const CTRL   = '../app/controllers/administradores/sorteoController.php';
const EMOJIS = ['🎰','🎲','🍀','⭐','💎','🔔','🎯','🏆','🌟','✨','🎁','🎊','🃏','🎴'];

// ── Estado ─────────────────────────────────────────────────────────
let cola = [], idxActivo = -1, corriendo = false;
let reelTimers = [];
let fuenteActual = 'quorum';
let horaDesde    = '';
let horaHasta    = '';

// ── Audio Context ──────────────────────────────────────────────────
let audioCtx = null;
function getAC() {
    if (!audioCtx) audioCtx = new (window.AudioContext||window.webkitAudioContext)();
    try { audioCtx.resume(); } catch(e){}
    return audioCtx;
}

// Beep genérico
function beep(freq, vol, dur, type='sine', delay=0) {
    try {
        const ac=getAC(), o=ac.createOscillator(), g=ac.createGain();
        o.connect(g); g.connect(ac.destination);
        o.type=type; o.frequency.value=freq;
        const t=ac.currentTime+delay;
        g.gain.setValueAtTime(0,t);
        g.gain.linearRampToValueAtTime(vol,t+0.01);
        g.gain.exponentialRampToValueAtTime(0.001,t+dur);
        o.start(t); o.stop(t+dur+0.05);
    } catch(e){}
}

// ── SONIDO RULETA GIRANDO ──────────────────────────────────────────
let ruletaOsc = null, ruletaGainNode = null;
function startRuletaSound() {
    try {
        const ac = getAC();
        // Oscilador base mecánico
        ruletaOsc = ac.createOscillator();
        ruletaGainNode = ac.createGain();
        ruletaOsc.type = 'sawtooth';
        ruletaOsc.frequency.setValueAtTime(200, ac.currentTime);
        ruletaOsc.frequency.linearRampToValueAtTime(80, ac.currentTime + 1.4);
        ruletaGainNode.gain.setValueAtTime(0.07, ac.currentTime);
        ruletaOsc.connect(ruletaGainNode);
        ruletaGainNode.connect(ac.destination);
        ruletaOsc.start();
        // Ticks rápidos simulando ruleta
        for (let i = 0; i < 18; i++) {
            const delay = i * 0.075;
            beep(600 + Math.random()*600, 0.08, 0.04, 'square', delay);
        }
    } catch(e){}
}
function stopRuletaSound() {
    try { if(ruletaOsc) { ruletaOsc.stop(); ruletaOsc = null; } } catch(e){}
    ruletaGainNode = null;
}

// ── SONIDO CUENTA REGRESIVA DRAMÁTICA ─────────────────────────────
function beepConteo(n) {
    try {
        const ac = getAC();
        // Tono grave principal — más dramático al bajar el número
        const freqBase = [110, 120, 130, 150, 165][5-n] || 165;
        // Bajo profundo
        beep(freqBase,     0.30, 0.7, 'sine');
        beep(freqBase * 2, 0.20, 0.5, 'sine');
        // Golpe de percusión
        const buf = ac.createBuffer(1, ac.sampleRate * 0.1, ac.sampleRate);
        const data = buf.getChannelData(0);
        for (let i = 0; i < data.length; i++) data[i] = (Math.random() * 2 - 1) * Math.exp(-i / (ac.sampleRate * 0.03));
        const src = ac.createBufferSource();
        src.buffer = buf;
        const g = ac.createGain();
        g.gain.setValueAtTime(0.4, ac.currentTime);
        g.gain.exponentialRampToValueAtTime(0.001, ac.currentTime + 0.1);
        src.connect(g); g.connect(ac.destination);
        src.start();
    } catch(e){}
}

// ── FANFARRIA + OVACIÓN ────────────────────────────────────────────
function fanfarria() {
    // Acorde triunfal
    [523,659,784,1047,1319].forEach((f,i)=>{
        beep(f, 0.22+i*.02, 0.7, 'sine', i*.08);
    });
    [392,494,587].forEach((f,i)=>{
        beep(f, 0.12, 0.8, 'sine', i*.1);
    });
}

function ovacion() {
    fanfarria();
    // Aplausos: ruido blanco modulado
    try {
        const ac      = getAC();
        const durSecs = 4.5;
        const sr      = ac.sampleRate;
        const buf     = ac.createBuffer(2, sr * durSecs, sr);
        for (let ch = 0; ch < 2; ch++) {
            const data = buf.getChannelData(ch);
            for (let i = 0; i < data.length; i++) {
                // Pulsos de ruido que simulan palmadas
                const t    = i / sr;
                const env  = Math.max(0, Math.sin(Math.PI * t / durSecs)) * 0.6;
                const bursts = Math.abs(Math.sin(t * 8.5 + ch)) > 0.3 ? 1 : 0.15;
                data[i] = (Math.random() * 2 - 1) * env * bursts * 0.35;
            }
        }
        const src = ac.createBufferSource();
        src.buffer = buf;
        const g = ac.createGain();
        g.gain.setValueAtTime(0, ac.currentTime);
        g.gain.linearRampToValueAtTime(0.8, ac.currentTime + 0.3);
        g.gain.setValueAtTime(0.8, ac.currentTime + durSecs - 0.8);
        g.gain.linearRampToValueAtTime(0, ac.currentTime + durSecs);
        // Filtro para darle calidez
        const filt = ac.createBiquadFilter();
        filt.type = 'bandpass';
        filt.frequency.value = 2000;
        filt.Q.value = 0.4;
        src.connect(filt); filt.connect(g); g.connect(ac.destination);
        src.start();
    } catch(e){}
}

// ── Confeti ────────────────────────────────────────────────────────
function confetiFiesta() {
    if (typeof confetti==='undefined') return;
    const c=['#1F4E79','#17c1e8','#FFD700','#28a745','#ff6b6b','#fff'];
    // Usar canvas interno cuando está en fullscreen para que se vea dentro del panel
    const enFs = !!(document.fullscreenElement || document.webkitFullscreenElement);
    const cvs  = document.getElementById('confeti-canvas');
    cvs.style.display = enFs ? '' : 'none';
    const shoot = enFs
        ? confetti.create(cvs, {resize: true, useWorker: false})
        : confetti;
    shoot({particleCount:90,spread:100,origin:{x:.5,y:.1},colors:c});
    const end=Date.now()+4000;
    (function loop(){
        shoot({particleCount:6,angle:60, spread:60,origin:{x:0,y:.65},colors:c});
        shoot({particleCount:6,angle:120,spread:60,origin:{x:1,y:.65},colors:c});
        if(Date.now()<end) requestAnimationFrame(loop);
    })();
    setTimeout(()=>shoot({particleCount:140,spread:110,origin:{x:.5,y:.6},colors:c,scalar:1.2}),500);
    setTimeout(()=>{
        shoot({particleCount:60,spread:80,origin:{x:.25,y:.45},colors:c});
        shoot({particleCount:60,spread:80,origin:{x:.75,y:.45},colors:c});
    },1800);
    // Ocultar canvas al terminar
    setTimeout(()=>{ cvs.style.display='none'; }, 6000);
}

// ── Ruleta visual ──────────────────────────────────────────────────
function iniciarRuleta() {
    pararRuleta();
    [0,1,2].forEach((i)=>{
        reelTimers[i] = setInterval(()=>{
            const el=document.getElementById('r'+i);
            if(el) el.textContent=EMOJIS[Math.floor(Math.random()*EMOJIS.length)];
        }, 90+i*35);
    });
}
function pararRuleta(final=['🏆','🌟','🎊']) {
    reelTimers.forEach(id=>clearInterval(id));
    reelTimers=[];
    [0,1,2].forEach((i,idx)=>{
        setTimeout(()=>{
            const el=document.getElementById('r'+i);
            if(el) el.textContent=final[idx]||'🏆';
        }, idx*180);
    });
}

// ── Pantalla completa ──────────────────────────────────────────────
async function entrarPantallaCompleta() {
    const el = document.getElementById('panel-sorteo');
    try {
        if (el.requestFullscreen)       await el.requestFullscreen();
        else if (el.webkitRequestFullscreen) el.webkitRequestFullscreen();
    } catch(e){}
}
function salirPantallaCompleta() {
    try {
        if (document.exitFullscreen)       document.exitFullscreen();
        else if (document.webkitExitFullscreen) document.webkitExitFullscreen();
    } catch(e){}
    document.getElementById('btn-exit-fs').style.display = 'none';
}
document.addEventListener('fullscreenchange', ()=>{
    const enFs = !!document.fullscreenElement;
    document.getElementById('btn-exit-fs').style.display = enFs ? '' : 'none';
});

// ── Configuración fuente ───────────────────────────────────────────
function setFuente(f) {
    fuenteActual = f;
    document.getElementById('btn-f-quorum').classList.toggle('activo', f==='quorum');
    document.getElementById('btn-f-todos').classList.toggle('activo', f==='todos');
    document.getElementById('filtro-hora').style.display = f==='quorum' ? '' : 'none';
    refrescarQuorum();
}
function actualizarFiltroHora() {
    horaDesde = document.getElementById('hora-desde').value || '';
    horaHasta = document.getElementById('hora-hasta').value || '';
    refrescarQuorum();
}
function limpiarFiltroHora() {
    document.getElementById('hora-desde').value = '';
    document.getElementById('hora-hasta').value = '';
    horaDesde = horaHasta = '';
    refrescarQuorum();
}

// Construir query string con fuente y filtros
function filtroParams() {
    let p = 'fuente=' + fuenteActual;
    if (fuenteActual === 'quorum' && horaDesde && horaHasta) {
        p += '&hora_desde=' + encodeURIComponent(horaDesde) + '&hora_hasta=' + encodeURIComponent(horaHasta);
    }
    return p;
}

// ── Cola de premios ────────────────────────────────────────────────
function agregarPremio() {
    const r=document.getElementById('inp-regalo').value.trim();
    const c=parseInt(document.getElementById('inp-cant').value)||1;
    if (!r){ document.getElementById('inp-regalo').focus(); return; }
    cola.push({regalo:r,cantidad:c,estado:'pendiente'});
    document.getElementById('inp-regalo').value='';
    document.getElementById('inp-cant').value='1';
    renderCola();
    beep(880,.1,.08);
    document.getElementById('inp-regalo').focus();
}
function quitarPremio(i){
    cola.splice(i,1);
    if(idxActivo===i){idxActivo=-1;mostrarEspera();}
    else if(idxActivo>i) idxActivo--;
    renderCola();
}
function seleccionarPremio(i){
    if(corriendo||cola[i].estado==='ejecutado') return;
    idxActivo=i; renderCola(); mostrarActivo();
}
function renderCola(){
    const ul=document.getElementById('lista-premios');
    if(!cola.length){
        ul.innerHTML='<li style="text-align:center;color:#ccc;font-size:.85em;padding:12px 0;">Agrega premios para comenzar</li>';
        return;
    }
    ul.innerHTML=cola.map((p,i)=>`
        <li class="item-p ${i===idxActivo?'activo':''} ${p.estado==='ejecutado'?'ejecutado':''}"
            onclick="seleccionarPremio(${i})">
            <div class="pnum">${i+1}</div>
            <div style="flex:1">
                <div class="pnombre">${esc(p.regalo)}</div>
                <div class="pcant">${p.cantidad} ganador${p.cantidad>1?'es':''}</div>
            </div>
            <span style="font-size:.8rem">${p.estado==='ejecutado'?'✅':i===idxActivo?'▶':''}</span>
            ${p.estado!=='ejecutado'&&!corriendo?`<button class="btn-rm" onclick="event.stopPropagation();quitarPremio(${i})">×</button>`:''}
        </li>`).join('');
}

// ── Paneles ────────────────────────────────────────────────────────
function mostrarEspera(){
    document.getElementById('est-espera').style.display='';
    document.getElementById('est-activo').style.display='none';
}
function mostrarActivo(){
    if(idxActivo<0){mostrarEspera();return;}
    const p=cola[idxActivo];
    document.getElementById('est-espera').style.display='none';
    document.getElementById('est-activo').style.display='';
    document.getElementById('p-nombre').textContent=p.regalo;
    document.getElementById('p-sub').textContent=`${p.cantidad} ganador${p.cantidad>1?'es':''} · Listo para sortear`;
    document.getElementById('slot-wrap').style.display='';
    document.getElementById('cd-wrap').style.display='none';
    document.getElementById('g-wrap').style.display='none';
    document.getElementById('btn-s').style.display='';
    document.getElementById('btn-s').disabled=false;
    document.getElementById('btn-sig').style.display='none';
    document.getElementById('btn-exit-fs').style.display='none';
    pararRuleta(['🎰','🎲','🍀']);
}

// ── Ejecutar sorteo ────────────────────────────────────────────────
async function ejecutar(){
    if(idxActivo<0||corriendo) return;
    const p=cola[idxActivo];
    corriendo=true;
    document.getElementById('btn-s').disabled=true;
    try { getAC(); } catch(e){}

    // ── 0. Pantalla completa ───────────────────────────────────────
    await entrarPantallaCompleta();
    await sleep(300);

    // ── 1. Crear sorteo ────────────────────────────────────────────
    let sorteoId;
    try {
        const fd=new FormData();
        fd.append('accion','crear'); fd.append('csrf_token',CSRF);
        fd.append('regalo',p.regalo); fd.append('cantidad',p.cantidad);
        fd.append('fuente',fuenteActual);
        if (fuenteActual==='quorum' && horaDesde && horaHasta) {
            fd.append('hora_desde', horaDesde);
            fd.append('hora_hasta', horaHasta);
        }
        const res=await fetch(CTRL,{method:'POST',body:fd});
        const txt=await res.text();
        let d; try{d=JSON.parse(txt);}catch(e){throw new Error('Respuesta inválida del servidor');}
        if(!d.ok) throw new Error(d.msg||'Error al crear sorteo');
        sorteoId=d.sorteo_id;
    } catch(e) {
        salirPantallaCompleta();
        pararRuleta();
        mostrarToast(e.message,'err');
        corriendo=false;
        document.getElementById('btn-s').disabled=false;
        return;
    }

    // ── 2. Animación + sonido ruleta ───────────────────────────────
    document.getElementById('slot-wrap').style.display='';
    document.getElementById('cd-wrap').style.display='none';
    iniciarRuleta();
    startRuletaSound();
    await sleep(1400);
    stopRuletaSound();
    pararRuleta();

    // ── 3. Cuenta regresiva dramática 5→1 ─────────────────────────
    document.getElementById('slot-wrap').style.display='none';
    document.getElementById('cd-wrap').style.display='';
    const cdEl=document.getElementById('cd-num');
    const colores=['#1F4E79','#2b6cb0','#dd6b20','#c53030','#c53030'];
    for(let n=5;n>=1;n--){
        cdEl.textContent=n;
        cdEl.style.color=colores[5-n];
        cdEl.classList.remove('bounce');
        await sleep(30); cdEl.classList.add('bounce');
        beepConteo(n);
        await sleep(870);
    }
    cdEl.textContent='🎯'; cdEl.style.color='#1F4E79';

    // ── 4. Ejecutar en BD ──────────────────────────────────────────
    let ganadores;
    try {
        const fd2=new FormData();
        fd2.append('accion','ejecutar'); fd2.append('csrf_token',CSRF);
        fd2.append('sorteo_id',sorteoId);
        fd2.append('fuente',fuenteActual);
        if (fuenteActual==='quorum' && horaDesde && horaHasta) {
            fd2.append('hora_desde', horaDesde);
            fd2.append('hora_hasta', horaHasta);
        }
        const res2=await fetch(CTRL,{method:'POST',body:fd2});
        const txt2=await res2.text();
        let d2; try{d2=JSON.parse(txt2);}catch(e){throw new Error('Respuesta inválida del servidor');}
        if(!d2.ok) throw new Error(d2.msg||'Error al ejecutar sorteo');
        ganadores=d2.ganadores;
    } catch(e) {
        salirPantallaCompleta();
        pararRuleta();
        mostrarToast(e.message,'err');
        corriendo=false;
        document.getElementById('btn-s').disabled=false;
        document.getElementById('slot-wrap').style.display='';
        document.getElementById('cd-wrap').style.display='none';
        return;
    }

    // ── 5. Mostrar ganadores ───────────────────────────────────────
    await sleep(250);
    document.getElementById('cd-wrap').style.display='none';
    document.getElementById('slot-wrap').style.display='none';
    document.getElementById('g-wrap').style.display='';
    document.getElementById('g-grid').innerHTML=ganadores.map((g,i)=>`
        <div class="ganador-card" style="animation-delay:${i*.18}s">
            <div class="ganador-trophy">🏆</div>
            <div class="ganador-nombre">${esc(g.nombre)}</div>
            <div class="ganador-cc">CC ${esc(g.cedula)}</div>
            <div class="ganador-zona">Zona ${esc(g.zona)}</div>
            <div class="ganador-premio">${esc(p.regalo)}</div>
        </div>`).join('');
    document.getElementById('p-sub').textContent='🎉 ¡Ganadores revelados!';

    ovacion();
    await sleep(350);
    confetiFiesta();

    // Mostrar botón salir pantalla completa
    document.getElementById('btn-exit-fs').style.display='';

    // ── 6. Actualizar estado ───────────────────────────────────────
    cola[idxActivo].estado='ejecutado';
    renderCola();
    cargarHistorial();
    refrescarQuorum();
    mostrarToast('¡Sorteo completado con éxito!','ok');

    document.getElementById('btn-s').style.display='none';
    const hayMas=cola.some((c,i)=>i>idxActivo&&c.estado==='pendiente');
    const bs=document.getElementById('btn-sig');
    bs.style.display=''; bs.disabled=!hayMas;
    corriendo=false;
}

function siguiente(){
    salirPantallaCompleta();
    const sig=cola.findIndex((p,i)=>i>idxActivo&&p.estado==='pendiente');
    if(sig>=0){idxActivo=sig;renderCola();mostrarActivo();}
}

// ── Quórum ─────────────────────────────────────────────────────────
async function refrescarQuorum(){
    try{
        const r=await fetch(CTRL+'?accion=disponibles&'+filtroParams());
        const d=await r.json();
        document.getElementById('q-num').textContent=d.ok?d.disponibles:'?';
    }catch(e){}
}

// ── Historial ──────────────────────────────────────────────────────
async function cargarHistorial(){
    try{
        const r=await fetch(CTRL+'?accion=ganadores');
        const d=await r.json();
        const tb=document.getElementById('t-hist');
        if(!d.ok||!d.ganadores.length){
            tb.innerHTML='<tr><td colspan="6" style="text-align:center;color:#ccc;padding:18px;">Sin ganadores aún</td></tr>';
            return;
        }
        tb.innerHTML=d.ganadores.map((g,i)=>`
            <tr>
                <td style="color:#ccc">${i+1}</td>
                <td style="font-weight:600">${esc(g.nombre)}</td>
                <td style="color:#888">${esc(g.cedula)}</td>
                <td style="color:#888">${esc(g.zona)}</td>
                <td><span class="badge-p">${esc(g.regalo)}</span></td>
                <td style="color:#aaa;font-size:.78em">${g.fecha}</td>
            </tr>`).join('');
    }catch(e){}
}

// ── Toast ──────────────────────────────────────────────────────────
function mostrarToast(msg,tipo='ok'){
    const t=document.getElementById('toast');
    t.textContent=tipo==='err'?'⚠ '+msg:'✔ '+msg;
    t.className='toast-msg '+tipo+' show';
    setTimeout(()=>t.classList.remove('show'),4000);
    if(tipo==='err') beep(300,.18,.5,'sawtooth');
}

// ── Utils ──────────────────────────────────────────────────────────
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
function esc(s){
    if(!s) return '—';
    return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}

// ── Enter en campo premio ──────────────────────────────────────────
document.getElementById('inp-regalo').addEventListener('keydown',e=>{
    if(e.key==='Enter') agregarPremio();
});

// ── Init ───────────────────────────────────────────────────────────
refrescarQuorum();
cargarHistorial();
setInterval(refrescarQuorum, 12000);
</script>
</body>
</html>
