<?php
require_once __DIR__ . "/_bootstrap.php";

//if (file_exists(__DIR__ . "/../verifica_login.php")) {
//  include __DIR__ . "/../verifica_login.php";
//} elseif (file_exists(__DIR__ . "/../includes/verifica_login.php")) {
//  include __DIR__ . "/../includes/verifica_login.php";
//}
?>
<!doctype html>
<html lang="pt-br">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
  <title>Balcão • Fatura por Sessão</title>

  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">

  <style>
    /* ====== Windows 10 Dark (padrão do projeto) ====== */
    :root{
      --bg:#1e1e1e;          /* fundo Win10 */
      --card:#252526;        /* superfície */
      --card2:#2d2d30;       /* superfície elevada */
      --text:#f3f3f3;
      --muted:#bdbdbd;
      --line: rgba(255,255,255,.10);

      --shadow: 0 10px 24px rgba(0,0,0,.45);
      --radius: 14px;

      --accent:#0078d4;      /* azul Win10 */
      --accent2:#2b88d8;

      --ok:#22c55e;
      --warn:#f59e0b;
      --danger:#ff5a5f;

      --btn:#2d2d30;         /* botão "flat" */
      --btnHover:#3a3a3d;

      --input:#1f1f1f;
      --focus: rgba(0,120,212,.45);
    }

    [data-theme="light"]{
      --bg:#f3f3f3;
      --card:#ffffff;
      --card2:#f7f7f7;
      --text:#111827;
      --muted:#4b5563;
      --line: rgba(17,24,39,.12);

      --shadow: 0 10px 24px rgba(17,24,39,.12);

      --accent:#0078d4;
      --accent2:#2b88d8;

      --ok:#16a34a;
      --warn:#b45309;
      --danger:#dc2626;

      --btn:#f3f4f6;
      --btnHover:#e5e7eb;

      --input:#ffffff;
      --focus: rgba(0,120,212,.35);
    }

    *{ box-sizing:border-box; }
    body{
      margin:0;
      font-family: "Segoe UI", system-ui, -apple-system, Roboto, Arial;
      background: var(--bg);
      color: var(--text);
    }

    .app{ min-height: 100vh; display:grid; grid-template-columns: 360px 1fr; }
    @media (max-width: 992px){
      .app{ grid-template-columns: 1fr; }
      .sidebar{ border-right:0 !important; border-bottom:1px solid var(--line); }
    }
    .sidebar{ border-right:1px solid var(--line); padding:16px; background: color-mix(in srgb, var(--bg) 82%, #000 18%); }
    .main{ padding:16px; }

    .brand{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:14px; }
    .btitle{ display:flex; align-items:center; gap:10px; }
    .logo{
      width:44px; height:44px; border-radius: 12px;
      background: linear-gradient(135deg, var(--accent), var(--accent2));
      box-shadow: var(--shadow);
      display:flex; align-items:center; justify-content:center;
      font-size:20px; flex: 0 0 auto;
      border:1px solid rgba(255,255,255,.08);
    }
    .btitle h1{ font-size:16px; margin:0; font-weight:900; }
    .sub{ color:var(--muted); font-size:12px; margin-top:2px; }

    /* Botões (flat Win10) */
    .btnGhost{
      border:1px solid var(--line);
      background: var(--btn);
      color: var(--text);
      padding:10px 12px;
      border-radius: 10px;
      cursor:pointer;
      font-weight: 800;
      transition: background .12s ease, transform .06s ease;
      user-select:none;
    }
    .btnGhost:hover{ background: var(--btnHover); }
    .btnGhost:active{ transform: translateY(1px); }

    .btnOk{
      border:none;
      background: linear-gradient(135deg, var(--ok), color-mix(in srgb, var(--ok) 70%, #000 30%));
      color:#fff;
      padding:10px 12px;
      border-radius: 10px;
      cursor:pointer;
      font-weight: 900;
      box-shadow: var(--shadow);
      transition: filter .12s ease, transform .06s ease;
    }
    .btnOk:hover{ filter: brightness(1.05); }
    .btnOk:active{ transform: translateY(1px); }
    .btnOk:disabled{ opacity:.55; cursor:not-allowed; }

    .btnWarn{
      border:none;
      background: linear-gradient(135deg, var(--warn), color-mix(in srgb, var(--warn) 70%, #000 30%));
      color:#fff;
      padding:10px 12px;
      border-radius: 10px;
      cursor:pointer;
      font-weight: 900;
      box-shadow: var(--shadow);
      transition: filter .12s ease, transform .06s ease;
    }
    .btnWarn:hover{ filter: brightness(1.05); }
    .btnWarn:active{ transform: translateY(1px); }

    .btnDanger{
      border:none;
      background: linear-gradient(135deg, var(--danger), color-mix(in srgb, var(--danger) 70%, #000 30%));
      color:#fff;
      padding:10px 12px;
      border-radius: 10px;
      cursor:pointer;
      font-weight: 900;
      box-shadow: var(--shadow);
      transition: filter .12s ease, transform .06s ease;
    }
    .btnDanger:hover{ filter: brightness(1.05); }
    .btnDanger:active{ transform: translateY(1px); }

    /* Inputs */
    .search{
      width:100%;
      border:1px solid var(--line);
      background: var(--input);
      color: var(--text);
      padding: 10px 12px;
      border-radius: 10px;
      outline:none;
    }
    .search::placeholder{ color: color-mix(in srgb, var(--muted) 80%, transparent); }
    .search:focus{
      border-color: rgba(0,120,212,.65);
      box-shadow: 0 0 0 3px var(--focus);
    }

    .list{
      margin-top:12px;
      display:grid;
      gap:10px;
      max-height: calc(100vh - 200px);
      overflow:auto;
      padding-right:4px;
    }
    .item{
      border:1px solid var(--line);
      background: var(--card2);
      border-radius: 12px;
      padding: 12px;
      cursor:pointer;
      transition: transform .06s ease, background .12s ease;
    }
    .item:hover{ transform: translateY(-1px); background: color-mix(in srgb, var(--card2) 88%, #fff 12%); }
    .item.active{ outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent); }

    .row1{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
    .mesa{ font-weight: 900; font-size: 14px; }
    .pill{
      border:1px solid var(--line);
      padding:4px 10px;
      border-radius: 999px;
      font-size: 12px;
      color: var(--muted);
      background: rgba(255,255,255,.04);
      white-space: nowrap;
    }

    .saldo{ font-weight: 900; font-size: 14px; }
    .saldo.ok{ color: var(--ok); }
    .saldo.warn{ color: var(--warn); }
    .saldo.danger{ color: var(--danger); }

    .topbar{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:12px; }
    .titleMain{ font-weight: 900; font-size: 16px; margin:0; }

    .totais{
      display:grid;
      grid-template-columns: repeat(5, 1fr);
      gap:10px;
    }
    @media (max-width: 1200px){ .totais{ grid-template-columns: 1fr 1fr; } }
    @media (max-width: 600px){ .totais{ grid-template-columns: 1fr; } }

    .kpi{
      border:1px solid var(--line);
      background: var(--card);
      border-radius: 12px;
      padding: 12px;
      box-shadow: var(--shadow);
    }
    .kpi .k{ color: var(--muted); font-size: 12px; }
    .kpi .v{ font-weight: 900; font-size: 18px; margin-top: 2px; }

    .cardx{
      border:1px solid var(--line);
      background: var(--card);
      border-radius: 14px;
      box-shadow: var(--shadow);
      overflow:hidden;
      margin-top: 12px;
    }
    .cardx .head{ padding:14px; border-bottom:1px solid var(--line); background: var(--card2); }
    .cardx .body{ padding:14px; }

    .sessWrap{ display:grid; gap: 10px; }
    .sess{
      border:1px solid var(--line);
      background: var(--card);
      border-radius: 14px;
      padding: 14px;
      box-shadow: var(--shadow);
    }
    .sessTop{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom: 8px; }
    .sessName{ font-weight: 900; }
    .sessKey{ color: var(--muted); font-size: 12px; }

    .sessGrid{ display:grid; grid-template-columns: repeat(6, 1fr); gap:10px; }
    @media (max-width: 1200px){ .sessGrid{ grid-template-columns: 1fr 1fr; } }
    @media (max-width: 600px){ .sessGrid{ grid-template-columns: 1fr; } }

    .mini{
      border:1px solid var(--line);
      border-radius: 12px;
      padding: 10px 12px;
      background: rgba(255,255,255,.04);
    }
    .mini .k{ color: var(--muted); font-size: 12px; }
    .mini .v{ font-weight: 900; margin-top: 2px; }

    .muted{ color: var(--muted); }

    /* Modal (Win10 dark) */
    .modal-content{
      background: var(--card);
      color: var(--text);
      border:1px solid var(--line);
      border-radius: 14px;
    }
    .modal-header, .modal-footer{ border-color: var(--line); background: var(--card2); }

    .form-control, .form-select{
      background: var(--input);
      color: var(--text);
      border:1px solid var(--line);
      border-radius: 10px;
      outline:none;
    }
    .form-control:focus, .form-select:focus{
      border-color: rgba(0,120,212,.65);
      box-shadow: 0 0 0 3px var(--focus);
    }
    .form-control::placeholder{ color: color-mix(in srgb, var(--muted) 80%, transparent); }

    /* Botão fechar do bootstrap (auto no tema) */
    .btn-close{ filter: none; opacity: .85; }
    [data-theme="dark"] .btn-close{ filter: invert(1) grayscale(100%); opacity: .9; }

    .line{ border-top:1px solid var(--line); margin:10px 0; }
    .itRow{
      border:1px solid var(--line);
      border-radius: 12px;
      padding: 10px 12px;
      background: rgba(255,255,255,.04);
      display:flex;
      justify-content:space-between;
      gap:10px;
      margin-bottom: 8px;
    }
    .itRow .nm{ font-weight: 900; }
    .itRow .obs{ color: var(--muted); font-size: 12px; margin-top: 2px; }
  </style>

<?php if (!empty($ONLY_CARTAO)): ?>
<style>
  /* Modo "somente cartao" (usado por /cartao/index.php) */
  .app{ display:none !important; }
  body{ padding:16px; }
  #cartaoBalModal{
    display:flex !important;
    position:relative !important;
    inset:auto !important;
    background: transparent !important;
    padding:0 !important;
  }
</style>
<?php endif; ?>



</head>

<body>
<div class="app">

  <aside class="sidebar">
    <div class="brand">
      <div class="btitle">
        <div class="logo">💳</div>
        <div>
          <h1>Balcão</h1>
          <div class="sub">Fatura só após ENTREGUE • parcial + avulso por sessão</div>
        </div>
      </div>
      <button class="btnGhost" onclick="toggleTheme()">🌗 Tema</button>
      <a class="btnGhost" href="../cartao/index.php" style="text-decoration:none;display:inline-block;text-align:center;">💳 Cartões</a>
    </div>

    <input id="search" class="search" placeholder="Buscar mesa/conta…" oninput="renderLista()">
    <div class="sub mt-2" id="infoLista">Carregando…</div>
    <div class="list" id="listaContas"></div>

    <div class="mt-3 d-grid gap-2">
      <button class="btnGhost" onclick="carregarContas()">🔄 Atualizar lista</button>
    </div>
  </aside>

  <main class="main">
    <div class="topbar">
      <div>
        <h2 class="titleMain" id="tituloMesa">Selecione uma mesa</h2>
        <div class="sub" id="subMesa">Contas abertas aparecerão na esquerda</div>
      </div>

      <div class="d-flex gap-2 flex-wrap">
        <button class="btnGhost" id="btnVerFaturaMesa" onclick="abrirFaturaMesa()" disabled>🧾 Ver fatura</button>
        <button class="btnWarn" id="btnPagarParcialMesa" onclick="abrirPagamentoParcialMesa()" disabled>💸 Pagamento parcial</button>
        <button class="btnDanger" id="btnLancamentoAvulso" onclick="abrirLancamentoAvulso()" disabled>➕ Lançamento avulso</button>
        <button class="btnGhost" id="btnFecharConta" onclick="fecharConta()" disabled>✅ Fechar conta</button>
      </div>
    </div>

    <!-- KPIs mesa -->
    <div class="totais">
      <div class="kpi">
        <div class="k">FATURA (ENTREGUE + avulsos)</div>
        <div class="v" id="kpiFatura">R$ 0,00</div>
      </div>
      <div class="kpi">
        <div class="k">ENTREGUE</div>
        <div class="v" id="kpiEntregue">R$ 0,00</div>
      </div>
      <div class="kpi">
        <div class="k">ANDAMENTO (não cobra)</div>
        <div class="v" id="kpiAndamento">R$ 0,00</div>
      </div>
      <div class="kpi">
        <div class="k">PAGO</div>
        <div class="v" id="kpiPago">R$ 0,00</div>
      </div>
      <div class="kpi">
        <div class="k">SALDO (fatura)</div>
        <div class="v" id="kpiSaldo">R$ 0,00</div>
      </div>
    </div>

    <div class="cardx">
      <div class="head">
        <div style="font-weight:900">Sessões desta mesa</div>
        <div class="sub">Saldo só considera o que já virou fatura (ENTREGUE + avulsos)</div>
      </div>
      <div class="body">
        <div id="sessoes" class="sessWrap">
          <div class="muted">Selecione uma conta para visualizar.</div>
        </div>
      </div>
    </div>
  </main>
</div>

<!-- Modal Pagamento -->
<div class="modal fade" id="modalPagamento" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <div>
          <div style="font-weight:900" id="mpTitulo">Receber pagamento</div>
          <div class="sub" id="mpSub">—</div>
        </div>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
      </div>

      <div class="modal-body" style="display:grid; gap:10px;">
        <div id="mpSessaoWrap" style="display:none;">
          <label class="form-label sub mb-1">Sessão para abater</label>
          <select id="mpSessao" class="form-select"></select>
          <div class="sub mt-1">Saldo da fatura da sessão:<strong id="mpSaldo">R$ 0,00<strong></div>
        </div>

        <div>
          <label class="form-label sub mb-1">Valor</label>
          <input id="mpValor" class="form-control" inputmode="decimal" placeholder="Ex.: 35.50">
        </div>

        <div>
          <label class="form-label sub mb-1">Método</label>
          <select id="mpMetodo" class="form-select">
            <option value="PIX">PIX</option>
            <option value="DINHEIRO">Dinheiro</option>
            <option value="CARTAO_CREDITO">Cartão Crédito</option>
            <option value="CARTAO_DEBITO">Cartão Débito</option>
            <option value="OUTRO">Outro</option>
          </select>
        
        <div id="mpDinheiroWrap" style="display:none;">
          <label class="form-label sub mb-1">Valor recebido (dinheiro)</label>
          <input id="mpRecebido" class="form-control" inputmode="decimal" placeholder="Ex.: 50.00">
          <div class="sub mt-1">Troco: <strong><b id="mpTroco">R$ 0,00</strong></div>
        </div>
</div>

        <div id="mpErro" class="muted" style="display:none; color: var(--danger); font-weight:900;"></div>
      </div>

      <div class="modal-footer">
        <button class="btnGhost" data-bs-dismiss="modal">Cancelar</button>
        <button class="btnOk" id="mpConfirmar" onclick="confirmarPagamento()">Confirmar</button>
      </div>
    </div>
  </div>
</div>

<!-- Modal Avulso -->
<div class="modal fade" id="modalAvulso" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <div>
          <div style="font-weight:900">➕ Lançamento avulso</div>
          <div class="sub" id="maSub">—</div>
        </div>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
      </div>

      <div class="modal-body" style="display:grid; gap:10px;">
        <div>
          <label class="form-label sub mb-1">Sessão</label>
          <select id="maSessao" class="form-select"></select>
        </div>

        <div>
          <label class="form-label sub mb-1">Valor</label>
          <input id="maValor" class="form-control" inputmode="decimal" placeholder="Ex.: 10.00">
        </div>

        <div>
          <label class="form-label sub mb-1">Descrição</label>
          <input id="maDesc" class="form-control" placeholder="Ex.: item extra / taxa / acréscimo…">
        </div>

        <div id="maErro" class="muted" style="display:none; color: var(--danger); font-weight:900;"></div>
      </div>

      <div class="modal-footer">
        <button class="btnGhost" data-bs-dismiss="modal">Cancelar</button>
        <button class="btnDanger" id="maConfirmar" onclick="confirmarAvulso()">Lançar</button>
      </div>
    </div>
  </div>
</div>

<!-- Modal Fatura (NOVO) -->
<div class="modal fade" id="modalFatura" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <div>
          <div style="font-weight:900" id="mfTitulo">🧾 Itens da fatura</div>
          <div class="sub" id="mfSub">—</div>
        </div>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
      </div>

      <div class="modal-body">
        <div class="sub mb-2" id="mfTotais">—</div>
        <div id="mfBody" class="muted">Carregando…</div>
      </div>

      <div class="modal-footer">
        <button class="btnGhost" data-bs-dismiss="modal">Fechar</button>
      </div>
    </div>
  </div>
</div>

<!-- Modal Mensagens (Info/Sucesso/Erro) -->
<div class="modal fade" id="modalMsg" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <div>
          <div style="font-weight:900" id="mmTitulo">Mensagem</div>
          <div class="sub" id="mmSub" style="display:none">—</div>
        </div>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
      </div>

      <div class="modal-body">
        <div id="mmBody" class="muted">—</div>
      </div>

      <div class="modal-footer">
        <button class="btnOk" id="mmOk" data-bs-dismiss="modal">OK</button>
      </div>
    </div>
  </div>
</div>

<!-- Modal Confirmar -->
<div class="modal fade" id="modalConfirm" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <div>
          <div style="font-weight:900" id="mcTitulo">Confirmar</div>
          <div class="sub" id="mcSub" style="display:none">—</div>
        </div>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
      </div>

      <div class="modal-body">
        <div id="mcBody" class="muted">—</div>
      </div>

      <div class="modal-footer">
        <button class="btnGhost" id="mcCancelar" data-bs-dismiss="modal">Cancelar</button>
        <button class="btnDanger" id="mcConfirmar">Confirmar</button>
      </div>
    </div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>

/* ===================== CARTOES (BALCAO) ===================== */
let balCartaoStream=null;
let balCartaoScanTimer=null;

function balcaoCartaoAbrir(){
  document.getElementById('cartaoBalModal').style.display='flex';
  document.getElementById('balCartaoCodigo').focus();
}
function balcaoCartaoFechar(){
  document.getElementById('cartaoBalModal').style.display='none';
  balcaoCartaoFecharLeitor();
}
function balcaoCartaoLimpar(){
  document.getElementById('balCartaoInfo').style.display='none';
  document.getElementById('balCartaoMovs').innerHTML='';
}
function balcaoFmt(v){
  if(typeof v==='number') return v.toFixed(2);
  return String(v||'').replace(',', '.');
}

async function balcaoCartaoConsultar(){
  const codigo=(document.getElementById('balCartaoCodigo').value||'').trim();
  if(!codigo){ showMsg({title:'Atenção', body:'Informe o código do cartão.', type:'warn'}); return; }
  try{
    const r=await fetch('api.php?action=cartao_buscar&codigo='+encodeURIComponent(codigo));
    const out=await r.json();
    if(!out.ok){ showMsg({title:'Erro', body:(out.error||'Erro'), type:'error'}); return; }
    const info=out.cartao||{};
    const saldo=out.saldo??0;
    document.getElementById('balCartaoInfoTxt').textContent = `Cartão ${info.codigo} • ${info.nome||'—'} • ${info.celular||'—'}`;
    document.getElementById('balCartaoSaldoTxt').textContent = `Saldo: R$ ${balcaoFmt(saldo)}`;
    const fechado = info.fechado_em ? 'SIM' : 'NÃO';
    document.getElementById('balCartaoStatusTxt').textContent = `Status: ${info.status||'—'} • Aberto em: ${info.aberto_em||'—'} • Fechado: ${fechado}`;
    document.getElementById('balCartaoInfo').style.display='block';

    // movimentos
    const r2=await fetch('api.php?action=cartao_movimentos&codigo='+encodeURIComponent(codigo));
    const out2=await r2.json();
    if(out2.ok){
      const wrap=document.getElementById('balCartaoMovs');
      const movs=out2.movimentos||[];
      if(!movs.length){ wrap.innerHTML = `<div class="muted">Sem movimentos na sessão atual.</div>`; }
      else{
        wrap.innerHTML = movs.map(m=>{
          const s = `${m.operacao==='C'?'➕':'➖'} ${m.motivo} • R$ ${balcaoFmt(parseFloat(m.valor||0))}`;
          const when = m.criado_em||'';
          const canEstorno = (!info.fechado_em && info.status==='EM_USO' && m.motivo!=='ESTORNO');
          return `
            <div class="itRow">
              <div>
                <div class="nm">${s}</div>
                <div class="obs">${when}${m.observacao?(' • '+m.observacao):''}</div>
              </div>
              <div style="display:flex; gap:8px; align-items:center;">
                ${canEstorno?`<button class="btnDanger" onclick="balcaoCartaoEstornar(${m.id})">Estornar</button>`:''}
              </div>
            </div>
          `;
        }).join('');
      }
    }
  }catch(e){
    showMsg({title:'Erro', body:'Erro ao consultar cartão.', type:'error'});
  }
}

async function balcaoCartaoRecarregar(){
  const codigo=(document.getElementById('balCartaoCodigo').value||'').trim();
  let v=(document.getElementById('balCartaoRecValor').value||'').trim();
  const nome=(document.getElementById('balCartaoNome').value||'').trim();
  const celular=(document.getElementById('balCartaoCel').value||'').trim();
  if(!codigo){ showMsg({title:'Atenção', body:'Informe o código do cartão.', type:'warn'}); return; }
  if(!v){ showMsg({title:'Atenção', body:'Informe o valor.', type:'warn'}); return; }
  v=v.replace(/\./g,'').replace(',','.');
  const valor=parseFloat(v);
  if(!isFinite(valor)||valor<=0){ showMsg({title:'Atenção', body:'Valor inválido.', type:'warn'}); return; }
  if(!confirm(`Confirmar recarga de R$ ${valor.toFixed(2)} no cartão ${codigo}?`)) return;
  try{
    const r=await fetch('api.php?action=cartao_recarregar',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({codigo,valor,nome,celular})});
    const out=await r.json();
    if(!out.ok){ showMsg({title:'Erro', body:(out.error||'Erro'), type:'error'}); return; }
    if(out.warn){ showMsg({title:'Atenção', body:String(out.warn), type:'warn'}); }
    document.getElementById('balCartaoRecValor').value='';
    await balcaoCartaoConsultar();
    showMsg({title:'Sucesso', body:'Recarga confirmada!', type:'success'});
  }catch(e){
    showMsg({title:'Erro', body:'Erro ao recarregar.', type:'error'});
  }
}

async function balcaoCartaoFecharCartao(){
  const codigo=(document.getElementById('balCartaoCodigo').value||'').trim();
  if(!codigo){ showMsg({title:'Atenção', body:'Informe o código do cartão.', type:'warn'}); return; }
  if(!confirm(`Fechar cartão ${codigo}? Após fechar, não será possível estornar.`)) return;
  try{
    const r=await fetch('api.php?action=cartao_fechar',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({codigo})});
    const out=await r.json();
    if(!out.ok){ showMsg({title:'Erro', body:(out.error||'Erro'), type:'error'}); return; }
    if(out.warn){ showMsg({title:'Atenção', body:String(out.warn), type:'warn'}); }
    await balcaoCartaoConsultar();
    showMsg({title:'Sucesso', body:'Cartão fechado!', type:'success'});
  }catch(e){
    showMsg({title:'Erro', body:'Erro ao fechar cartão.', type:'error'});
  }
}

async function balcaoCartaoEstornar(movId){
  if(!confirm('Estornar este movimento?')) return;
  try{
    const r=await fetch('api.php?action=cartao_estornar',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({mov_id:movId})});
    const out=await r.json();
    if(!out.ok){ showMsg({title:'Erro', body:(out.error||'Erro'), type:'error'}); return; }
    if(out.warn){ showMsg({title:'Atenção', body:String(out.warn), type:'warn'}); }
    await balcaoCartaoConsultar();
    showMsg({title:'Sucesso', body:'Estorno realizado!', type:'success'});
  }catch(e){
    showMsg({title:'Erro', body:'Erro ao estornar.', type:'error'});
  }
}

function balcaoCartaoAbrirLeitor(){
  document.getElementById('balCartaoQr').style.display='flex';
  balcaoCartaoIniciarCamera();
}
function balcaoCartaoFecharLeitor(){
  document.getElementById('balCartaoQr').style.display='none';
  balcaoCartaoPararCamera();
}

async function balcaoCartaoIniciarCamera(){
  const msg=document.getElementById('balCartaoQrMsg');
  const video=document.getElementById('balCartaoVideo');
  msg.textContent='Abrindo câmera...';
  try{
    balCartaoStream=await navigator.mediaDevices.getUserMedia({video:{facingMode:'environment'},audio:false});
    video.srcObject=balCartaoStream;
    await video.play();

    if('BarcodeDetector' in window){
      const det=new BarcodeDetector({formats:['qr_code']});
      msg.textContent='Aponte para o QR Code...';
      const scan=async()=>{
        if(!balCartaoStream) return;
        try{
          const codes=await det.detect(video);
          if(codes && codes.length){
            const raw=(codes[0].rawValue||'').trim();
            if(raw){
              document.getElementById('balCartaoCodigo').value=raw;
              balcaoCartaoFecharLeitor();
              balcaoCartaoConsultar();
              return;
            }
          }
        }catch(e){}
        balCartaoScanTimer=requestAnimationFrame(scan);
      };
      balCartaoScanTimer=requestAnimationFrame(scan);
    }else{
      msg.textContent='Leitor de QR não suportado. Digite o código manualmente.';
    }
  }catch(e){
    msg.textContent='Não foi possível acessar a câmera.';
  }
}

function balcaoCartaoPararCamera(){
  try{
    const video=document.getElementById('balCartaoVideo');
    if(balCartaoScanTimer){ cancelAnimationFrame(balCartaoScanTimer); balCartaoScanTimer=null; }
    if(video) video.pause();
    if(balCartaoStream){ balCartaoStream.getTracks().forEach(t=>t.stop()); balCartaoStream=null; }
  }catch(e){}
}

</script>
<script>
  window.ONLY_CARTAO = <?php echo !empty($ONLY_CARTAO) ? "true" : "false"; ?>;
  function applyTheme(t){ document.documentElement.setAttribute("data-theme", t); localStorage.setItem("balcao_theme", t); }
  function toggleTheme(){ const cur = document.documentElement.getAttribute("data-theme") || "dark"; applyTheme(cur === "dark" ? "light" : "dark"); }
  (function(){ applyTheme(localStorage.getItem("balcao_theme") || "dark"); })();

  let contas = [];
  let contaSelecionada = null;
  let detalhesConta = null;
  let pollingTimer = null;

  const modalPagamento = new bootstrap.Modal(document.getElementById("modalPagamento"));
  const modalAvulso = new bootstrap.Modal(document.getElementById("modalAvulso"));
  const modalFatura  = new bootstrap.Modal(document.getElementById("modalFatura"));
  const modalMsg     = new bootstrap.Modal(document.getElementById("modalMsg"));
  const modalConfirm = new bootstrap.Modal(document.getElementById("modalConfirm"));

  function setMsgModal({title, sub, body, type="info"}){
    document.getElementById("mmTitulo").textContent = title || "Mensagem";
    const subEl = document.getElementById("mmSub");
    if(sub){ subEl.style.display = "block"; subEl.textContent = sub; }
    else { subEl.style.display = "none"; subEl.textContent = ""; }
    const bodyEl = document.getElementById("mmBody");
    bodyEl.textContent = body || "";

    // Ajusta botão conforme tipo
    const okBtn = document.getElementById("mmOk");
    okBtn.classList.remove("btnOk","btnWarn","btnDanger","btnGhost");
    if(type === "success") okBtn.classList.add("btnOk");
    else if(type === "warn") okBtn.classList.add("btnWarn");
    else if(type === "error") okBtn.classList.add("btnDanger");
    else okBtn.classList.add("btnGhost");
  }

  function showMsg(opts){
    setMsgModal(opts || {});
    modalMsg.show();
  }

  function confirmModalAsk({title, sub, body, confirmText="Confirmar", cancelText="Cancelar", danger=true}={}){
    return new Promise((resolve) => {
      document.getElementById("mcTitulo").textContent = title || "Confirmar";
      const subEl = document.getElementById("mcSub");
      if(sub){ subEl.style.display = "block"; subEl.textContent = sub; }
      else { subEl.style.display = "none"; subEl.textContent = ""; }
      document.getElementById("mcBody").textContent = body || "";

      const btnC = document.getElementById("mcConfirmar");
      const btnX = document.getElementById("mcCancelar");
      btnC.textContent = confirmText;
      btnX.textContent = cancelText;

      btnC.classList.remove("btnOk","btnWarn","btnDanger","btnGhost");
      btnC.classList.add(danger ? "btnDanger" : "btnOk");

      let resolved = false;
      const cleanup = () => {
        btnC.onclick = null;
        btnX.onclick = null;
      };

      btnC.onclick = () => {
        if(resolved) return;
        resolved = true;
        cleanup();
        modalConfirm.hide();
        resolve(true);
      };
      btnX.onclick = () => {
        if(resolved) return;
        resolved = true;
        cleanup();
        resolve(false);
      };

      // Se fechar no X/Backdrop, considera cancelado
      document.getElementById("modalConfirm").addEventListener("hidden.bs.modal", function onHide(){
        document.getElementById("modalConfirm").removeEventListener("hidden.bs.modal", onHide);
        if(!resolved){
          resolved = true;
          cleanup();
          resolve(false);
        }
      });

      modalConfirm.show();
    });
  }

  let mp = { modo: "sessao", conta_id: 0, sessao_key: "" };

  function money(v){ const n = Number(v || 0); return "R$ " + n.toFixed(2).replace(".", ","); }
  function saldoClass(v){ const n = Number(v||0); if(n <= 0.01) return "ok"; if(n <= 30) return "warn"; return "danger"; }

  async function apiGet(url){
    const r = await fetch(url, {credentials:"same-origin"});
    return await r.json();
  }
  async function apiPost(url, body){
    const r = await fetch(url, {
      method:"POST",
      headers: {"Content-Type":"application/json"},
      credentials:"same-origin",
      body: JSON.stringify(body || {})
    });
    return await r.json();
  }

  async function carregarContas(){
    try{
      const out = await apiGet("api.php?action=contas_abertas");
      if(!out.ok){
        document.getElementById("infoLista").textContent = out.error || "Erro ao carregar";
        document.getElementById("listaContas").innerHTML = `<div class="muted">${escapeHtml(out.error || "Erro ao carregar")}</div>`;
        return;
      }
      contas = out.contas || [];
      renderLista();
    }catch(e){
      document.getElementById("infoLista").textContent = "Erro ao carregar lista.";
    }
  }

  function renderLista(){
    const q = (document.getElementById("search").value || "").trim().toLowerCase();
    const listEl = document.getElementById("listaContas");

    let filtradas = contas;
    if(q){
      filtradas = contas.filter(c => (`mesa ${c.mesa} conta ${c.conta_id}`).toLowerCase().includes(q));
    }

    document.getElementById("infoLista").textContent = `${filtradas.length} conta(s) aberta(s)`;
    listEl.innerHTML = "";

    if(filtradas.length === 0){
      listEl.innerHTML = `<div class="muted">Nenhuma conta encontrada.</div>`;
      return;
    }

    filtradas.forEach(c => {
      const isActive = contaSelecionada && Number(contaSelecionada.conta_id) === Number(c.conta_id);
      const div = document.createElement("div");
      div.className = "item" + (isActive ? " active" : "");
      div.onclick = () => selecionarConta(c.conta_id);

      const cls = saldoClass(c.saldo_fatura);

      div.innerHTML = `
        <div class="row1">
          <div class="mesa">Mesa ${c.mesa}</div>
          <div class="pill">Conta #${c.conta_id}</div>
        </div>
        <div class="row1 mt-2">
          <div class="muted" style="font-size:12px;">Fatura: <b>${money(c.total_fatura)}</b></div>
          <div class="saldo ${cls}">${money(c.saldo_fatura)}</div>
        </div>
      `;
      listEl.appendChild(div);
    });
  }

  function renderDetalhesVazio(){
    document.getElementById("tituloMesa").textContent = "Selecione uma mesa";
    document.getElementById("subMesa").textContent = "Contas abertas aparecerão na esquerda";
    document.getElementById("kpiFatura").textContent = money(0);
    document.getElementById("kpiEntregue").textContent = money(0);
    document.getElementById("kpiAndamento").textContent = money(0);
    document.getElementById("kpiPago").textContent = money(0);
    document.getElementById("kpiSaldo").textContent = money(0);

    document.getElementById("sessoes").innerHTML = `<div class="muted">Selecione uma conta para visualizar.</div>`;
    document.getElementById("btnFecharConta").disabled = true;
    document.getElementById("btnPagarParcialMesa").disabled = true;
    document.getElementById("btnLancamentoAvulso").disabled = true;
    document.getElementById("btnVerFaturaMesa").disabled = true;
  }

  async function selecionarConta(contaId){
    contaSelecionada = contas.find(c => Number(c.conta_id) === Number(contaId)) || {conta_id: contaId};
    renderLista();
    await carregarDetalhesConta();
    iniciarPolling();
  }

  async function carregarDetalhesConta(){
    if(!contaSelecionada) return;

    try{
      const out = await apiGet(`api.php?action=faturas_sessoes&conta_id=${encodeURIComponent(contaSelecionada.conta_id)}`);
      if(!out.ok){
        document.getElementById("sessoes").innerHTML = `<div class="muted">${escapeHtml(out.error || "Erro ao carregar detalhes.")}</div>`;
        return;
      }
      detalhesConta = out;
      renderDetalhesConta();
    }catch(e){
      document.getElementById("sessoes").innerHTML = `<div class="muted">Erro ao carregar detalhes.</div>`;
    }
  }

  function renderDetalhesConta(){
    const mesa = detalhesConta.mesa;
    const conta = detalhesConta.conta || {};
    const sessoes = detalhesConta.sessoes || [];

    document.getElementById("tituloMesa").textContent = `Mesa ${mesa} • Conta #${contaSelecionada.conta_id}`;
    document.getElementById("subMesa").textContent = `Status da conta: ${detalhesConta.conta_status || "-"}`;

    document.getElementById("kpiFatura").textContent = money(conta.total_fatura);
    document.getElementById("kpiEntregue").textContent = money(conta.pedidos_entregue);
    document.getElementById("kpiAndamento").textContent = money(conta.pedidos_andamento);
    document.getElementById("kpiPago").textContent = money(conta.total_pago);
    document.getElementById("kpiSaldo").textContent = money(conta.saldo_fatura);

    document.getElementById("btnFecharConta").disabled = !(Number(conta.saldo_fatura) <= 0.01);
    document.getElementById("btnPagarParcialMesa").disabled = (sessoes.length === 0);
    document.getElementById("btnLancamentoAvulso").disabled = (sessoes.length === 0);
    document.getElementById("btnVerFaturaMesa").disabled = false;

    const wrap = document.getElementById("sessoes");
    if(sessoes.length === 0){
      wrap.innerHTML = `<div class="muted">Nenhuma sessão encontrada para esta mesa.</div>`;
      return;
    }

    let html = "";
    sessoes.forEach(s => {
      const cls = saldoClass(s.saldo_fatura);
      const disabled = Number(s.saldo_fatura) <= 0.01 ? "disabled" : "";

      html += `
        <div class="sess">
          <div class="sessTop">
            <div>
              <div class="sessName">${escapeHtml(s.cliente || "Sessão")}</div>
              <div class="sessKey">sessao_key: ${escapeHtml(s.sessao_key)}</div>
            </div>
            <div style="text-align:right">
              <div class="sub">Saldo (fatura)</div>
              <div class="saldo ${cls}" style="font-size:16px;">${money(s.saldo_fatura)}</div>
            </div>
          </div>

          <div class="sessGrid">
            <div class="mini">
              <div class="k">Fatura (ENTREGUE + avulsos)</div>
              <div class="v">${money(s.total_fatura)}</div>
            </div>
            <div class="mini">
              <div class="k">Entregue</div>
              <div class="v">${money(s.pedidos_entregue)}</div>
            </div>
            <div class="mini">
              <div class="k">Andamento</div>
              <div class="v">${money(s.pedidos_andamento)}</div>
            </div>
            <div class="mini">
              <div class="k">Pago</div>
              <div class="v">${money(s.total_pago)}</div>
            </div>

            <div class="mini">
              <div class="k">Receber</div>
              <button class="btnOk" ${disabled} onclick="abrirPagamentoSessao(${Number(contaSelecionada.conta_id)}, '${jsEscape(s.sessao_key)}')">
                💰 Receber
              </button>
            </div>

            <div class="mini">
              <div class="k">Fatura</div>
              <button class="btnGhost" onclick="abrirFaturaSessao('${jsEscape(s.sessao_key)}')">
                📄 Ver pedidos
              </button>
            </div>
          </div>
        </div>
      `;
    });

    wrap.innerHTML = html;
  }

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

  function getSessaoByKey(sk){
    const sessoes = (detalhesConta && detalhesConta.sessoes) ? detalhesConta.sessoes : [];
    return sessoes.find(x => String(x.sessao_key) === String(sk)) || null;
  }

  function preencherSelectSessoes(selectId){
    const sel = document.getElementById(selectId);
    const sessoes = (detalhesConta && detalhesConta.sessoes) ? detalhesConta.sessoes : [];
    sel.innerHTML = "";
    sessoes.forEach(s => {
      const opt = document.createElement("option");
      opt.value = s.sessao_key;
      opt.textContent = `${s.cliente || "Sessão"} (${String(s.sessao_key).slice(0,6)}…)`;
      sel.appendChild(opt);
    });
  }

  /* ===================== FATURA (NOVO) ===================== */
  async function abrirFaturaMesa(){
    if(!contaSelecionada) return;
    await abrirModalFatura({ conta_id: Number(contaSelecionada.conta_id), sessao_key: "" });
  }

  async function abrirFaturaSessao(sessaoKey){
    if(!contaSelecionada) return;
    await abrirModalFatura({ conta_id: Number(contaSelecionada.conta_id), sessao_key: String(sessaoKey) });
  }

  async function abrirModalFatura({conta_id, sessao_key}){
    document.getElementById("mfBody").innerHTML = `<div class="muted">Carregando…</div>`;
    document.getElementById("mfTotais").textContent = "—";

    const mesa = detalhesConta ? detalhesConta.mesa : "-";
    const sess = sessao_key ? ` • sessão ${sessao_key}` : " • mesa inteira";
    document.getElementById("mfTitulo").textContent = "🧾 Itens da fatura";
    document.getElementById("mfSub").textContent = `Mesa ${mesa} • Conta #${conta_id}${sess}`;

    modalFatura.show();

    try{
      const url = `api.php?action=pedidos_fatura&conta_id=${encodeURIComponent(conta_id)}${sessao_key ? `&sessao_key=${encodeURIComponent(sessao_key)}` : ""}`;
      const out = await apiGet(url);
      if(!out.ok){
        document.getElementById("mfBody").innerHTML = `<div class="muted">${escapeHtml(out.error || "Erro ao carregar fatura.")}</div>`;
        return;
      }

      const t = out.totais || {};
      document.getElementById("mfTotais").innerHTML =
        `Fatura: <b>${money(t.total_fatura)}</b> • Entregue: <b>${money(t.pedidos_entregue)}</b> • Avulsos: <b>${money(t.avulsos_total)}</b> • Pago: <b>${money(t.total_pago)}</b> • Saldo: <b>${money(t.saldo_fatura)}</b>`;

      const pedidos = out.pedidos || [];
      const avulsos = out.avulsos || [];

      let html = "";

      if(pedidos.length === 0 && avulsos.length === 0){
        html = `<div class="muted">Nenhum item na fatura (a fatura só considera pedidos <b>ENTREGUE</b> + avulsos).</div>`;
        document.getElementById("mfBody").innerHTML = html;
        return;
      }

      if(pedidos.length){
        html += `<div style="font-weight:900; margin-bottom:8px;">Pedidos ENTREGUE</div>`;
        pedidos.forEach(p => {
          html += `<div class="itRow">
            <div>
              <div class="nm">Pedido #${p.pedido_id}</div>
              <div class="obs">Sessão: ${escapeHtml(p.sessao_key || "-")} • ${escapeHtml(p.entregue_em || "")}</div>
            </div>
            <div style="font-weight:900">${money(p.subtotal)}</div>
          </div>`;

          (p.itens || []).forEach(it => {
            const obs = it.observacao ? `<div class="obs">📝 ${escapeHtml(it.observacao)}</div>` : "";
            html += `<div class="itRow" style="opacity:.98">
              <div>
                <div class="nm">${escapeHtml(it.produto)} <span class="muted">x${Number(it.qtd||0)}</span></div>
                ${obs}
              </div>
              <div style="font-weight:900">${money(it.subtotal)}</div>
            </div>`;
          });

          html += `<div class="line"></div>`;
        });
      }

      if(avulsos.length){
        html += `<div style="font-weight:900; margin: 6px 0 8px;">Lançamentos avulsos</div>`;
        avulsos.forEach(a => {
          html += `<div class="itRow">
            <div>
              <div class="nm">➕ ${escapeHtml(a.descricao || "Avulso")}</div>
              <div class="obs">Sessão: ${escapeHtml(a.sessao_key || "-")} • ${escapeHtml(a.criado_em || "")}</div>
            </div>
            <div style="font-weight:900">${money(a.valor)}</div>
          </div>`;
        });
      }

      document.getElementById("mfBody").innerHTML = html;

    }catch(e){
      document.getElementById("mfBody").innerHTML = `<div class="muted">Erro ao carregar fatura.</div>`;
    }
  }

  /* ===================== PAGAMENTO ===================== */
  function abrirPagamentoSessao(contaId, sessaoKey){
    mp = { modo: "sessao", conta_id: Number(contaId), sessao_key: String(sessaoKey) };

    const s = getSessaoByKey(sessaoKey);
    const saldoSessao = s ? Number(s.saldo_fatura || 0) : 0;

    document.getElementById("mpTitulo").textContent = "Receber pagamento (sessão)";
    document.getElementById("mpSessaoWrap").style.display = "none";
    document.getElementById("mpSub").textContent = s ? `${s.cliente} • ${s.sessao_key}` : sessaoKey;
    document.getElementById("mpValor").value = (saldoSessao > 0 ? saldoSessao.toFixed(2) : "");
    document.getElementById("mpMetodo").value = "PIX";
    const mpRecebidoEl = document.getElementById("mpRecebido");
    if (mpRecebidoEl) mpRecebidoEl.value = "";
    atualizarDinheiroTroco();
    document.getElementById("mpMetodo").onchange = atualizarDinheiroTroco;
    document.getElementById("mpValor").oninput = atualizarDinheiroTroco;
    if (mpRecebidoEl) mpRecebidoEl.oninput = atualizarDinheiroTroco;
    document.getElementById("mpErro").style.display = "none";
    document.getElementById("mpErro").textContent = "";

    modalPagamento.show();
  }

  function abrirPagamentoParcialMesa(){
    if(!contaSelecionada || !detalhesConta) return;

    mp = { modo: "mesa_parcial", conta_id: Number(contaSelecionada.conta_id), sessao_key: "" };

    document.getElementById("mpTitulo").textContent = "Pagamento parcial da mesa (escolha a sessão)";
    document.getElementById("mpSessaoWrap").style.display = "block";

    preencherSelectSessoes("mpSessao");

    const sk = document.getElementById("mpSessao").value;
    mp.sessao_key = sk;

    const s = getSessaoByKey(sk);
    document.getElementById("mpSaldo").textContent = money(s ? s.saldo_fatura : 0);

    document.getElementById("mpSub").textContent = `Mesa ${detalhesConta.mesa} • Conta #${contaSelecionada.conta_id}`;
    document.getElementById("mpValor").value = "";
    document.getElementById("mpMetodo").value = "PIX";
    const mpRecebidoEl = document.getElementById("mpRecebido");
    if (mpRecebidoEl) mpRecebidoEl.value = "";
    atualizarDinheiroTroco();

    // atualiza UI/troco conforme o usuário digita
    document.getElementById("mpMetodo").onchange = atualizarDinheiroTroco;
    document.getElementById("mpValor").oninput = atualizarDinheiroTroco;
    if (mpRecebidoEl) mpRecebidoEl.oninput = atualizarDinheiroTroco;

    document.getElementById("mpSessao").onchange = () => {
      const sk2 = document.getElementById("mpSessao").value;
      mp.sessao_key = sk2;
      const s2 = getSessaoByKey(sk2);
      document.getElementById("mpSaldo").textContent = money(s2 ? s2.saldo_fatura : 0);
    };

    document.getElementById("mpErro").style.display = "none";
    document.getElementById("mpErro").textContent = "";

    modalPagamento.show();
  }

  
function moneyToNumber(v){
  v = String(v ?? "").trim().replace(/\s/g,'');

  // remove símbolo de moeda
  v = v.replace(/[R$\$]/g, '');

  const hasComma = v.includes(',');
  const hasDot   = v.includes('.');

  // Caso BR: 1.234,56
  if (hasComma && hasDot && v.lastIndexOf(',') > v.lastIndexOf('.')) {
    v = v.replace(/\./g, '').replace(',', '.');
  }
  // Caso US: 1,234.56
  else if (hasComma && hasDot && v.lastIndexOf('.') > v.lastIndexOf(',')) {
    v = v.replace(/,/g, '');
  }
  // Só vírgula: 35,50
  else if (hasComma && !hasDot) {
    v = v.replace(',', '.');
  }
  // Só ponto: 35.50 (já está certo)

  return parseFloat(v) || 0;
}


  function atualizarDinheiroTroco(){
    const wrap = document.getElementById("mpDinheiroWrap");
    const metodo = (document.getElementById("mpMetodo").value || "OUTRO").toUpperCase();
    const trocoEl = document.getElementById("mpTroco");
    if(metodo !== "DINHEIRO"){
      wrap.style.display = "none";
      return;
    }
    wrap.style.display = "block";

    const valor = moneyToNumber(document.getElementById("mpValor").value);
    const recebido = moneyToNumber(document.getElementById("mpRecebido").value);

    const troco = (Number.isFinite(valor) && Number.isFinite(recebido)) ? Math.max(0, recebido - valor) : 0;
    trocoEl.textContent = money(troco);
  }
async function confirmarPagamento(){
    const erroEl = document.getElementById("mpErro");
    erroEl.style.display = "none";
    erroEl.textContent = "";

    const metodo = document.getElementById("mpMetodo").value || "OUTRO";
    const valor = moneyToNumber(document.getElementById("mpValor").value);

    // dinheiro: valor recebido pode ser maior (troco)
    let valorRecebido = null;
    if (String(metodo).toUpperCase() === "DINHEIRO") {
      const r = moneyToNumber(document.getElementById("mpRecebido").value);
      valorRecebido = Number.isFinite(r) && r > 0 ? r : null;
    }

    if(!contaSelecionada || !mp.conta_id){
      erroEl.textContent = "Conta inválida.";
      erroEl.style.display = "block";
      return;
    }

    if(mp.modo === "mesa_parcial"){
      mp.sessao_key = document.getElementById("mpSessao").value;
    }

    if(!mp.sessao_key){
      erroEl.textContent = "Selecione a sessão.";
      erroEl.style.display = "block";
      return;
    }

    if(!Number.isFinite(valor) || valor <= 0){
      erroEl.textContent = "Informe um valor válido.";
      erroEl.style.display = "block";
      return;
    }

    if(String(metodo).toUpperCase() === "DINHEIRO"){
      const recebido = (valorRecebido === null ? valor : valorRecebido);
      if(recebido + 0.0001 < valor){
        erroEl.textContent = "No dinheiro, o valor recebido não pode ser menor que o valor a abater.";
        erroEl.style.display = "block";
        return;
      }
    }

    const s = getSessaoByKey(mp.sessao_key);
    const saldoAtual = s ? Number(s.saldo_fatura || 0) : 0;

    if(valor > saldoAtual + 0.01){
      erroEl.textContent = "Valor maior que o saldo da fatura da sessão selecionada.";
      erroEl.style.display = "block";
      return;
    }

    document.getElementById("mpConfirmar").disabled = true;

    try{
      const out = await apiPost("api.php?action=registrar_pagamento", {
        conta_id: mp.conta_id,
        sessao_key: mp.sessao_key,
        valor: valor,
        metodo: metodo,
        valor_recebido: (String(metodo).toUpperCase()==="DINHEIRO" ? (valorRecebido===null?valor:valorRecebido) : null)
      });

      if(!out.ok){
        erroEl.textContent = out.error || "Erro ao registrar pagamento.";
        erroEl.style.display = "block";
        document.getElementById("mpConfirmar").disabled = false;
        return;
      }

      modalPagamento.hide();
      document.getElementById("mpConfirmar").disabled = false;

      if(out.warn){ showMsg({title:'Atenção', body:String(out.warn), type:'warn'}); }

      // ✅ dinheiro: mostrar troco quando houver
      if(String(metodo).toUpperCase()==="DINHEIRO"){
        const troco = Number(out.troco || 0);
        if(Number.isFinite(troco) && troco > 0.009){
          showMsg({title:'Troco', body:`Troco: ${money(troco)}</b>`, type:'info'});
        }
      }

      await carregarContas();
      await carregarDetalhesConta();
    }catch(e){
      erroEl.textContent = "Erro ao registrar pagamento.";
      erroEl.style.display = "block";
      document.getElementById("mpConfirmar").disabled = false;
    }
  }

  /* ===================== AVULSO ===================== */
  function abrirLancamentoAvulso(){
    if(!contaSelecionada || !detalhesConta) return;

    preencherSelectSessoes("maSessao");
    document.getElementById("maSub").textContent = `Mesa ${detalhesConta.mesa} • Conta #${contaSelecionada.conta_id}`;

    document.getElementById("maValor").value = "";
    document.getElementById("maDesc").value = "";
    document.getElementById("maErro").style.display = "none";
    document.getElementById("maErro").textContent = "";
    document.getElementById("maConfirmar").disabled = false;

    modalAvulso.show();
  }

  async function confirmarAvulso(){
    const erroEl = document.getElementById("maErro");
    erroEl.style.display = "none";
    erroEl.textContent = "";

    const sessaoKey = document.getElementById("maSessao").value;
    let v = (document.getElementById("maValor").value || "").trim().replace(",", ".");
    let valor = Number(v);
    let desc = (document.getElementById("maDesc").value || "").trim();

    if(!contaSelecionada){
      erroEl.textContent = "Conta inválida.";
      erroEl.style.display = "block";
      return;
    }
    if(!sessaoKey){
      erroEl.textContent = "Selecione a sessão.";
      erroEl.style.display = "block";
      return;
    }
    if(!Number.isFinite(valor) || valor <= 0){
      erroEl.textContent = "Informe um valor válido.";
      erroEl.style.display = "block";
      return;
    }
    if(desc.length < 2){
      erroEl.textContent = "Informe uma descrição.";
      erroEl.style.display = "block";
      return;
    }

    document.getElementById("maConfirmar").disabled = true;

    try{
      const out = await apiPost("api.php?action=registrar_lancamento", {
        conta_id: Number(contaSelecionada.conta_id),
        sessao_key: sessaoKey,
        valor: valor,
        descricao: desc
      });

      if(!out.ok){
        erroEl.textContent = out.error || "Erro ao lançar avulso.";
        erroEl.style.display = "block";
        document.getElementById("maConfirmar").disabled = false;
        return;
      }

      modalAvulso.hide();
      document.getElementById("maConfirmar").disabled = false;

      await carregarContas();
      await carregarDetalhesConta();
    }catch(e){
      erroEl.textContent = "Erro ao lançar avulso.";
      erroEl.style.display = "block";
      document.getElementById("maConfirmar").disabled = false;
    }
  }

  /* ===================== FECHAR CONTA ===================== */
  async function fecharConta(){
    if(!contaSelecionada) return;
    const ok = await confirmModalAsk({
      title: "Fechar conta",
      sub: "Atenção",
      body: "Fechar conta? Só será possível se o saldo da fatura estiver zerado.",
      confirmText: "Fechar",
      cancelText: "Cancelar",
      danger: true
    });
    if(!ok) return;

    const out = await apiPost("api.php?action=fechar_conta", { conta_id: Number(contaSelecionada.conta_id) });
    if(!out.ok){
      showMsg({ type: "error", title: "Não foi possível fechar", body: (out.error || "Erro ao fechar conta.") });
      return;
    }

    showMsg({ type: "success", title: "Conta fechada", body: "Conta fechada com sucesso!" });
    contaSelecionada = null;
    detalhesConta = null;
    await carregarContas();
    renderDetalhesVazio();
    pararPolling();
  }

  /* ===================== POLLING ===================== */
  function iniciarPolling(){
    pararPolling();
    pollingTimer = setInterval(async () => {
      await carregarContas();
      if(contaSelecionada) await carregarDetalhesConta();
    }, 3000);
  }
  function pararPolling(){
    if(pollingTimer){
      clearInterval(pollingTimer);
      pollingTimer = null;
    }
  }

  if(!window.ONLY_CARTAO){
    renderDetalhesVazio();
    carregarContas();
    iniciarPolling();
  }else{
    // Abre direto o painel de cartao
    setTimeout(() => { try{ balcaoCartaoAbrir(); }catch(e){} }, 50);
  }
</script>


<!-- ===================== MODAL: CARTOES (BALCAO) ===================== -->
<div id="cartaoBalModal" style="display:none; position:fixed; inset:0; background: rgba(0,0,0,.55); z-index:9999; align-items:center; justify-content:center; padding:16px;">
  <div style="width:min(920px, 100%); background: var(--card); border:1px solid var(--line); border-radius:16px; box-shadow: var(--shadow); overflow:hidden;">
    <div style="padding:14px 16px; display:flex; align-items:center; justify-content:space-between; gap:10px; background: var(--card2); border-bottom:1px solid var(--line);">
      <div style="font-weight:900;">💳 Cartões • Recarga / Estorno / Fechar</div>
      <button class="btnGhost" onclick="balcaoCartaoFechar()">✕</button>
    </div>

    <div style="padding:16px; display:grid; gap:12px;">
      <div style="display:grid; grid-template-columns: 1.2fr .6fr; gap:10px; align-items:end;">
        <div>
          <label style="font-size:12px; color:var(--muted);">Código do cartão</label>
          <input id="balCartaoCodigo" class="search" placeholder="Aponte o QR ou digite" oninput="balcaoCartaoLimpar()">
        </div>
        <div style="display:flex; gap:8px; flex-wrap:wrap; justify-content:flex-end;">
          <button class="btnGhost" onclick="balcaoCartaoAbrirLeitor()">📷 Ler QR</button>
          <button class="btnOk" onclick="balcaoCartaoConsultar()">🔎 Consultar</button>
        </div>
      </div>

      <div id="balCartaoInfo" style="display:none; border:1px solid var(--line); border-radius:12px; padding:12px; background: rgba(255,255,255,.04);">
        <div style="display:flex; justify-content:space-between; flex-wrap:wrap; gap:10px;">
          <div style="font-weight:900;" id="balCartaoInfoTxt">—</div>
          <div style="font-weight:900;" id="balCartaoSaldoTxt">Saldo: R$ 0,00</div>
        </div>
        <div style="margin-top:6px; color:var(--muted); font-size:12px;" id="balCartaoStatusTxt"></div>
      </div>

      <div style="display:grid; grid-template-columns: 1fr 1fr 1fr; gap:10px;">
        <div>
          <label style="font-size:12px; color:var(--muted);">Valor recarga (balcão)</label>
          <input id="balCartaoRecValor" class="search" placeholder="0,00" inputmode="decimal">
        </div>
        <div>
          <label style="font-size:12px; color:var(--muted);">Nome (opcional)</label>
          <input id="balCartaoNome" class="search" placeholder="Cliente">
        </div>
        <div>
          <label style="font-size:12px; color:var(--muted);">Celular (opcional)</label>
          <input id="balCartaoCel" class="search" placeholder="(xx) 9xxxx-xxxx">
        </div>
      </div>

      <div style="display:flex; gap:10px; flex-wrap:wrap; justify-content:flex-end;">
        <button class="btnOk" onclick="balcaoCartaoRecarregar()">➕ Confirmar recarga</button>
        <button class="btnWarn" onclick="balcaoCartaoFecharCartao()">✅ Fechar cartão</button>
      </div>

      <div style="border-top:1px solid var(--line); margin-top:6px; padding-top:12px;">
        <div style="font-weight:900; margin-bottom:8px;">Movimentos (sessão atual)</div>
        <div id="balCartaoMovs" style="display:grid; gap:8px;"></div>
        <div style="color:var(--muted); font-size:12px;">* Estorno só é permitido com o cartão ABERTO (em uso). Cartão fechado não permite estorno.</div>
      </div>
    </div>
  </div>
</div>

<!-- Leitor QR (camera) -->
<div id="balCartaoQr" style="display:none; position:fixed; inset:0; background: rgba(0,0,0,.65); z-index:10000; align-items:center; justify-content:center; padding:16px;">
  <div style="width:min(720px,100%); background: var(--card); border:1px solid var(--line); border-radius:16px; box-shadow: var(--shadow); overflow:hidden;">
    <div style="padding:14px 16px; display:flex; align-items:center; justify-content:space-between; gap:10px; background: var(--card2); border-bottom:1px solid var(--line);">
      <div style="font-weight:900;">📷 Ler QR do cartão</div>
      <button class="btnGhost" onclick="balcaoCartaoFecharLeitor()">✕</button>
    </div>
    <div style="padding:16px;">
      <video id="balCartaoVideo" style="width:100%; border-radius:12px; border:1px solid var(--line); background:#000" playsinline></video>
      <div id="balCartaoQrMsg" style="margin-top:10px; color:var(--muted); font-size:12px;"></div>
      <div style="display:flex; justify-content:flex-end; margin-top:12px;">
        <button class="btnGhost" onclick="balcaoCartaoFecharLeitor()">Fechar</button>
      </div>
    </div>
  </div>
</div>

</body>
</html>
