<?php
// chat_api/stream.php
declare(strict_types=1);
require_once __DIR__.'/_db.php';

@set_time_limit(0);
@ignore_user_abort(true);

$room = isset($_GET['room']) ? trim((string)$_GET['room']) : 'geral';
$last_id = 0;

// SSE pode enviar Last-Event-ID
if (!empty($_SERVER['HTTP_LAST_EVENT_ID'])) {
  $last_id = (int)$_SERVER['HTTP_LAST_EVENT_ID'];
} elseif (isset($_GET['last_id'])) {
  $last_id = (int)$_GET['last_id'];
}

$conn = chat_pg();

// acha room_id
$res = pg_query_params($conn, "SELECT id FROM ia.chat_rooms WHERE slug=$1 LIMIT 1", [$room]);
if (!$res || pg_num_rows($res) < 1) {
  header("Content-Type: text/event-stream; charset=utf-8");
  echo "event: error\n";
  echo "data: room_not_found\n\n";
  @ob_flush(); @flush();
  exit;
}
$room_id = (int)pg_fetch_result($res, 0, 0);

function online_count(PgSql\Connection $conn, int $room_id): int {
  // janela simples: online = quem deu presença nos últimos 45s
  $q = pg_query_params(
    $conn,
    "SELECT count(*)::int AS c
     FROM ia.chat_presence
     WHERE room_id=$1
       AND last_seen_at > (now() - interval '45 seconds')",
    [$room_id]
  );
  if (!$q || pg_num_rows($q) < 1) return 0;
  return (int)pg_fetch_result($q, 0, 0);
}

// headers SSE
header("Content-Type: text/event-stream; charset=utf-8");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
header("X-Accel-Buffering: no"); // nginx
header("Connection: keep-alive");

// ping inicial com contador (pra topo já mostrar rápido)
$oc0 = online_count($conn, $room_id);
echo "event: ping\n";
echo "data: ".json_encode(['online'=>$oc0], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)."\n\n";
@ob_flush(); @flush();

// envia backlog (se last_id informado)
if ($last_id > 0) {
  $q = pg_query_params(
    $conn,
    "SELECT id, uid, sender_name, sender_email, sender_photo_url, body, created_at
     FROM ia.chat_messages
     WHERE room_id=$1 AND id > $2
     ORDER BY id ASC
     LIMIT 200",
    [$room_id, $last_id]
  );
  if ($q) {
    while ($row = pg_fetch_assoc($q)) {
      $msg = [
        'id' => (int)$row['id'],
        'uid' => (string)$row['uid'],
        'name' => (string)($row['sender_name'] ?? ''),
        'email' => (string)($row['sender_email'] ?? ''),
        'photo_url' => (string)($row['sender_photo_url'] ?? ''),
        'body' => (string)$row['body'],
        'created_at' => (string)$row['created_at'],
      ];
      echo "id: ".$msg['id']."\n";
      echo "event: message\n";
      echo "data: ".json_encode($msg, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)."\n\n";
    }
    @ob_flush(); @flush();
  }
}

// LISTEN realtime
pg_query($conn, "LISTEN chat_messages");

$sock = pg_socket($conn);
$last_ping = time();

while (true) {
  if (connection_aborted()) break;

  $r = [$sock];
  $w = null;
  $e = null;

  // bloqueia até 15s (sem polling)
  $n = @stream_select($r, $w, $e, 15);

  // ping keepalive a cada ~20s + contador online
  if (time() - $last_ping >= 20) {
    $oc = online_count($conn, $room_id);
    echo "event: ping\n";
    echo "data: ".json_encode(['online'=>$oc], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)."\n\n";
    @ob_flush(); @flush();
    $last_ping = time();
  }

  if ($n === false || $n === 0) {
    continue;
  }

  // processa NOTIFY
  pg_consume_input($conn);
  while ($notify = pg_get_notify($conn, PGSQL_ASSOC)) {
    // payload "room_id:id"
    $payload = (string)($notify['payload'] ?? '');
    $parts = explode(':', $payload, 2);
    if (count($parts) !== 2) continue;
    $rid = (int)$parts[0];
    $mid = (int)$parts[1];
    if ($rid !== $room_id) continue;

    $q = pg_query_params(
      $conn,
      "SELECT id, uid, sender_name, sender_email, sender_photo_url, body, created_at
       FROM ia.chat_messages
       WHERE room_id=$1 AND id=$2
       LIMIT 1",
      [$room_id, $mid]
    );
    if (!$q || pg_num_rows($q) < 1) continue;

    $row = pg_fetch_assoc($q);
    $msg = [
      'id' => (int)$row['id'],
      'uid' => (string)$row['uid'],
      'name' => (string)($row['sender_name'] ?? ''),
      'email' => (string)($row['sender_email'] ?? ''),
      'photo_url' => (string)($row['sender_photo_url'] ?? ''),
      'body' => (string)$row['body'],
      'created_at' => (string)$row['created_at'],
    ];

    echo "id: ".$msg['id']."\n";
    echo "event: message\n";
    echo "data: ".json_encode($msg, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)."\n\n";
    @ob_flush(); @flush();
  }
}
