<?php
declare(strict_types=1);

require_once __DIR__ . '/_cors.php';
header('Content-Type: application/json; charset=utf-8');

function respond(int $s, array $p): void {
  http_response_code($s);
  echo json_encode($p, JSON_UNESCAPED_SLASHES);
  exit;
}
function pickSessionName(): ?string {
  if (!empty($_COOKIE['PHPSESSADM'])) return 'PHPSESSADM';
  if (!empty($_COOKIE['PHPSESSCLI'])) return 'PHPSESSCLI';
  if (!empty($_COOKIE['PHPSESSAFF'])) return 'PHPSESSAFF';
  return null;
}

require_once __DIR__ . '/conn.php';

$sn = pickSessionName();
if (!$sn) respond(401, ['error'=>'Not authenticated']);
session_name($sn);
session_start();

$userId = (int)($_SESSION['user_id'] ?? 0);
if ($userId <= 0) $userId = (int)($_SESSION['SESS_MEMBER_ID'] ?? 0);
if ($userId <= 0) respond(401, ['error'=>'Not authenticated']);

// optional: since=messageId to only return rooms updated after that messageId
$sinceRaw = trim((string)($_GET['since'] ?? '0'));
$since = ctype_digit($sinceRaw) ? (int)$sinceRaw : 0;

/** Load user geo context */
$uStmt = $db->prepare("
  SELECT id, role, county_id, constituency_id, ward_id, polling_station_id
  FROM users
  WHERE id = :uid
  LIMIT 1
");
$uStmt->execute([':uid'=>$userId]);
$user = $uStmt->fetch(PDO::FETCH_ASSOC);
if (!$user) respond(401, ['error'=>'User not found']);

$countyId = (int)($user['county_id'] ?? 0);
$constId  = (int)($user['constituency_id'] ?? 0);
$wardId   = (int)($user['ward_id'] ?? 0);
$psId     = (int)($user['polling_station_id'] ?? 0);

/**
 * Build room list:
 *  A) membership rooms: dm + custom (and any explicit groups you use members for)
 *  B) scope rooms: polling_station/ward/constituency/county/national that match the user
 *
 * NOTE: This assumes you actually created those scope rooms in pth_party_room.
 */
$sqlRooms = "
  SELECT DISTINCT r.id AS roomId
  FROM pth_party_room r
  JOIN pth_party_room_members rm ON rm.room_id = r.id
  WHERE rm.user_id = :uid

  UNION DISTINCT

  SELECT r.id AS roomId
  FROM pth_party_room r
  WHERE r.scope_level = 'national'

  UNION DISTINCT

  SELECT r.id AS roomId
  FROM pth_party_room r
  WHERE r.scope_level = 'county' AND r.county_id = :county_id

  UNION DISTINCT

  SELECT r.id AS roomId
  FROM pth_party_room r
  WHERE r.scope_level = 'constituency' AND r.constituency_id = :const_id

  UNION DISTINCT

  SELECT r.id AS roomId
  FROM pth_party_room r
  WHERE r.scope_level = 'ward' AND r.ward_id = :ward_id

  UNION DISTINCT

  SELECT r.id AS roomId
  FROM pth_party_room r
  WHERE r.scope_level = 'polling_station' AND r.polling_station_id = :ps_id
";

$stmtRooms = $db->prepare($sqlRooms);
$stmtRooms->execute([
  ':uid' => $userId,
  ':county_id' => $countyId,
  ':const_id' => $constId,
  ':ward_id' => $wardId,
  ':ps_id' => $psId,
]);

$roomIds = array_map(fn($r) => (int)$r['roomId'], $stmtRooms->fetchAll(PDO::FETCH_ASSOC));
$roomIds = array_values(array_unique(array_filter($roomIds, fn($x) => $x > 0)));

if (!$roomIds) {
  respond(200, ['totalUnread'=>0, 'updates'=>[]]);
}

/**
 * Load state + latest + unread using indexed queries.
 * We do this in one SQL using room_id IN (...) and correlated counts.
 *
 * IMPORTANT: pth_party_messages must have INDEX(room_id, id).
 */
$in = implode(',', array_fill(0, count($roomIds), '?'));

$sql = "
  SELECT
    r.id AS roomId,
    COALESCE(s.is_archived,0) AS isArchived,
    COALESCE(s.last_read_message_id,0) AS lastReadId,

    -- latest message id
    (SELECT MAX(m.id) FROM pth_party_messages m WHERE m.room_id = r.id) AS latestMessageId,

    -- unread count (exclude my own messages)
    (SELECT COUNT(*)
     FROM pth_party_messages m2
     WHERE m2.room_id = r.id
       AND m2.id > COALESCE(s.last_read_message_id,0)
       AND m2.user_id <> ?
       AND (m2.is_deleted = 0 OR m2.is_deleted IS NULL)
    ) AS unreadCount

  FROM pth_party_room r
  LEFT JOIN pth_party_room_user_state s
    ON s.room_id = r.id AND s.user_id = ?

  WHERE r.id IN ($in)
";

$params = [];
$params[] = $userId; // for unread exclude
$params[] = $userId; // for state join
foreach ($roomIds as $rid) $params[] = $rid;

$stmt = $db->prepare($sql);
$stmt->execute($params);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

$totalUnread = 0;
$updates = [];

foreach ($rows as $row) {
  $isArchived = ((int)$row['isArchived']) === 1;
  $unreadCount = (int)($row['unreadCount'] ?? 0);
  $latestId = (int)($row['latestMessageId'] ?? 0);

  if (!$isArchived) $totalUnread += $unreadCount;

  // Report rooms where latest message is newer than "since"
  if ($latestId > $since) {
    $updates[] = [
      'roomId' => (string)$row['roomId'],
      'latestMessageId' => $latestId,
      'unreadCount' => $unreadCount,
      'archived' => $isArchived,
    ];
  }
}

respond(200, [
  'totalUnread' => $totalUnread,
  'updates' => $updates,
]);
