<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

require_once __DIR__ . "/../../includes/db.php";
header("Content-Type: application/json; charset=utf-8");

if (session_status() !== PHP_SESSION_ACTIVE) {
  session_start();
}

$action = $_GET["action"] ?? "";

// ---------- helpers ----------
function json_input(): array {
  $raw = file_get_contents("php://input");
  $data = json_decode($raw, true);
  return is_array($data) ? $data : [];
}

function table_exists(PDO $pdo, string $table): bool {
  try {
    $st = $pdo->prepare("SELECT COUNT(*) c FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME=?");
    $st->execute([$table]);
    $r = $st->fetch();
    return ((int)($r['c'] ?? 0) > 0);
  } catch (Throwable $e) {
    return false;
  }
}

function column_exists(PDO $pdo, string $table, string $column): bool {
  try {
    $st = $pdo->prepare("
      SELECT COUNT(*) c
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_SCHEMA = DATABASE()
        AND TABLE_NAME = ?
        AND COLUMN_NAME = ?
    ");
    $st->execute([$table, $column]);
    $r = $st->fetch();
    return ((int)($r['c'] ?? 0) > 0);
  } catch (Throwable $e) {
    return false;
  }
}

function esc($s): string {
  return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}

// ---------- totais ----------

// soma lançamentos avulsos confirmados da SESSÃO (se existir tabela lancamentos)
function total_avulsos_sessao(PDO $pdo, int $contaId, string $sessaoKey): float {
  if ($contaId <= 0 || $sessaoKey === '') return 0.0;
  if (!table_exists($pdo, 'lancamentos')) return 0.0;

  try {
    $st = $pdo->prepare("
      SELECT COALESCE(SUM(valor),0) AS total
      FROM lancamentos
      WHERE conta_id=? AND sessao_key=? AND status='CONFIRMADO'
    ");
    $st->execute([$contaId, $sessaoKey]);
    $r = $st->fetch();
    return (float)($r['total'] ?? 0);
  } catch (Throwable $e) {
    return 0.0;
  }
}

// ✅ soma lançamentos avulsos confirmados da CONTA (mesa inteira)
function total_avulsos_conta(PDO $pdo, int $contaId): float {
  if ($contaId <= 0) return 0.0;
  if (!table_exists($pdo, 'lancamentos')) return 0.0;

  try {
    $st = $pdo->prepare("
      SELECT COALESCE(SUM(valor),0) AS total
      FROM lancamentos
      WHERE conta_id=? AND status='CONFIRMADO'
    ");
    $st->execute([$contaId]);
    $r = $st->fetch();
    return (float)($r['total'] ?? 0);
  } catch (Throwable $e) {
    return 0.0;
  }
}

// tenta descobrir soma da fatura (se existir tabela fatura_itens / movimentos etc)
function total_fatura(PDO $pdo, int $contaId): float {
  if ($contaId <= 0) return 0.0;

  // tenta tabela fatura_itens
  if (table_exists($pdo, 'fatura_itens')) {
    try {
      $st = $pdo->prepare("SELECT COALESCE(SUM(valor_total),0) AS t FROM fatura_itens WHERE conta_id=?");
      $st->execute([$contaId]);
      $r = $st->fetch();
      return (float)($r['t'] ?? 0);
    } catch (Throwable $e) {}
  }

  // tenta tabela pedido_itens (padrão do projeto)
  if (table_exists($pdo, 'pedido_itens') && table_exists($pdo, 'pedidos')) {
    try {
      $st = $pdo->prepare("
        SELECT COALESCE(SUM(pi.qtd*pi.preco_unit),0) AS t
        FROM pedido_itens pi
        JOIN pedidos p ON p.id = pi.pedido_id
        WHERE p.conta_id=? AND p.status IN ('ENTREGUE','EM_PREPARO','ACEITO')
      ");
      $st->execute([$contaId]);
      $r = $st->fetch();
      return (float)($r['t'] ?? 0);
    } catch (Throwable $e) {}
  }

  return 0.0;
}

// tenta descobrir total já descontado (se existir tabela descontos)
function total_pago_conta(PDO $pdo, int $contaId): float {
  // Total já pago/abatido na conta (mesa)
  if ($contaId <= 0) return 0.0;
  if (!table_exists($pdo, 'pagamentos')) return 0.0;

  try {
    // segue o mesmo padrão do balcão: apenas CONFIRMADO
    $st = $pdo->prepare("SELECT COALESCE(SUM(valor),0) AS t FROM pagamentos WHERE conta_id=? AND status='CONFIRMADO'");
    $st->execute([$contaId]);
    $r = $st->fetch();
    return (float)($r['t'] ?? 0);
  } catch (Throwable $e) {
    return 0.0;
  }
}

function total_pago_sessao(PDO $pdo, int $contaId, string $sessaoKey): float {
  // Total já pago/abatido apenas desta sessão (cliente atual)
  if ($contaId <= 0) return 0.0;
  if ($sessaoKey === "") return 0.0;
  if (!table_exists($pdo, 'pagamentos')) return 0.0;
  if (!column_exists($pdo, 'pagamentos', 'sessao_key')) return 0.0;

  try {
    $st = $pdo->prepare("SELECT COALESCE(SUM(valor),0) AS t FROM pagamentos WHERE conta_id=? AND sessao_key=? AND status='CONFIRMADO'");
    $st->execute([$contaId, $sessaoKey]);
    $r = $st->fetch();
    return (float)($r['t'] ?? 0);
  } catch (Throwable $e) {
    return 0.0;
  }
}



// ---------- Controle de participação na mesa (autorização de entrada) ----------
function require_table(PDO $pdo, string $table): void {
  if (!table_exists($pdo, $table)) {
    http_response_code(500);
    echo json_encode(["ok"=>false, "error"=>"Tabela necessária não encontrada: {$table}"], JSON_UNESCAPED_UNICODE);
    exit;
  }
}

function participante_row(PDO $pdo, int $contaId, int $clienteId, string $sessaoKey): ?array {
  if ($contaId <= 0 || $clienteId <= 0 || $sessaoKey === '') return null;
  require_table($pdo, 'conta_participantes');

  $st = $pdo->prepare("
    SELECT id, conta_id, cliente_id, sessao_key, status, solicitado_em, aprovado_em, aprovado_por_cliente_id
    FROM conta_participantes
    WHERE conta_id=? AND cliente_id=? AND sessao_key=?
    ORDER BY id DESC
    LIMIT 1
  ");
  $st->execute([$contaId, $clienteId, $sessaoKey]);
  $r = $st->fetch();
  return $r ?: null;
}

function require_login_basic(): array {
  $cid = (int)($_SESSION["cliente_id"] ?? 0);
  $contaId = (int)($_SESSION["conta_id"] ?? 0);
  $sessaoKey = (string)($_SESSION["sessao_key"] ?? "");

  if ($cid <= 0 || $contaId <= 0 || $sessaoKey === "") {
    http_response_code(403);
    echo json_encode(["ok"=>false, "error"=>"Cliente não identificado"], JSON_UNESCAPED_UNICODE);
    exit;
  }
  return [$cid, $contaId, $sessaoKey];
}

function require_participante(PDO $pdo): array {
  [$cid, $contaId, $sessaoKey] = require_login_basic();
  $p = participante_row($pdo, $contaId, $cid, $sessaoKey);
  if (!$p) {
    http_response_code(403);
    echo json_encode(["ok"=>false, "error"=>"Sessão inválida. Identifique-se novamente.", "force_reidentify"=>true], JSON_UNESCAPED_UNICODE);
    exit;
  }
  return [$cid, $contaId, $sessaoKey, $p];
}

function require_participante_ativo(PDO $pdo): array {
  [$cid, $contaId, $sessaoKey, $p] = require_participante($pdo);
  if (($p["status"] ?? "") !== "ATIVO") {
    http_response_code(403);
    echo json_encode(["ok"=>false, "error"=>"Aguardando autorização para entrar na mesa.", "pending"=>true], JSON_UNESCAPED_UNICODE);
    exit;
  }
  return [$cid, $contaId, $sessaoKey, $p];
}


// ---------- liberação de mesa (garçom) ----------
function liberacao_mode(PDO $pdo): string {
  // 'flag' se existir contas.liberada, 'ts' se existir contas.liberada_em, senão 'table'
  if (column_exists($pdo, "contas", "liberada")) return "flag";
  if (column_exists($pdo, "contas", "liberada_em")) return "ts";
  return "table";
}

function ensure_contas_liberacoes(PDO $pdo): void {
  if (table_exists($pdo, 'contas_liberacoes')) return;
  $pdo->exec("
    CREATE TABLE IF NOT EXISTS contas_liberacoes (
      conta_id INT NOT NULL PRIMARY KEY,
      liberada TINYINT(1) NOT NULL DEFAULT 0,
      liberada_em DATETIME NULL,
      liberada_por INT NULL,
      criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
      atualizado_em DATETIME NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  ");
}


function conta_liberacao_status(PDO $pdo, int $contaId): int {
  // 0 pendente | 1 liberada | 2 recusada
  if ($contaId <= 0) return 0;

  // sempre cria/usa tabela auxiliar (suporta RECUSADA mesmo quando contas.liberada existe)
  ensure_contas_liberacoes($pdo);

  $st = $pdo->prepare("SELECT liberada FROM contas_liberacoes WHERE conta_id=? LIMIT 1");
  $st->execute([$contaId]);
  $r = $st->fetch(PDO::FETCH_ASSOC);
  if ($r) return (int)($r["liberada"] ?? 0);

  // sem registro -> inferir pela tabela contas
  $mode = liberacao_mode($pdo);

  if ($mode === "flag") {
    $st = $pdo->prepare("SELECT COALESCE(liberada,0) AS liberada FROM contas WHERE id=? LIMIT 1");
    $st->execute([$contaId]);
    $r = $st->fetch(PDO::FETCH_ASSOC);
    return ((int)($r["liberada"] ?? 0) === 1) ? 1 : 0;
  }

  if ($mode === "ts") {
    $st = $pdo->prepare("SELECT liberada_em FROM contas WHERE id=? LIMIT 1");
    $st->execute([$contaId]);
    $r = $st->fetch(PDO::FETCH_ASSOC);
    return (!empty($r["liberada_em"])) ? 1 : 0;
  }

  return 0;
}

function conta_esta_liberada(PDO $pdo, int $contaId): bool {
  return (conta_liberacao_status($pdo, $contaId) === 1);
}


function conta_pendente_liberacao(PDO $pdo, int $contaId): bool {
  if ($contaId <= 0) return true;
  return !conta_esta_liberada($pdo, $contaId);
}


// ---------- actions ----------

/**
 * ME (info da sessão)
 */
if ($action === "me") {
  $cid = (int)($_SESSION["cliente_id"] ?? 0);
  $sessaoKey = (string)($_SESSION["sessao_key"] ?? "");
  $contaId = (int)($_SESSION["conta_id"] ?? 0);

  if ($cid <= 0) {
    echo json_encode(["ok" => true, "logado" => false], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $stmt = $pdo->prepare("SELECT id, nome, celular, criado_em FROM clientes WHERE id=?");
  $stmt->execute([$cid]);
  $c = $stmt->fetch();

  // status de participação (ATIVO | PENDENTE | ...)
  $pStatus = null;
  if ($contaId > 0 && $sessaoKey !== "" && table_exists($pdo, 'conta_participantes')) {
    $p = participante_row($pdo, $contaId, $cid, $sessaoKey);
    $pStatus = $p ? ($p["status"] ?? null) : null;
  }

  echo json_encode([
    "ok" => true,
    "logado" => true,
    "cliente" => $c,
    "conta_id" => $contaId,
    "mesa_liberada" => ($contaId>0 ? conta_esta_liberada($pdo,$contaId) : false),
    "liberacao_mode" => ($contaId>0 ? liberacao_mode($pdo) : null),
    "sessao_key_ok" => ($sessaoKey !== ""),
    "participante_status" => $pStatus,
    "pode_autorizar" => ($pStatus === "ATIVO")
  ], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * STATUS_ENTRADA
 */
if ($action === "status_entrada") {
  [$cid, $contaId, $sessaoKey, $p] = require_participante($pdo);
  echo json_encode(["ok"=>true, "status"=>$p["status"]], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * SOLICITACOES_ENTRADA
 */
if ($action === "solicitacoes_entrada") {
  [$cid, $contaId, $sessaoKey, $p] = require_participante_ativo($pdo);

  $st = $pdo->prepare("
    SELECT cp.id, cp.solicitado_em, cl.nome, cl.celular
    FROM conta_participantes cp
    JOIN clientes cl ON cl.id = cp.cliente_id
    WHERE cp.conta_id=? AND cp.status='PENDENTE'
    ORDER BY cp.id ASC
    LIMIT 50
  ");
  $st->execute([$contaId]);
  $rows = $st->fetchAll();

  echo json_encode(["ok"=>true, "solicitacoes"=>$rows], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * APROVAR_ENTRADA
 */
if ($action === "aprovar_entrada") {
  [$cid, $contaId, $sessaoKey, $p] = require_participante_ativo($pdo);
  $data = json_input();
  $pid = (int)($data["participante_id"] ?? 0);

  if ($pid <= 0) {
    http_response_code(400);
    echo json_encode(["ok"=>false, "error"=>"participante_id inválido"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $st = $pdo->prepare("SELECT id, cliente_id, status FROM conta_participantes WHERE id=? AND conta_id=? LIMIT 1");
  $st->execute([$pid, $contaId]);
  $alvo = $st->fetch();

  if (!$alvo) {
    http_response_code(404);
    echo json_encode(["ok"=>false, "error"=>"Solicitação não encontrada"], JSON_UNESCAPED_UNICODE);
    exit;
  }
  if ($alvo["status"] !== "PENDENTE") {
    echo json_encode(["ok"=>true, "already"=>true], JSON_UNESCAPED_UNICODE);
    exit;
  }
  if ((int)$alvo["cliente_id"] === $cid) {
    http_response_code(400);
    echo json_encode(["ok"=>false, "error"=>"Você não pode aprovar a si mesmo"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $st = $pdo->prepare("UPDATE conta_participantes SET status='ATIVO', aprovado_em=NOW(), aprovado_por_cliente_id=? WHERE id=? AND conta_id=? AND status='PENDENTE'");
  $st->execute([$cid, $pid, $contaId]);

  echo json_encode(["ok"=>true], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * RECUSAR_ENTRADA
 */
if ($action === "recusar_entrada") {
  [$cid, $contaId, $sessaoKey, $p] = require_participante_ativo($pdo);
  $data = json_input();
  $pid = (int)($data["participante_id"] ?? 0);

  if ($pid <= 0) {
    http_response_code(400);
    echo json_encode(["ok"=>false, "error"=>"participante_id inválido"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $st = $pdo->prepare("UPDATE conta_participantes SET status='NEGADO', aprovado_em=NOW(), aprovado_por_cliente_id=? WHERE id=? AND conta_id=? AND status='PENDENTE'");
  $st->execute([$cid, $pid, $contaId]);

  echo json_encode(["ok"=>true], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * MENU
 */
if ($action === "menu") {
  $cols = $pdo->query("
    SELECT COLUMN_NAME
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME = 'produtos'
  ")->fetchAll(PDO::FETCH_COLUMN);

  $hasFoto = in_array('foto', $cols, true);

  $select = "id, nome, descricao, categoria, preco, ativo";
  if ($hasFoto) $select .= ", foto";

  $stmt = $pdo->prepare("SELECT {$select} FROM produtos WHERE ativo=1 ORDER BY categoria, nome");
  $stmt->execute();
  $rows = $stmt->fetchAll();

  echo json_encode(["ok" => true, "produtos" => $rows], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * ABRIR_CONTA
 */
if ($action === "abrir_conta") {
  $mesa = (int)($_GET["mesa"] ?? 0);
  $token = $_GET["token"] ?? "";
  if ($mesa <= 0 || $token === "") {
    http_response_code(400);
    echo json_encode(["ok" => false, "error" => "Mesa/token inválidos"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $stmt = $pdo->prepare("SELECT id FROM mesas WHERE numero=? AND token=? AND ativa=1 LIMIT 1");
  $stmt->execute([$mesa, $token]);
  $m = $stmt->fetch();
  if (!$m) {
    http_response_code(403);
    echo json_encode(["ok" => false, "error" => "Mesa não encontrada ou inativa"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $mesaId = (int)$m["id"];

  $mode = liberacao_mode($pdo);

  // tenta reutilizar uma conta ABERTA
  $stmt = $pdo->prepare("SELECT id FROM contas WHERE mesa_id=? AND status='ABERTA' ORDER BY id DESC LIMIT 1");
  $stmt->execute([$mesaId]);
  $c = $stmt->fetch();

  if (!$c) {
    // cria conta ABERTA (compatível com ENUM existente) e marca liberação como pendente
    if ($mode === "flag" && column_exists($pdo, 'contas', 'liberada')) {
      $st = $pdo->prepare("INSERT INTO contas (mesa_id, status, aberta_em, liberada) VALUES (?, 'ABERTA', NOW(), 0)");
      $st->execute([$mesaId]);
      $contaId = (int)$pdo->lastInsertId();
    } else {
      $st = $pdo->prepare("INSERT INTO contas (mesa_id, status, aberta_em) VALUES (?, 'ABERTA', NOW())");
      $st->execute([$mesaId]);
      $contaId = (int)$pdo->lastInsertId();
    }

    if ($mode === "table") {
      ensure_contas_liberacoes($pdo);
      // insere registro pendente (opcional; se não inserir, fica pendente do mesmo jeito)
      $ins = $pdo->prepare("INSERT INTO contas_liberacoes (conta_id, liberada) VALUES (?,0)");
      $ins->execute([$contaId]);
    }
  } else {
    $contaId = (int)$c["id"];
  }

  $_SESSION["mesa"] = $mesa;
  $_SESSION["token"] = $token;
  $_SESSION["conta_id"] = $contaId;

  
  // garante registro na tabela auxiliar de liberação (0 = pendente)
  try{
    ensure_contas_liberacoes($pdo);
    $st2 = $pdo->prepare("INSERT IGNORE INTO contas_liberacoes (conta_id, liberada) VALUES (?,0)");
    $st2->execute([$contaId]);
  }catch(Throwable $e){}
echo json_encode(["ok" => true, "conta_id" => $contaId], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * CRIAR_PEDIDO (somente ATIVO)
 */
if ($action === "criar_pedido") {
  [$cidSess, $contaSessId, $sessaoKey, $pRow] = require_participante_ativo($pdo);
  $data = json_input();
  $contaId = (int)($data["conta_id"] ?? 0);

  if ($contaId !== $contaSessId) {
    http_response_code(403);
    echo json_encode(["ok"=>false, "error"=>"Conta inválida para esta sessão", "force_reidentify"=>true], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $itens = $data["itens"] ?? [];
  if ($contaId <= 0 || !is_array($itens) || count($itens) === 0) {
    http_response_code(400);
    echo json_encode(["ok" => false, "error" => "Dados inválidos"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $stmt = $pdo->prepare("SELECT id, status FROM contas WHERE id=?");
  $stmt->execute([$contaId]);
  $conta = $stmt->fetch();

  if (!$conta) {
    http_response_code(404);
    echo json_encode(["ok" => false, "error" => "Conta não encontrada"], JSON_UNESCAPED_UNICODE);
    exit;
  }
  // Se conta não está liberada pelo garçom, bloqueia envio do pedido
  if (conta_pendente_liberacao($pdo, $contaId)) {
    http_response_code(403);
    echo json_encode(["ok"=>false, "error"=>"Aguardando liberação do garçom.", "pending_release"=>true], JSON_UNESCAPED_UNICODE);
    exit;
  }

  // Se a conta não está mais aberta (fechada/encerrada), força reidentificar
  if (($conta["status"] ?? "") !== "ABERTA") {
    http_response_code(403);
    echo json_encode(["ok" => false, "error" => "Conta fechada", "force_reidentify" => true], JSON_UNESCAPED_UNICODE);
    exit;
  }

  
  // 🚦 Liberação do garçom (mesa/conta)
  $libStatus = conta_liberacao_status($pdo, $contaId);
  if ($libStatus !== 1) {
    http_response_code(403);
    if ($libStatus === 2) {
      echo json_encode([
        "ok"=>false,
        "error"=>"Liberação recusada pelo garçom.",
        "pending_release"=>true,
        "refused"=>true
      ], JSON_UNESCAPED_UNICODE);
    } else {
      echo json_encode([
        "ok"=>false,
        "error"=>"Aguardando liberação do garçom para pedir.",
        "pending_release"=>true
      ], JSON_UNESCAPED_UNICODE);
    }
    exit;
  }

$pdo->beginTransaction();
  try {
    $stmt = $pdo->prepare("INSERT INTO pedidos (conta_id, cliente_id, sessao_key, status, criado_em) VALUES (?, ?, ?, 'NOVO', NOW())");
    $stmt->execute([$contaId, $cidSess, $sessaoKey]);
    $pedidoId = (int)$pdo->lastInsertId();

    $stmtItem = $pdo->prepare("INSERT INTO pedido_itens (pedido_id, produto_id, qtd, preco_unit, observacao) VALUES (?, ?, ?, ?, ?)");
    $stmtProd = $pdo->prepare("SELECT id, preco, ativo FROM produtos WHERE id=? AND ativo=1");

    foreach ($itens as $it) {
      $produtoId = (int)($it["produto_id"] ?? 0);
      $qtd = (int)($it["qtd"] ?? 0);
      $obs = (string)($it["obs"] ?? "");

      if ($produtoId <= 0 || $qtd <= 0) throw new Exception("Item inválido");

      $stmtProd->execute([$produtoId]);
      $p = $stmtProd->fetch();
      if (!$p) throw new Exception("Produto inválido/inativo: {$produtoId}");

      $stmtItem->execute([$pedidoId, $produtoId, $qtd, $p["preco"], $obs]);
    }

    $pdo->commit();
    echo json_encode(["ok" => true, "pedido_id" => $pedidoId], JSON_UNESCAPED_UNICODE);
  } catch (Exception $e) {
    $pdo->rollBack();
    http_response_code(500);
    echo json_encode(["ok" => false, "error" => $e->getMessage()], JSON_UNESCAPED_UNICODE);
  }
  exit;
}

/**
 * CHAMAR_GARCOM (somente ATIVO)
 */
if ($action === "chamar_garcom") {
  [$cidSess, $contaSessId, $sessaoKey, $pRow] = require_participante_ativo($pdo);
  $data = json_input();
  $mesa = (int)($data["mesa"] ?? 0);
  $contaId = (int)($data["conta_id"] ?? 0);

  if ($contaId !== $contaSessId) {
    http_response_code(403);
    echo json_encode(["ok"=>false, "error"=>"Conta inválida para esta sessão", "force_reidentify"=>true], JSON_UNESCAPED_UNICODE);
    exit;
  }

  if ($mesa <= 0) {
    http_response_code(400);
    echo json_encode(["ok" => false, "error" => "Mesa inválida"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $stmt = $pdo->prepare("SELECT id FROM mesas WHERE numero=? AND ativa=1 LIMIT 1");
  $stmt->execute([$mesa]);
  $m = $stmt->fetch();
  if (!$m) {
    http_response_code(403);
    echo json_encode(["ok" => false, "error" => "Mesa não encontrada"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  if (!table_exists($pdo, "chamados_garcom")) {
    $pdo->exec("
      CREATE TABLE IF NOT EXISTS chamados_garcom (
        id INT AUTO_INCREMENT PRIMARY KEY,
        mesa INT NOT NULL,
        conta_id INT NOT NULL,
        cliente_id INT NOT NULL,
        sessao_key VARCHAR(20) NOT NULL,
        status ENUM('ABERTO','ATENDIDO') NOT NULL DEFAULT 'ABERTO',
        criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        atendido_em DATETIME NULL
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    ");
  }

  $st = $pdo->prepare("INSERT INTO chamados_garcom (mesa, conta_id, cliente_id, sessao_key, status) VALUES (?, ?, ?, ?, 'ABERTO')");
  $st->execute([$mesa, $contaId, $cidSess, $sessaoKey]);

  echo json_encode(["ok" => true], JSON_UNESCAPED_UNICODE);
  exit;
}

/**
 * STATUS_PEDIDOS (somente ATIVO)
 * ✅ Agora retorna totais da MESA (conta inteira) e da SESSÃO (cliente atual)
 */
if ($action === "status_pedidos") {
  [$cidSess, $contaSessId, $sessaoKey, $pRow] = require_participante_ativo($pdo);

  $contaId = (int)($_GET["conta_id"] ?? 0);
  if ($contaId <= 0) {
    http_response_code(400);
    echo json_encode(["ok" => false, "error" => "conta_id inválido"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  if ($contaId !== $contaSessId) {
    http_response_code(403);
    echo json_encode(["ok"=>false, "error"=>"Conta inválida para esta sessão", "force_reidentify"=>true], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $stmt = $pdo->prepare("SELECT id, status FROM contas WHERE id=?");
  $stmt->execute([$contaId]);
  $conta = $stmt->fetch();

  if (!$conta) {
    http_response_code(404);
    echo json_encode(["ok" => false, "error" => "Conta não encontrada"], JSON_UNESCAPED_UNICODE);
    exit;
  }

  if ($conta["status"] !== "ABERTA") {
    echo json_encode(["ok" => true, "conta_status" => $conta["status"], "pedidos" => []], JSON_UNESCAPED_UNICODE);
    exit;
  }

  $hasSessaoSeq = column_exists($pdo, "pedidos", "sessao_seq");
  $sessaoSeqSelect = $hasSessaoSeq ? "p.sessao_seq" : "0 AS sessao_seq";

  try {
    // pedidos da sessão atual
    $stmt = $pdo->prepare("
      SELECT
        p.id AS pedido_id,
        p.status,
        p.criado_em,
        {$sessaoSeqSelect},
        COALESCE(SUM(pi.qtd*pi.preco_unit),0) AS total
      FROM pedidos p
      LEFT JOIN pedido_itens pi ON pi.pedido_id = p.id
      WHERE p.conta_id=? AND p.sessao_key=?
      GROUP BY p.id
      ORDER BY p.id DESC
      LIMIT 50
    ");
    $stmt->execute([$contaId, $sessaoKey]);
    $rows = $stmt->fetchAll();

    // totais da mesa
    $mesaFatura     = total_fatura($pdo, $contaId);
    $mesaAvulsos    = total_avulsos_conta($pdo, $contaId);
    $mesaDescontado = total_pago_conta($pdo, $contaId);
    $mesaTotal      = ($mesaFatura + $mesaAvulsos - $mesaDescontado);

    // totais da sessão
    $sessaoPedidos = 0.0;
    foreach ($rows as $r) {
      $st = strtoupper(trim((string)($r["status"] ?? "")));
      // pedidos cancelados/recusados NÃO entram na fatura da sessão
      if ($st === "CANCELADO" || $st === "RECUSADO" || $st === "NEGADO" || strpos($st, "CANCEL") === 0 || strpos($st, "RECUS") === 0) {
        continue;
      }
      $sessaoPedidos += (float)($r["total"] ?? 0);
    }
    $sessaoAvulsos = total_avulsos_sessao($pdo, $contaId, $sessaoKey);
    $sessaoDescontado = total_pago_sessao($pdo, $contaId, $sessaoKey);
    $sessaoTotal   = ($sessaoPedidos + $sessaoAvulsos - $sessaoDescontado);
echo json_encode([
      "ok" => true,
      "conta_status" => $conta["status"],
      "pedidos" => $rows,
      "totais" => [
        "mesa" => [
          "fatura"     => $mesaFatura,
          "avulsos"    => $mesaAvulsos,
          "descontado" => $mesaDescontado,
          "total"      => $mesaTotal,
        ],
        "sessao" => [
          "pedidos" => $sessaoPedidos,
          "avulsos" => $sessaoAvulsos,
          "descontado" => $sessaoDescontado,
          "total"   => $sessaoTotal,
        ]
      ]
    ], JSON_UNESCAPED_UNICODE);
  } catch (Throwable $e) {
    http_response_code(500);
    echo json_encode(["ok"=>false, "error"=>"Falha ao carregar pedidos: ".$e->getMessage()], JSON_UNESCAPED_UNICODE);
  }
  exit;
}

/**
 * LOGOUT
 */
if ($action === "logout") {
  $cid = (int)($_SESSION["cliente_id"] ?? 0);
  $contaId = (int)($_SESSION["conta_id"] ?? 0);
  $sessaoKey = (string)($_SESSION["sessao_key"] ?? "");

  if ($cid > 0 && $contaId > 0 && $sessaoKey !== "" && table_exists($pdo, 'conta_participantes')) {
    try {
      $st = $pdo->prepare("UPDATE conta_participantes SET status='SAIU' WHERE conta_id=? AND cliente_id=? AND sessao_key=? AND status IN ('ATIVO','PENDENTE')");
      $st->execute([$contaId, $cid, $sessaoKey]);
    } catch (Throwable $e) {}
  }

  foreach ([
    'reconnect_mesa',
    'reconnect_token',
    'reconnect_conta',
    'reconnect_cliente',
    'reconnect_sessao',
  ] as $k) {
    @setcookie($k, '', [
      'expires' => time() - 3600,
      'path' => '/',
      'secure' => false,
      'httponly' => true,
      'samesite' => 'Lax',
    ]);
  }

  $_SESSION = [];

  if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
      $params["path"], $params["domain"],
      $params["secure"], $params["httponly"]
    );
  }

  @session_destroy();

  echo json_encode(["ok" => true], JSON_UNESCAPED_UNICODE);
  exit;
}

http_response_code(404);
echo json_encode(["ok" => false, "error" => "Ação inválida"], JSON_UNESCAPED_UNICODE);
