<?php
require_once __DIR__ . "/../../includes/db.php";

$contaId = (int)($_GET['conta'] ?? 0);
$token   = trim((string)($_GET['t'] ?? ''));

$st = $pdo->prepare("
  SELECT id, expira_em
  FROM conta_extratos
  WHERE conta_id=? AND token=? AND expira_em >= NOW()
  LIMIT 1
");
$st->execute([$contaId, $token]);
$row = $st->fetch(PDO::FETCH_ASSOC);

if (!$row){
  http_response_code(403);
  echo "Link de extrato inválido ou expirado.";
  exit;
}


$codigo = trim((string)($_GET["c"] ?? ""));
$token  = trim((string)($_GET["t"] ?? ""));

?>
<!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>Extrato do Cartão</title>

  <style>
    :root{
      --bg:#0f0f10;
      --mica:#111214;

      --card: rgba(26,27,31,.70);
      --card2: rgba(18,19,22,.60);

      --text:#f3f4f6;
      --muted:#a9afbf;
      --line: rgba(255,255,255,.10);
      --line2: rgba(255,255,255,.08);

      --shadow:none;
      --shadow2:none;

      --radius: 14px;
      --radius2: 12px;

      --accent:#60a5fa;
      --green:#22c55e;
      --red:#ef4444;
      --amber:#f59e0b;

      --btn: rgba(255,255,255,.06);
      --btnHover: rgba(255,255,255,.10);
      --btnPress: rgba(255,255,255,.14);
      --focus: rgba(96,165,250,.45);
    }

    *{ box-sizing:border-box; }
    body{
      margin:0;
      background: var(--bg);
      color: var(--text);
      font-family: "Segoe UI Variable","Segoe UI",ui-sans-serif,system-ui,-apple-system,Roboto,Arial;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }

    .wrap{ max-width: 980px; margin:0 auto; padding: 18px 14px 34px; }

    .card{
      background: #1c1c1e;
      border: 1px solid var(--line);
      border-radius: var(--radius);
      box-shadow:none;
      overflow:hidden;
      
      -webkit-
    }
    .p16{ padding:16px; }
    .p12{ padding:12px; }

    .top{
      display:flex;
      align-items:flex-start;
      justify-content:space-between;
      gap:12px;
      margin-bottom: 12px;
    }

    .title{
      display:flex;
      flex-direction:column;
      gap:6px;
    }
    .title h1{
      margin:0;
      font-size: 1.05rem;
      font-weight: 900;
      letter-spacing:.2px;
    }
    .title .sub{
      color: var(--muted);
      font-size: .92rem;
      line-height: 1.25rem;
    }

    
    .btn{
      border:1px solid var(--line);
      background: rgba(255,255,255,.06);
      color: var(--text);
      padding: 10px 14px;
      border-radius: 12px;
      cursor:pointer;
      font-weight: 800;
      user-select:none;
      white-space: nowrap;
    }

    .btn:hover{ background: var(--btnHover); border-color: rgba(255,255,255,.14); }
    .btn:active{ transform: translateY(1px); background: var(--btnPress); }
    .btn:focus{ outline:none; box-shadow:none; }

    /* Header “bancário” */
    .bankHeader{
      display:grid;
      grid-template-columns: 1fr auto;
      gap: 12px;
      align-items:start;
    }
    @media (max-width: 740px){
      .bankHeader{ grid-template-columns: 1fr; }
    }

    .acct{
      display:flex;
      flex-direction:column;
      gap:8px;
    }

    .pillRow{
      display:flex;
      flex-wrap:wrap;
      gap:8px;
      align-items:center;
    }

    .pill{
      display:inline-flex;
      align-items:center;
      gap:8px;
      padding: 7px 10px;
      border-radius: 999px;
      background: rgba(255,255,255,.06);
      border: 1px solid var(--line2);
      color: var(--muted);
      font-size: .88rem;
    }
    .mono{ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; }

    
    .saldoBox{
      background: rgba(96,165,250,.10);
      border: 1px solid rgba(96,165,250,.25);
      border-radius: var(--radius2);
      padding: 12px 14px;
    }

    .saldoBox .lbl{
      color: rgba(169,175,191,.95);
      font-weight: 800;
      font-size: .86rem;
      letter-spacing:.2px;
    }
    .saldoBox .val{
      margin-top: 6px;
      font-size: 1.65rem;
      font-weight: 950;
      letter-spacing:.3px;
      color: #dbeafe;
    }
    .saldoBox .hint{
      margin-top: 6px;
      color: var(--muted);
      font-size: .88rem;
      line-height: 1.2rem;
    }

    /* Resumo */
    .summary{
      margin-top: 12px;
      display:grid;
      grid-template-columns: 1fr 1fr 1fr;
      gap: 10px;
    }
    @media (max-width: 560px){
      .summary{ grid-template-columns: 1fr; }
    }
    .sItem{
      padding: 12px;
      border-radius: var(--radius2);
      border: 1px solid var(--line2);
      background: rgba(255,255,255,.03);
    }
    .sItem .lbl{ color: var(--muted); font-size: .86rem; font-weight: 800; }
    .sItem .val{ margin-top: 6px; font-size: 1.08rem; font-weight: 950; }

    .pos{ color: var(--green); }
    .neg{ color: var(--red); }
    .est{ color: var(--amber); }

    .sep{ height:1px; background: rgba(255,255,255,.06); margin: 12px 0; }

    /* Extrato (banco) */
    .sectionTitle{
      display:flex;
      justify-content:space-between;
      align-items:baseline;
      gap:12px;
      margin-bottom: 10px;
    }
    .sectionTitle .h{
      font-weight: 950;
      letter-spacing:.2px;
    }
    .sectionTitle .meta{
      color: var(--muted);
      font-size: .88rem;
    }

    .tableWrap{
      border: 1px solid var(--line2);
      border-radius: var(--radius2);
      overflow:auto;
      background: rgba(255,255,255,.03);
    }

    table{
      width:100%;
      border-collapse: collapse;
      min-width: 720px;
    }
    th, td{
      padding: 12px 10px;
      border-bottom: 1px solid rgba(255,255,255,.06);
      text-align:left;
      font-size: .92rem;
      vertical-align: top;
    }
    th{
      color: rgba(169,175,191,.95);
      font-weight: 900;
      letter-spacing:.22px;
      background: rgba(0,0,0,.20);
      position: sticky;
      top: 0;
      z-index: 1;
    }
    tr:hover td{ background: rgba(255,255,255,.03); }

    .type{
      display:inline-flex;
      align-items:center;
      justify-content:center;
      min-width: 56px;
      padding: 6px 10px;
      border-radius: 999px;
      border: 1px solid var(--line2);
      font-weight: 950;
      font-size: .80rem;
      letter-spacing:.25px;
      white-space: nowrap;
    }
    .tCR{ color:#86efac; background: rgba(34,197,94,.10); }
    .tDB{ color:#fecaca; background: rgba(239,68,68,.10); }
    .tEST{ color:#fde68a; background: rgba(245,158,11,.12); }

    .desc{
      display:flex;
      flex-direction:column;
      gap:3px;
      white-space: normal;
    }
    .desc .main{ font-weight: 850; }
    .desc .sub{ color: var(--muted); font-size: .86rem; }

    .amt{
      text-align:right;
      font-weight: 950;
      white-space: nowrap;
    }
    .bal{
      text-align:right;
      color: var(--muted);
      font-weight: 900;
      white-space: nowrap;
    }

    .empty{
      padding: 16px;
      color: var(--muted);
      text-align:center;
    }

    .err{
      margin-top: 12px;
      padding: 12px 14px;
      border-radius: 12px;
      border: 1px solid rgba(239,68,68,.30);
      background: rgba(239,68,68,.10);
      color: #fecaca;
      display:none;
      box-shadow:none;
    }

    /* Mobile: cartão por lançamento (padrão extrato banco no app) */
    @media (max-width: 780px){
      table{ min-width: 0; }
      .tableWrap{ overflow: visible; background: transparent; border: 0; }
      table, thead{ display:none; }
      .mList{ display:flex; flex-direction:column; gap:10px; }
      .mRow{
        border: 1px solid var(--line2);
        background: rgba(255,255,255,.03);
        border-radius: var(--radius2);
        padding: 12px;
      }
      .mTop{
        display:flex; justify-content:space-between; align-items:center; gap:10px;
      }
      .mMid{ margin-top:8px; color: var(--muted); font-size:.90rem; }
      .mBot{
        margin-top:10px;
        display:flex; justify-content:space-between; align-items:flex-end; gap:10px;
      }
      .mAmt{ font-weight: 950; font-size: 1.05rem; }
      .mBal{ color: var(--muted); font-weight: 900; }
      .hideOnMobile{ display:none !important; }
    }
  </style>
</head>

<body>
  <div class="wrap">
    <div class="top">
      <div class="title">
        <h1>Extrato</h1>
        <div class="sub">Lançamentos e saldo do seu cartão</div>
      </div>
      <button class="btn" id="btnAtualizar">Atualizar</button>
    </div>

    <!-- Header bancário -->
    <div class="card">
      <div class="p16">
        <div class="bankHeader">
          <div class="acct">
            <div class="pillRow">
              <div class="pill" id="chipCodigo">Cartão: <span class="mono">—</span></div>
              <div class="pill" id="chipStatus">Status: —</div>
              <div class="pill" id="chipMesa">Mesa: —</div>
            </div>

            <div class="summary">
              <div class="sItem">
                <div class="lbl">Entradas</div>
                <div class="val pos" id="vCreditos">R$ 0,00</div>
              </div>
              <div class="sItem">
                <div class="lbl">Saídas</div>
                <div class="val neg" id="vDebitos">R$ 0,00</div>
              </div>
              <div class="sItem">
                <div class="lbl">Estornos</div>
                <div class="val est" id="vEstornos">R$ 0,00</div>
              </div>
            </div>
          </div>

          <div class="saldoBox">
            <div class="lbl">Saldo disponível</div>
            <div class="val" id="vSaldoGrande">R$ 0,00</div>
            <div class="hint">Recargas são feitas no balcão.</div>
          </div>
        </div>

        <div class="err" id="boxErr"></div>
      </div>
    </div>

    <div style="height:12px"></div>

    <!-- Extrato estilo banco -->
    <div class="card">
      <div class="p16">
        <div class="sectionTitle">
          <div class="h">Lançamentos</div>
          <div class="meta" id="chipQtd">0 itens</div>
        </div>

        <div class="tableWrap" id="tableWrap">
          <table aria-label="Extrato">
            <thead>
              <tr>
                <th style="width:120px">Data/Hora</th>
                <th>Descrição</th>
                <th style="width:140px; text-align:right">Valor</th>
                <th style="width:140px; text-align:right">Saldo após</th>
              </tr>
            </thead>
            <tbody id="tbody">
              <tr><td colspan="4" class="empty">Carregando…</td></tr>
            </tbody>
          </table>

          <!-- mobile list -->
          <div class="mList" id="mList" style="display:none;"></div>
        </div>
      </div>
    </div>
  </div>

<script>
  const CODIGO = <?= json_encode($codigo, JSON_UNESCAPED_UNICODE) ?>;
  const TOKEN  = <?= json_encode($token, JSON_UNESCAPED_UNICODE) ?>;

  const $ = (q)=>document.querySelector(q);

  function money(v){
    try{
      return (Number(v)||0).toLocaleString('pt-BR',{style:'currency',currency:'BRL'});
    }catch(e){
      return 'R$ ' + (Number(v)||0).toFixed(2).replace('.',',');
    }
  }

  function showErr(msg){
    const box = $("#boxErr");
    box.style.display = "block";
    box.textContent = msg || "Erro.";
  }
  function clearErr(){
    const box = $("#boxErr");
    box.style.display = "none";
    box.textContent = "";
  }

  async function api(action, params={}){
    const url = new URL("api.php", window.location.href);
    url.searchParams.set("action", action);
    url.searchParams.set("c", CODIGO);
    if (TOKEN) url.searchParams.set("t", TOKEN);
    Object.entries(params).forEach(([k,v])=>url.searchParams.set(k, v));

    const r = await fetch(url.toString(), { headers: { "Accept":"application/json" }});
    const j = await r.json().catch(()=>null);
    if(!r.ok || !j || j.ok !== true){
      const err = (j && j.error) ? j.error : ("Falha ao consultar ("+r.status+").");
      throw new Error(err);
    }
    return j;
  }

  // guardamos saldo atual para calcular "saldo após" por linha
  let SALDO_ATUAL = 0;

  function renderInfo(j){
    const c = j.cartao || {};
    const s = j.saldo  || {};

    const est = Number(s.estornos || 0);

    $("#chipCodigo").innerHTML = `Cartão: <span class="mono">${escapeHtml(c.codigo || "—")}</span>`;
    $("#chipStatus").textContent = "Status: " + (c.status || "—");
    $("#chipMesa").textContent   = "Mesa: " + (c.mesa ? ("#" + c.mesa) : "—");

    $("#vCreditos").textContent = money(s.creditos);
    $("#vDebitos").textContent  = money(s.debitos);
    $("#vEstornos").textContent = money(est);

    $("#vSaldoGrande").textContent = money(s.saldo);

    SALDO_ATUAL = Number(s.saldo || 0);
  }

  function tipoLancamento(it){
    const op = (it.operacao || "").toUpperCase();
    const motivoUp = (it.motivo || "").toUpperCase();
    const isEstorno = (op === "E") || (motivoUp === "ESTORNO");
    if (isEstorno) return "EST";
    if (op === "C") return "CR";
    return "DB";
  }

  function efeito(it){
    // efeito no saldo: CR +, EST +, DB -
    const t = tipoLancamento(it);
    const v = Number(it.valor || 0);
    if (t === "DB") return -v;
    return +v;
  }

  function fmtDataHora(s){
    // tenta ficar “banco”: dd/mm hh:mm, mas sem quebrar se vier diferente
    const raw = String(s || "").trim();
    if (!raw) return "—";
    // se vier "YYYY-MM-DD HH:MM:SS"
    const m = raw.match(/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})/);
    if (m){
      const dd = m[3], mm = m[2], hh = m[4], mi = m[5];
      return `${dd}/${mm} ${hh}:${mi}`;
    }
    return raw;
  }

  function renderExtrato(itens){
    const tbody = $("#tbody");
    const mList = $("#mList");
    tbody.innerHTML = "";
    mList.innerHTML = "";

    const qtd = (itens && itens.length) ? itens.length : 0;
    $("#chipQtd").textContent = qtd + " itens";

    // mobile detection
    const isMobile = window.matchMedia && window.matchMedia("(max-width: 780px)").matches;
    $("#mList").style.display = isMobile ? "flex" : "none";
    $("#tableWrap").classList.toggle("isMobile", isMobile);

    if(!qtd){
      tbody.innerHTML = `<tr><td colspan="4" class="empty">Nenhum lançamento encontrado.</td></tr>`;
      if (isMobile){
        mList.innerHTML = `<div class="empty">Nenhum lançamento encontrado.</div>`;
      }
      return;
    }

    // cálculo do "saldo após" em ordem decrescente (mais recente primeiro)
    // Linha 1 (mais recente): saldo após = SALDO_ATUAL
    // Próxima linha: saldo após = SALDO_ATUAL - efeito(linha anterior)
    let saldoApos = SALDO_ATUAL;

    for (let i=0; i<itens.length; i++){
      const it = itens[i];
      const t = tipoLancamento(it);
      const dt = fmtDataHora(it.criado_em || it.data || "");
      const motivo = (it.motivo || "-");
      const origem = (it.origem || "-");

      const val = Number(it.valor || 0);
      const valCls = (t === "DB") ? "neg" : (t === "EST" ? "est" : "pos");
      const tipoCls = (t === "DB") ? "type tDB" : (t === "EST" ? "type tEST" : "type tCR");

      const saldoLinha = saldoApos;

      // prepara próximo saldoApos (saldo depois do próximo lançamento mais antigo)
      saldoApos = saldoApos - efeito(it);

      if (!isMobile){
        const tr = document.createElement("tr");
        tr.innerHTML = `
          <td class="mono">${escapeHtml(dt)}</td>
          <td>
            <div class="desc">
              <div class="main"><span class="${tipoCls}">${t}</span> &nbsp; ${escapeHtml(motivo)}</div>
              <div class="sub">${escapeHtml(origem)}</div>
            </div>
          </td>
          <td class="amt ${valCls}">${money(val)}</td>
          <td class="bal">${money(saldoLinha)}</td>
        `;
        tbody.appendChild(tr);
      } else {
        const div = document.createElement("div");
        div.className = "mRow";
        div.innerHTML = `
          <div class="mTop">
            <div class="${tipoCls}">${t}</div>
            <div class="mono" style="color:var(--muted); font-weight:800;">${escapeHtml(dt)}</div>
          </div>
          <div class="mMid">
            <div style="font-weight:900; color:var(--text)">${escapeHtml(motivo)}</div>
            <div style="margin-top:2px;">${escapeHtml(origem)}</div>
          </div>
          <div class="mBot">
            <div class="mAmt ${valCls}">${money(val)}</div>
            <div class="mBal">Saldo após: ${money(saldoLinha)}</div>
          </div>
        `;
        mList.appendChild(div);
      }
    }
  }

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

  async function carregar(){
    clearErr();

    if(!CODIGO){
      showErr("Cartão inválido: código não informado.");
      $("#tbody").innerHTML = `<tr><td colspan="4" class="empty">Cartão inválido.</td></tr>`;
      return;
    }

    $("#tbody").innerHTML = `<tr><td colspan="4" class="empty">Carregando…</td></tr>`;
    $("#mList").innerHTML = ``;

    try{
      const info = await api("info");
      renderInfo(info);

      const ext = await api("extrato", { limit: 60 });
      renderExtrato(ext.itens || []);
    }catch(e){
      showErr(e.message || "Erro ao carregar.");
      $("#tbody").innerHTML = `<tr><td colspan="4" class="empty">Não foi possível carregar o extrato.</td></tr>`;
      $("#mList").innerHTML = `<div class="empty">Não foi possível carregar o extrato.</div>`;
    }
  }

  $("#btnAtualizar").addEventListener("click", carregar);
  window.addEventListener("resize", ()=> {
    // re-render para alternar tabela <-> cards quando mudar breakpoint
    // sem chamar API de novo
    const currentRows = window.__lastItens || null;
    if (currentRows) renderExtrato(currentRows);
  });

  // intercepta renderExtrato para guardar itens (para resize)
  const _renderExtrato = renderExtrato;
  renderExtrato = function(itens){
    window.__lastItens = itens || [];
    return _renderExtrato(itens || []);
  }

  carregar();
</script>
</body>
</html>
