<?php
// Depto de Engenharia e Automação - Master Automação - Autor: Derlivon Silva
$nomeEmpresa = trim((string)($config['nome_empresa'] ?? ($config['empresa'] ?? '')));
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<title><?= \App\Core\View::e($titulo ?? 'Avisos de Pratos Prontos') ?></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
<style>
:root{
  --bg:#0a0e14; --bg2:#10151c; --card:#1a2230; --border:#2a3340;
  --txt:#f1f5f9; --muted:#94a3b8; --accent:#10b981;
  --novo:#fbbf24; --urgente:#ef4444;
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html,body{background:var(--bg);color:var(--txt);font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;min-height:100vh;user-select:none}

.av-topbar{display:flex;align-items:center;gap:1rem;padding:1rem 1.4rem;background:var(--bg2);border-bottom:2px solid var(--border)}
.av-logo{display:flex;align-items:center;gap:.6rem;font-size:1.6rem;font-weight:800;color:var(--accent)}
.av-logo i{font-size:2rem}
.av-empresa{font-size:1.1rem;color:var(--muted);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.av-relogio{font-size:1.6rem;font-weight:800;font-variant-numeric:tabular-nums;color:#fff}
.av-status{display:flex;align-items:center;gap:.4rem;font-size:1rem;color:var(--muted)}
.av-status .dot{width:12px;height:12px;border-radius:50%;background:var(--accent);box-shadow:0 0 10px var(--accent)}
.av-som{
  background:rgba(245,158,11,.15);border:2px solid var(--novo);color:var(--novo);
  border-radius:10px;padding:.55rem .9rem;font-size:.95rem;font-weight:700;
  cursor:pointer;display:inline-flex;align-items:center;gap:.4rem;
  animation:somAtenc 1.8s ease-in-out infinite
}
.av-som.ativo{ background:rgba(16,185,129,.15); border-color:var(--accent); color:var(--accent); animation:none }
.av-som:hover{filter:brightness(1.1)}
@keyframes somAtenc {
  0%,100%{ box-shadow: 0 0 0 0 rgba(245,158,11,.6) }
  50%   { box-shadow: 0 0 0 8px rgba(245,158,11,0) }
}

.av-banner{padding:.7rem 1.4rem;background:#131922;border-bottom:1px solid var(--border);font-size:1.1rem;color:var(--muted);display:flex;align-items:center;gap:.6rem}
.av-banner b{color:#fff}

.av-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.2rem;padding:1.4rem}
@media(min-width:1400px){ .av-grid{grid-template-columns:repeat(auto-fill,minmax(420px,1fr))} }

.av-card{
  background:linear-gradient(135deg,#1a2230 0%,#1e3a2e 100%);
  border:3px solid var(--accent);border-radius:18px;padding:1.4rem;
  display:flex;flex-direction:column;gap:.7rem;
  box-shadow:0 0 30px rgba(16,185,129,.25);
  animation:apareceu .35s ease-out;position:relative
}
@keyframes apareceu {
  from{opacity:0;transform:scale(.9)}
  to{opacity:1;transform:scale(1)}
}
.av-card.urgente{
  background:linear-gradient(135deg,#1a2230 0%,#3d1a1a 100%);
  border-color:var(--urgente);
  box-shadow:0 0 40px rgba(239,68,68,.45);
  animation:piscar 1.2s ease-in-out infinite
}
@keyframes piscar {
  0%,100%{box-shadow:0 0 40px rgba(239,68,68,.45)}
  50%{box-shadow:0 0 60px rgba(239,68,68,.8)}
}

.av-cabec{display:flex;align-items:center;justify-content:space-between;gap:.8rem}
.av-mesa{
  font-size:1.1rem;font-weight:800;background:rgba(255,255,255,.12);
  padding:.3rem .8rem;border-radius:8px;letter-spacing:.5px
}
.av-tempo{
  font-size:1.6rem;font-weight:800;font-variant-numeric:tabular-nums;
  color:var(--accent)
}
.av-card.urgente .av-tempo{color:#fecaca}

.av-garcom{
  font-size:2.1rem;font-weight:800;color:#fff;
  display:flex;align-items:center;gap:.6rem;line-height:1.1;
  letter-spacing:-.02em
}
.av-garcom i{color:var(--accent);font-size:1.6rem}
.av-card.urgente .av-garcom i{color:var(--urgente)}

.av-prato{
  font-size:1.5rem;font-weight:700;line-height:1.2;
  background:rgba(0,0,0,.25);padding:.7rem .9rem;border-radius:10px
}
.av-qtd{
  display:inline-block;background:rgba(255,255,255,.15);font-weight:800;
  padding:.1rem .5rem;border-radius:5px;font-size:1.3rem;margin-right:.4rem
}

.av-btn{
  background:var(--accent);color:#000;border:none;border-radius:12px;
  padding:1.2rem 1.2rem;font-size:1.5rem;font-weight:800;cursor:pointer;
  text-transform:uppercase;letter-spacing:.5px;
  display:flex;align-items:center;justify-content:center;gap:.6rem;
  margin-top:auto;width:100%
}
.av-btn:hover{filter:brightness(1.12)}
.av-btn:active{transform:scale(.96)}
.av-card.urgente .av-btn{background:#fecaca;color:#7f1d1d}

.av-vazio{
  grid-column:1/-1;text-align:center;padding:6rem 2rem;color:var(--muted)
}
.av-vazio i{font-size:6rem;color:#3b4252;display:block;margin-bottom:1rem}
.av-vazio h1{font-size:2.4rem;color:#94a3b8;margin-bottom:.5rem;font-weight:700}
.av-vazio p{font-size:1.3rem}

.av-rodape{text-align:center;padding:.6rem;font-size:.8rem;color:#475569;border-top:1px solid var(--border);background:#070a0e}

/* Modal de garcons (quem retirou) */
.av-modal-bg{
  position:fixed;inset:0;background:rgba(0,0,0,.85);display:none;
  align-items:center;justify-content:center;padding:1rem;z-index:300
}
.av-modal-bg.aberto{display:flex}
.av-modal{
  background:#1a2230;border:2px solid var(--accent);border-radius:18px;
  padding:1.4rem;max-width:600px;width:100%;max-height:90vh;
  display:flex;flex-direction:column;gap:1rem
}
.av-modal-titulo{font-size:1.5rem;font-weight:800;display:flex;align-items:center;gap:.6rem}
.av-modal-titulo i{color:var(--accent);font-size:1.8rem}
.av-modal-sub{color:var(--muted);font-size:1rem;margin-top:-.5rem}
.av-modal-busca{
  background:#0d141d;border:2px solid var(--border);color:#fff;
  border-radius:10px;padding:.85rem 1rem;font-size:1.1rem;width:100%;
  font-weight:600
}
.av-modal-busca:focus{outline:none;border-color:var(--accent)}
.av-modal-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:.5rem;overflow-y:auto;max-height:45vh
}
.av-modal-btn{
  background:#0d141d;border:2px solid var(--border);color:var(--txt);
  padding:.6rem .5rem;border-radius:8px;font-size:.92rem;font-weight:700;
  cursor:pointer;text-align:center;display:flex;align-items:center;justify-content:center;gap:.3rem;
  min-height:48px;line-height:1.15
}
.av-modal-btn:hover{ background:rgba(16,185,129,.15); border-color:var(--accent); color:var(--accent) }
.av-modal-btn.recente{ background:rgba(99,102,241,.15); border-color:#6366F1; color:#a5b4fc }
.av-modal-vazio{
  grid-column:1/-1;text-align:center;padding:1.5rem;color:var(--muted);font-size:.95rem
}
.av-modal-cancela{
  background:transparent;border:1px solid var(--border);color:var(--muted);
  padding:.7rem;border-radius:10px;cursor:pointer;font-size:.95rem
}

.av-toast{
  position:fixed;bottom:1.5rem;left:50%;transform:translateX(-50%) translateY(120px);
  background:var(--accent);color:#000;padding:1rem 2rem;border-radius:12px;
  font-size:1.4rem;font-weight:800;box-shadow:0 8px 30px rgba(0,0,0,.5);
  transition:transform .25s ease-out;z-index:200;display:flex;align-items:center;gap:.6rem
}
.av-toast.show{transform:translateX(-50%) translateY(0)}
</style>
</head>
<body>

<div class="av-topbar">
    <div class="av-logo"><i class="bi bi-bell-fill"></i><span>Pratos Prontos</span></div>
    <div class="av-empresa"><?= \App\Core\View::e($nomeEmpresa) ?></div>
    <button class="av-som" id="avSom" onclick="ativarSom(true)" title="Ativar/testar som">
        <i class="bi bi-volume-up-fill" id="avSomIco"></i>
        <span id="avSomTxt">Ativar som</span>
    </button>
    <div class="av-status" id="avStatus"><span class="dot"></span>Conectado</div>
    <div class="av-relogio" id="avRelogio">--:--:--</div>
</div>

<div class="av-banner">
    <i class="bi bi-info-circle"></i>
    <span>Quando o prato sai da cozinha, aparece aqui. Toque em <b>RETIREI</b> ao buscar pra que ele suma do painel.</span>
</div>

<div class="av-grid" id="avGrid">
    <div class="av-vazio">
        <i class="bi bi-hourglass"></i>
        <h1>Aguardando…</h1>
    </div>
</div>

<div class="av-toast" id="avToast"><i class="bi bi-check-circle-fill"></i><span id="avToastTxt">OK</span></div>

<!-- Modal: quem retirou? -->
<div class="av-modal-bg" id="modalQuem">
    <div class="av-modal">
        <div class="av-modal-titulo"><i class="bi bi-person-check-fill"></i> Quem está retirando?</div>
        <div class="av-modal-sub">Digite seu nome ou toque no botão.</div>
        <input type="text" class="av-modal-busca" id="modalBusca" placeholder="🔍 Digite seu nome…" autocomplete="off">
        <div class="av-modal-grid" id="modalGrid"></div>
        <button class="av-modal-cancela" onclick="fecharModal()">Cancelar</button>
    </div>
</div>

<div class="av-rodape">
    Fire Sistemas &middot; Premium Express BI v<?= \App\Core\View::e(\App\Core\Versao::ATUAL) ?> &middot; Pratos Prontos
</div>

<script>
'use strict';
const POLLING_MS = 5000;
let avisosAtuais = [];
let chavesNoUI = new Set();
let bloqueado = new Set();

// ── Alerta sonoro + vibração — gerado em runtime via WebAudio ───────────────
const audioCtx = (window.AudioContext || window.webkitAudioContext) ? new (window.AudioContext || window.webkitAudioContext)() : null;
let audioHabilitado = false;

function umBeep(freq, durSeg, atrasoSeg){
  if (!audioCtx) return;
  const t0 = audioCtx.currentTime + atrasoSeg;
  const o = audioCtx.createOscillator();
  const g = audioCtx.createGain();
  o.connect(g); g.connect(audioCtx.destination);
  o.type = 'sine'; o.frequency.value = freq;
  g.gain.setValueAtTime(0.0001, t0);
  g.gain.exponentialRampToValueAtTime(0.95, t0 + 0.02);  // volume CHEIO (era 0.4)
  g.gain.exponentialRampToValueAtTime(0.0001, t0 + durSeg);
  o.start(t0);
  o.stop(t0 + durSeg + 0.05);
}

function alertaCompleto(){
  if (!audioCtx) return;
  if (audioCtx.state === 'suspended') {
    audioCtx.resume().catch(()=>{});
  }
  try {
    // 3 bipes (era 2): grave-agudo-grave bem audível
    umBeep(880,  0.35, 0.00);
    umBeep(1320, 0.35, 0.40);
    umBeep(880,  0.50, 0.80);
  } catch(e){}
  // Vibração 3 pulsos longos (Android)
  if (navigator.vibrate) {
    try { navigator.vibrate([400, 150, 400, 150, 600]); } catch(e){}
  }
}

// Alias antigo
function beep(){ alertaCompleto(); }

const z = n => String(n).padStart(2,'0');
function tickRelogio(){
  const d = new Date();
  document.getElementById('avRelogio').textContent = z(d.getHours())+':'+z(d.getMinutes())+':'+z(d.getSeconds());
}
setInterval(tickRelogio, 1000);
tickRelogio();

function escape(s){
  if (s === null || s === undefined) return '';
  return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[c]);
}

function toast(msg){
  const t = document.getElementById('avToast');
  document.getElementById('avToastTxt').textContent = msg;
  t.classList.add('show');
  setTimeout(()=>t.classList.remove('show'), 1800);
}

function chaveDe(a){ return a.cod_empresa + '|' + a.cod_abertura + '|' + a.cod_lanc; }

function tempoPronto(seg){
  if (seg < 60) return seg + ' seg';
  const m = Math.floor(seg/60), s = seg%60;
  return m + 'm ' + (s<10?'0':'') + s + 's';
}

function cardHtml(a){
  const seg = a.seg_pronto || 0;
  const urgente = seg > 120; // 2 min sem retirar = pisca
  const garcom = (a.garcom || '').trim() || 'Garçom';
  const obs = (a.observacao || '').trim();
  const qtd = parseFloat(a.qtd) || 1;
  const qtdLbl = qtd >= 1 ? Math.round(qtd) : qtd.toFixed(2);
  const chave = chaveDe(a);
  return `
    <div class="av-card ${urgente?'urgente':''}" data-key="${chave}">
      <div class="av-cabec">
        <span class="av-mesa"><i class="bi bi-grid-3x3-gap-fill"></i> Mesa ${escape(a.cod_mesa)}</span>
        <span class="av-tempo">${tempoPronto(seg)}</span>
      </div>
      <div class="av-garcom"><i class="bi bi-person-fill"></i> ${escape(garcom)}</div>
      <div class="av-prato"><span class="av-qtd">${qtdLbl}x</span>${escape(a.produto)}${obs?'<br><small style="color:#fbbf24">obs: '+escape(obs)+'</small>':''}</div>
      <button class="av-btn" onclick="retirar(${a.cod_empresa}, ${a.cod_abertura}, ${a.cod_lanc}, this)">
        <i class="bi bi-hand-thumbs-up-fill"></i> Retirei
      </button>
    </div>
  `;
}

function render(){
  const grid = document.getElementById('avGrid');
  const visiveis = avisosAtuais.filter(a => !bloqueado.has(chaveDe(a)));
  if (!visiveis.length) {
    grid.innerHTML = '<div class="av-vazio"><i class="bi bi-emoji-smile"></i><h1>Tudo entregue</h1><p>Sem pratos prontos pendentes.</p></div>';
    return;
  }
  grid.innerHTML = visiveis.map(cardHtml).join('');
}

// Guarda quais chaves já avisamos (pra re-alertar a cada 30s se ninguém retirar)
const jaAvisei = new Map(); // chave -> timestamp do último beep
const RE_ALERTA_MS = 30000;

async function carregar(){
  try {
    const r = await fetch('/api/cozinha/avisos-pendentes', { credentials:'same-origin', cache:'no-store' });
    if (!r.ok) throw new Error('HTTP ' + r.status);
    const j = await r.json();

    const novasChaves = new Set((j.avisos||[]).map(chaveDe));
    const antigasChaves = new Set(avisosAtuais.map(chaveDe));
    let temNovo = false;
    novasChaves.forEach(k => {
      if (!antigasChaves.has(k) && !bloqueado.has(k) && !jaAvisei.has(k)) temNovo = true;
    });

    // Re-alerta: prato que ainda tá aí há mais de 30s sem ser retirado, bipe DE NOVO
    const agora = Date.now();
    let temAtrasado = false;
    novasChaves.forEach(k => {
      const ult = jaAvisei.get(k);
      if (ult && (agora - ult) > RE_ALERTA_MS && !bloqueado.has(k)) temAtrasado = true;
    });

    avisosAtuais = j.avisos || [];
    render();

    if (temNovo || temAtrasado) {
      alertaCompleto();
      novasChaves.forEach(k => jaAvisei.set(k, agora));
    }

    // Limpa controle de chaves que já foram retiradas
    Array.from(jaAvisei.keys()).forEach(k => { if (!novasChaves.has(k)) jaAvisei.delete(k); });

    document.getElementById('avStatus').innerHTML = '<span class="dot"></span>Conectado';
  } catch (e) {
    document.getElementById('avStatus').innerHTML = '<span class="dot" style="background:#ef4444;box-shadow:0 0 10px #ef4444"></span>Sem conexao';
  }
}

let GARCONS = [];
let avisoEmRetirada = null; // {codEmpresa, codAbertura, codLanc, btn}

async function carregarGarcons(){
  try {
    const r = await fetch('/api/cozinha/garcons', { credentials:'same-origin' });
    const j = await r.json();
    if (Array.isArray(j.garcons)) GARCONS = j.garcons;
  } catch (e) { /* segue sem lista — modal vai aparecer com 'Outro' */ }
}

function abrirModalQuem(codEmpresa, codAbertura, codLanc, btn){
  const chave = codEmpresa + '|' + codAbertura + '|' + codLanc;
  if (bloqueado.has(chave)) return;
  avisoEmRetirada = { codEmpresa, codAbertura, codLanc, chave, btn };

  document.getElementById('modalBusca').value = '';
  renderListaGarcons('');
  document.getElementById('modalQuem').classList.add('aberto');
  // Auto-foco no input (mas só se NÃO for telinha com teclado virtual obrigatorio em TV)
  setTimeout(() => {
    const input = document.getElementById('modalBusca');
    if (input && window.innerWidth > 600) input.focus();
  }, 100);
}

function renderListaGarcons(filtro){
  const grid = document.getElementById('modalGrid');
  const f = (filtro || '').trim().toLowerCase();

  // Memoria: ultimo garcom usado nos ultimos 10min (LocalStorage)
  const recente = localStorage.getItem('kds_ultimo_garcom') || '';
  const tsRecente = parseInt(localStorage.getItem('kds_ultimo_garcom_ts') || '0', 10);
  const ainda = (Date.now() - tsRecente) < 10*60*1000 && recente;

  let html = '';
  const filtra = (nome) => !f || nome.toLowerCase().includes(f);

  if (ainda && filtra(recente)) {
    html += `<button class="av-modal-btn recente" onclick="confirmarRetirada('${escape(recente).replace(/'/g,"\\'")}')"><i class="bi bi-star-fill"></i> ${escape(recente)}</button>`;
  }
  let achou = 0;
  GARCONS.forEach(g => {
    if (ainda && g.NOME === recente) return;
    if (!filtra(g.NOME)) return;
    html += `<button class="av-modal-btn" onclick="confirmarRetirada('${escape(g.NOME).replace(/'/g,"\\'")}')">${escape(g.NOME)}</button>`;
    achou++;
  });
  if (!GARCONS.length && !ainda) {
    html += '<button class="av-modal-btn" onclick="confirmarRetirada(\'Balcao\')">Outro / sem identificar</button>';
  } else if (achou === 0 && !ainda) {
    html += '<div class="av-modal-vazio">Nenhum garçom encontrado pra "' + escape(filtro) + '"</div>';
  }
  grid.innerHTML = html;
}

// Filtra em tempo real conforme digita
document.addEventListener('DOMContentLoaded', () => {
  const input = document.getElementById('modalBusca');
  if (input) {
    input.addEventListener('input', e => renderListaGarcons(e.target.value));
    // Enter no input = seleciona o primeiro garçom da lista filtrada
    input.addEventListener('keydown', e => {
      if (e.key === 'Enter') {
        const primeiro = document.querySelector('#modalGrid .av-modal-btn');
        if (primeiro) primeiro.click();
      }
    });
  }
});

function fecharModal(){
  document.getElementById('modalQuem').classList.remove('aberto');
  avisoEmRetirada = null;
}

async function confirmarRetirada(nomeGarcom){
  if (!avisoEmRetirada) return;
  const { codEmpresa, codAbertura, codLanc, chave, btn } = avisoEmRetirada;
  document.getElementById('modalQuem').classList.remove('aberto');

  // Memoriza pro próximo (atalho 10min)
  localStorage.setItem('kds_ultimo_garcom', nomeGarcom);
  localStorage.setItem('kds_ultimo_garcom_ts', String(Date.now()));

  if (bloqueado.has(chave)) return;
  bloqueado.add(chave);
  if (btn) { btn.disabled = true; btn.innerHTML = '<i class="bi bi-hourglass-split"></i> Retirando…'; }

  try {
    const r = await fetch('/api/cozinha/marcar-retirado', {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      credentials:'same-origin',
      body:JSON.stringify({
        cod_empresa: codEmpresa, cod_abertura: codAbertura, cod_lanc: codLanc,
        retirado_por: nomeGarcom
      })
    });
    const j = await r.json();
    if (!r.ok || j.erro) throw new Error(j.erro || 'Falha');

    const card = document.querySelector(`.av-card[data-key="${chave}"]`);
    if (card) {
      card.style.transition = 'opacity .3s, transform .3s';
      card.style.opacity = '0';
      card.style.transform = 'scale(.85)';
      setTimeout(()=>{ render(); }, 300);
    }
    toast('Retirado por ' + nomeGarcom);
    setTimeout(carregar, 400);
  } catch (e) {
    bloqueado.delete(chave);
    if (btn) { btn.disabled = false; btn.innerHTML = '<i class="bi bi-hand-thumbs-up-fill"></i> Retirei'; }
    toast('Erro: ' + e.message);
  }
  avisoEmRetirada = null;
}

// Alias antigo do botão — agora abre o modal
function retirar(codEmpresa, codAbertura, codLanc, btn){
  abrirModalQuem(codEmpresa, codAbertura, codLanc, btn);
}

window.retirar = retirar;
window.confirmarRetirada = confirmarRetirada;
window.fecharModal = fecharModal;

// Atualiza timer dos cards a cada segundo sem refetch
setInterval(() => {
  avisosAtuais = avisosAtuais.map(a => ({ ...a, seg_pronto: (a.seg_pronto || 0) + 1 }));
  document.querySelectorAll('.av-card').forEach(card => {
    const key = card.getAttribute('data-key');
    const aviso = avisosAtuais.find(a => chaveDe(a) === key);
    if (!aviso) return;
    const tempoEl = card.querySelector('.av-tempo');
    if (tempoEl) tempoEl.textContent = tempoPronto(aviso.seg_pronto);
    if (aviso.seg_pronto > 120 && !card.classList.contains('urgente')) card.classList.add('urgente');
  });
}, 1000);

// Wake Lock pra TV/tablet nao apagar
if ('wakeLock' in navigator) {
  navigator.wakeLock.request('screen').catch(()=>{});
}

function ativarSom(tocarTeste){
    if (!audioCtx) return;
    if (audioCtx.state === 'suspended') {
        audioCtx.resume().catch(()=>{});
    }
    audioHabilitado = true;
    const btn = document.getElementById('avSom');
    btn.classList.add('ativo');
    document.getElementById('avSomIco').className = 'bi bi-volume-up-fill';
    document.getElementById('avSomTxt').textContent = 'Som ativo';
    if (tocarTeste) {
        alertaCompleto();
        toast('Som testado — agora você vai ouvir os avisos');
    }
}
window.ativarSom = ativarSom;

// Tenta destravar audio em qualquer interacao do usuario (1a vez)
['click','touchstart','keydown'].forEach(ev => {
    document.addEventListener(ev, () => { if (!audioHabilitado) ativarSom(false); }, { once:false, passive:true });
});

carregarGarcons();
carregar();
setInterval(carregar, POLLING_MS);
// Recarrega lista de garçons a cada 30 min (entrou alguém novo no ERP)
setInterval(carregarGarcons, 30*60*1000);
</script>

</body>
</html>
