<?php
require_once __DIR__ . "/_bootstrap.php";
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, "UTF-8"); }
?>
<!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 • Caixa</title>

  <style>

    :root{
      --bg:#0f0f10;
      --card:rgba(32,32,34,.92);
      --text:#f3f3f3;
      --muted:rgba(243,243,243,.70);
      --line: rgba(255,255,255,.12);
      --shadow: none;
      --radius: 16px;

      --blue:#60cdff;
      --green:#22c55e;
      --red:#ff5a5f;
      --amber:#f59e0b;

      --btn: rgba(255,255,255,.06);
      --btn2: rgba(255,255,255,.10);
    }

*{box-sizing:border-box}
    body{
      margin:0;
      font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
      background: var(--bg);
color:var(--text);
      padding: 22px 14px;
    }
    .wrap{max-width: 1100px; margin: 0 auto;}
    .top{
      display:flex; align-items:center; justify-content:space-between;
      gap: 12px; margin-bottom: 14px;
      flex-wrap: wrap;
    }
    h1{margin:0; font-size: 20px; letter-spacing:.2px;}
    .status{
      display:flex; align-items:center; gap:10px;
      padding:10px 12px; border:1px solid var(--line); border-radius: 999px;
      background: rgba(255,255,255,.04);
      box-shadow: none;
      white-space: nowrap;
    }
    .dot{
      width:10px;height:10px;border-radius:99px;background: var(--red);
      box-shadow: none;
    }
    .dot.ok{
      background: var(--green);
      box-shadow: none;
    }
    .dot.warn{
      background: var(--amber);
      box-shadow: none;
    }
    .grid{
      display:grid;
      grid-template-columns: 1.2fr .8fr;
      gap: 14px;
    }
    @media (max-width: 980px){
      .grid{grid-template-columns: 1fr;}
    }
    .card{
      background: var(--card);
      border: 1px solid var(--line);
      border-radius: var(--radius);
      padding: 14px;
      box-shadow: none;
    }
    .muted{color:var(--muted); font-size: 13px;}
    .row{display:flex; gap: 12px; flex-wrap:wrap; margin-top: 10px;}
    .kpi{
      flex:1; min-width: 180px;
      border:1px solid var(--line);
      background: rgba(255,255,255,.04);
      border-radius: 14px;
      padding: 12px;
    }
    .kpi .label{font-size:12px;color:var(--muted); display:flex; align-items:center; justify-content:space-between; gap:10px;}
    .kpi .value{font-size:20px;margin-top:6px;font-weight:700}
    .kpi .value.green{color: var(--green)}
    .kpi .value.red{color: var(--red)}
    .kpi .value.amber{color: var(--amber)}
    .badge{
      font-size:12px;
      padding: 4px 10px;
      border-radius: 999px;
      border:1px solid rgba(255,255,255,.14);
      background: rgba(18,18,20,.92);
      color: var(--text);
    }
    .badge.warn{
      border-color: rgba(245,158,11,.45);
      background: rgba(245,158,11,.10);
      color: #ffd28a;
    }
    .form label{display:block; font-size: 13px; color: var(--muted); margin-top: 10px;}
    input, textarea{
      width:100%;
      margin-top:6px;
      padding: 11px 12px;
      border-radius: 12px;
      border:1px solid var(--line);
      background: rgba(18,18,20,.92);
      color: var(--text);
      outline: none;
    }
    textarea{min-height: 90px; resize: vertical;}
    .btns{display:flex; gap: 10px; margin-top: 12px; flex-wrap: wrap;}
    button{
      appearance:none; border: 1px solid var(--line);
      background: var(--btn);
      color: var(--text);
      padding: 10px 12px;
      border-radius: 12px;
      cursor:pointer;
    }
    button:hover{background: var(--btn2);}
    button.primary{background: rgba(37,99,235,.25); border-color: rgba(37,99,235,.45);}
    button.warn{background: rgba(245,158,11,.14); border-color: rgba(245,158,11,.40);}
    button:disabled{opacity:.55; cursor:not-allowed;}
    .toast{
      position: fixed;
      left: 50%;
      transform: translateX(-50%);
      bottom: 18px;
      background: rgba(0,0,0,.55);
      border: 1px solid rgba(255,255,255,.14);
      padding: 10px 14px;
      border-radius: 12px;
      display:none;
      max-width: 92vw;
      box-shadow: none;
      z-index: 50;
    }
    table{width:100%; border-collapse: collapse; margin-top: 10px; font-size: 13px;}
    th, td{padding: 8px 10px; border-bottom: 1px solid rgba(255,255,255,.10); text-align:left; vertical-align: top;}
    th{color: var(--muted); font-weight: 600;}
    .mono{font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;}
    .small{font-size:12px;color:var(--muted)}
  
    .shadow, .shadow-sm, .shadow-lg, .card, .btn { box-shadow:none !important; }
</style>
</head>
<body>
  <div class="wrap">
    <div class="top">
      <h1>Caixa</h1>
      <div class="status">
        <span id="dot" class="dot"></span>
        <span id="stText">Carregando…</span>
        <button id="btnReload" type="button" style="margin-left:8px;">Recarregar</button>
      </div>
    </div>

    <div class="grid">
      <div class="card">
        <div class="muted">Resumo do caixa</div>

        <div class="row">
          <div class="kpi">
            <div class="label"><span>Saldo atual</span></div>
            <div id="cxSaldoAtual" class="value">—</div>
          </div>
          <div class="kpi">
            <div class="label"><span>Entradas</span></div>
            <div id="cxEntradas" class="value green">—</div>
          </div>
          <div class="kpi">
            <div class="label"><span>Saídas</span></div>
            <div id="cxSaidas" class="value red">—</div>
          </div>

          <div class="kpi">
            <div class="label">
              <span>Pendentes</span>
              <span id="pendBadge" class="badge">0</span>
            </div>
            <div id="pendValor" class="value amber">—</div>
          </div>
        </div>

        <div style="display:flex;gap:10px;flex-wrap:wrap;margin-top:10px;">
          <div class="muted">ID: <b id="cxId">—</b></div>
          <div class="muted">Aberto em: <b id="cxAbertoEm">—</b></div>
          <div class="muted">Obs: <b id="cxObs">—</b></div>
        </div>

        <div class="muted" style="margin-top:12px;">
          Categorias (apenas lançamentos OK do caixa atual):
        </div>
        <div style="overflow:auto;">
          <table>
            <thead>
              <tr>
                <th>Categoria</th>
                <th>Entradas</th>
                <th>Saídas</th>
              </tr>
            </thead>
            <tbody id="tbCats">
              <tr><td colspan="3" class="muted">—</td></tr>
            </tbody>
          </table>
        </div>
      </div>

      <div class="card">
        <div class="muted">Abrir caixa</div>

        <form id="formAbrir" class="form" autocomplete="off">
          <label>Saldo inicial</label>
          <input id="saldo_inicial" name="saldo_inicial" inputmode="decimal" placeholder="Ex: 100,00">

          <label>Observações</label>
          <textarea id="observacoes" name="observacoes" placeholder="Opcional"></textarea>

          <div class="btns">
            <button id="btnAbrir" class="primary" type="submit">Abrir</button>
            <button id="btnLimpar" type="button">Limpar</button>
          </div>

          <div class="small" style="margin-top:10px;">
            Ao abrir, o sistema concilia automaticamente os <b>pendentes de hoje</b>.
          </div>
        </form>

        <hr style="border:none;border-top:1px solid rgba(255,255,255,.10); margin:14px 0;">

        <div class="muted">Pendentes (caixa fechado)</div>
        <div class="small" style="margin-top:6px;">
          Quando o caixa estava fechado, os módulos (balcão/cartão) registraram aqui.
          Abra o caixa e concilie, ou concilie manualmente no caixa aberto.
        </div>

        <div class="btns">
          <button id="btnListarPend" type="button">Listar pendentes</button>
          <button id="btnConciliar" class="warn" type="button" disabled>Conciliar pendentes (todos)</button>
          <button id="btnConciliarHoje" class="warn" type="button" disabled>Conciliar pendentes (hoje)</button>
        </div>

        <div style="overflow:auto; max-height: 340px; margin-top: 10px;">
          <table>
            <thead>
              <tr>
                <th>ID</th>
                <th>Tipo</th>
                <th>Categoria</th>
                <th>Valor</th>
                <th>Descrição</th>
                <th>Data</th>
              </tr>
            </thead>
            <tbody id="tbPend">
              <tr><td colspan="6" class="muted">—</td></tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>

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

  <script>
    const API = "api.php";
    let pollTimer = null;

    function toast(msg){
      const el = document.getElementById("toast");
      el.textContent = msg;
      el.style.display = "block";
      clearTimeout(window.__t);
      window.__t = setTimeout(()=> el.style.display="none", 2800);
    }

    function fmtBRL(v){
      if (v === null || v === undefined || v === "") return "—";
      const n = Number(v);
      if (Number.isNaN(n)) return String(v);
      return n.toLocaleString("pt-BR", {style:"currency", currency:"BRL"});
    }

    function setStatus(open, pendQtd){
      const dot = document.getElementById("dot");
      const st = document.getElementById("stText");

      dot.classList.remove("ok","warn");

      if (open){
        dot.classList.add(pendQtd > 0 ? "warn" : "ok");
        st.textContent = pendQtd > 0 ? "Caixa ABERTO (há pendentes)" : "Caixa ABERTO";
      } else {
        if (pendQtd > 0) dot.classList.add("warn");
        st.textContent = pendQtd > 0 ? "Caixa FECHADO (há pendentes)" : "Caixa FECHADO";
      }
    }

    function fillCaixa(cx){
      document.getElementById("cxId").textContent = cx?.id ?? "—";
      document.getElementById("cxAbertoEm").textContent = cx?.aberto_em ?? "—";
      document.getElementById("cxObs").textContent = (cx?.observacoes && cx.observacoes.trim()) ? cx.observacoes : "—";
    }

    function fillCats(cats){
      const tb = document.getElementById("tbCats");
      if (!cats || !cats.length){
        tb.innerHTML = `<tr><td colspan="3" class="muted">Sem lançamentos ainda.</td></tr>`;
        return;
      }
      tb.innerHTML = cats.map(c => `
        <tr>
          <td>${String(c.categoria || "")}</td>
          <td>${fmtBRL(c.entradas || 0)}</td>
          <td>${fmtBRL(c.saidas || 0)}</td>
        </tr>
      `).join("");
    }

    function fillResumo(totais){
      document.getElementById("cxSaldoAtual").textContent = fmtBRL(totais?.saldo_atual ?? 0);
      document.getElementById("cxEntradas").textContent   = fmtBRL(totais?.entradas ?? 0);
      document.getElementById("cxSaidas").textContent     = fmtBRL(totais?.saidas ?? 0);
    }

    function fillPend(p){
      const qtd = Number(p?.qtd ?? 0);
      const valor = Number(p?.valor ?? 0);

      const badge = document.getElementById("pendBadge");
      badge.textContent = String(qtd);
      badge.classList.toggle("warn", qtd > 0);

      document.getElementById("pendValor").textContent = fmtBRL(valor);

      document.getElementById("btnConciliar").disabled = !(window.__caixaAberto && qtd > 0);
      document.getElementById("btnConciliarHoje").disabled = !(window.__caixaAberto && qtd > 0);
    }

    function fillPendTable(itens){
      const tb = document.getElementById("tbPend");
      if (!itens || !itens.length){
        tb.innerHTML = `<tr><td colspan="6" class="muted">Sem pendentes.</td></tr>`;
        return;
      }
      tb.innerHTML = itens.map(x => `
        <tr>
          <td class="mono">${x.id}</td>
          <td>${x.tipo}</td>
          <td>${x.categoria}</td>
          <td>${fmtBRL(x.valor)}</td>
          <td>
            ${x.descricao ? String(x.descricao) : ''}
            ${x.ref_table ? `<div class="small mono">${x.ref_table}:${x.ref_id ?? ''}</div>` : ''}
          </td>
          <td class="small">${x.criado_em ?? ''}</td>
        </tr>
      `).join("");
    }

    async function loadStatus(){
      const r = await fetch(API + "?action=status", {cache:"no-store"});
      const j = await r.json();
      if (!j.ok){
        toast(j.error || "Falha ao carregar status.");
        return;
      }

      window.__caixaAberto = !!j.caixa_aberto;

      fillCaixa(j.caixa);
      fillPend(j.pendentes);
      setStatus(j.caixa_aberto, Number(j.pendentes?.qtd ?? 0));

      const form = document.getElementById("formAbrir");
      if (j.caixa_aberto){
        form.querySelectorAll("input,textarea,button").forEach(x=> x.disabled = true);
      } else {
        form.querySelectorAll("input,textarea,button").forEach(x=> x.disabled = false);
      }

      await loadResumo();
      setupPolling();
    }

    async function loadResumo(){
      const r = await fetch(API + "?action=resumo", {cache:"no-store"});
      const j = await r.json();
      if (!j.ok){
        toast(j.error || "Falha ao carregar resumo.");
        return;
      }

      window.__caixaAberto = !!j.caixa_aberto;

      fillCaixa(j.caixa);
      fillResumo(j.totais);
      fillCats(j.por_categoria);
      fillPend(j.pendentes);

      setStatus(j.caixa_aberto, Number(j.pendentes?.qtd ?? 0));
    }

    function setupPolling(){
      if (pollTimer){
        clearInterval(pollTimer);
        pollTimer = null;
      }
      pollTimer = setInterval(loadResumo, 5000);
    }

    async function listarPendentes(){
      const r = await fetch(API + "?action=pendentes_listar", {cache:"no-store"});
      const j = await r.json();
      if (!j.ok){
        toast(j.error || "Falha ao listar pendentes.");
        return;
      }
      fillPendTable(j.itens);
    }

    async function conciliarPendentes(apenasHoje){
      const fd = new FormData();
      fd.append("action", "conciliar_pendentes");
      if (apenasHoje) fd.append("apenas_hoje", "1");

      const r = await fetch(API, {method:"POST", body: fd});
      const j = await r.json();
      if (!j.ok){
        toast(j.error || "Não foi possível conciliar.");
        return;
      }
      toast(`${j.message || "Conciliado"} (qtd: ${j.qtd ?? 0})`);
      await loadResumo();
      await listarPendentes();
    }

    document.getElementById("btnReload").addEventListener("click", loadStatus);

    document.getElementById("btnLimpar").addEventListener("click", ()=>{
      document.getElementById("saldo_inicial").value = "";
      document.getElementById("observacoes").value = "";
    });

    document.getElementById("btnListarPend").addEventListener("click", listarPendentes);
    document.getElementById("btnConciliar").addEventListener("click", ()=> conciliarPendentes(false));
    document.getElementById("btnConciliarHoje").addEventListener("click", ()=> conciliarPendentes(true));

    document.getElementById("formAbrir").addEventListener("submit", async (e)=>{
      e.preventDefault();
      const btn = document.getElementById("btnAbrir");
      btn.disabled = true;

      const fd = new FormData(e.target);
      fd.append("action", "abrir");

      try{
        const r = await fetch(API, {method:"POST", body: fd});
        const j = await r.json();
        if (!j.ok){
          toast(j.error || "Não foi possível abrir o caixa.");
          btn.disabled = false;
          return;
        }
        toast((j.message || "Caixa aberto.") + (j.conciliados_hoje ? ` Pendentes de hoje conciliados: ${j.conciliados_hoje}` : ""));
        await loadStatus();
        await listarPendentes();
      }catch(err){
        toast("Erro de rede.");
        btn.disabled = false;
      }
    });

    loadStatus().then(listarPendentes);
  </script>
</body>
</html>