<?php
declare(strict_types=1);

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

function respond(int $status, array $payload): void {
  http_response_code($status);
  echo json_encode($payload, JSON_UNESCAPED_SLASHES);
  exit;
}
function cookieNames(): array { return array_values(array_keys($_COOKIE ?? [])); }
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';

/** ---------- Role helpers (adjust strings to match your DB) ---------- */
function roleIs(array $user, array $roles): bool {
  $r = strtolower((string)($user['role'] ?? ''));
  foreach ($roles as $x) if ($r === strtolower($x)) return true;
  return false;
}
function isSuperAdmin(array $u): bool { return roleIs($u, ['super_admin','superadmin']); }
function isNational(array $u): bool { return roleIs($u, ['national','national_leader']); }
function isCounty(array $u): bool { return roleIs($u, ['county','county_rep']); }
function isConstituency(array $u): bool { return roleIs($u, ['constituency','constituency_rep']); }
function isWard(array $u): bool { return roleIs($u, ['ward','ward_rep']); }

function isMember(PDO $db, int $roomId, int $userId): bool {
  $st = $db->prepare("SELECT 1 FROM pth_party_room_members WHERE room_id=:rid AND user_id=:uid LIMIT 1");
  $st->execute([':rid'=>$roomId, ':uid'=>$userId]);
  return (bool)$st->fetchColumn();
}

function canAccessScopeRoom(array $user, array $room): bool {
  if (isSuperAdmin($user)) return true;
  if (isNational($user)) return true;

  $scope = (string)($room['scope_level'] ?? '');

  // POLICY: allow everyone to read national rooms (recommended for operations).
  // Change to `return false;` if you want leadership-only.
  if ($scope === 'national') return true;

  $uCounty = (int)($user['county_id'] ?? 0);
  $uConst  = (int)($user['constituency_id'] ?? 0);
  $uWard   = (int)($user['ward_id'] ?? 0);
  $uPs     = (int)($user['polling_station_id'] ?? 0);

  $rCounty = (int)($room['county_id'] ?? 0);
  $rConst  = (int)($room['constituency_id'] ?? 0);
  $rWard   = (int)($room['ward_id'] ?? 0);
  $rPs     = (int)($room['polling_station_id'] ?? 0);

  if ($scope === 'county') return $uCounty > 0 && $uCounty === $rCounty;

  if ($scope === 'constituency') {
    if (isCounty($user)) return $uCounty > 0 && $uCounty === $rCounty;
    return $uConst > 0 && $uConst === $rConst;
  }

  if ($scope === 'ward') {
    if (isCounty($user)) return $uCounty > 0 && $uCounty === $rCounty;
    if (isConstituency($user)) return $uConst > 0 && $uConst === $rConst;
    return $uWard > 0 && $uWard === $rWard;
  }

  if ($scope === 'polling_station') {
    if (isCounty($user)) return $uCounty > 0 && $uCounty === $rCounty;
    if (isConstituency($user)) return $uConst > 0 && $uConst === $rConst;
    if (isWard($user)) return $uWard > 0 && $uWard === $rWard;
    return $uPs > 0 && $uPs === $rPs;
  }

  return false;
}

/** ---------- Session ---------- */
$sessionName = pickSessionName();
if (!$sessionName) {
  respond(401, [
    'error' => 'Not authenticated (no valid session cookie)',
    'cookie_names' => cookieNames(),
  ]);
}
session_name($sessionName);
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']);

/** ---------- Input ---------- */
$roomIdRaw = trim((string)($_GET['roomId'] ?? ''));
if ($roomIdRaw === '' || !ctype_digit($roomIdRaw)) {
  respond(400, ['error' => 'roomId is required and must be a number']);
}
$roomId = (int)$roomIdRaw;

$limitRaw = trim((string)($_GET['limit'] ?? '50'));
$limit = (ctype_digit($limitRaw) ? (int)$limitRaw : 50);
if ($limit < 1) $limit = 1;
if ($limit > 200) $limit = 200;

$beforeIdRaw = trim((string)($_GET['beforeId'] ?? ''));
$beforeId = ($beforeIdRaw !== '' && ctype_digit($beforeIdRaw)) ? (int)$beforeIdRaw : 0;

/** ---------- Load room ---------- */
$roomStmt = $db->prepare("
  SELECT id, room_type, room_key, room_name, scope_level,
         county_id, constituency_id, ward_id, polling_station_id, party_id
  FROM pth_party_room
  WHERE id = :rid
  LIMIT 1
");
$roomStmt->execute([':rid'=>$roomId]);
$room = $roomStmt->fetch(PDO::FETCH_ASSOC);
if (!$room) respond(404, ['error' => 'Room not found']);

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

/** ---------- Authorization ---------- */
$roomType = (string)($room['room_type'] ?? '');
$scopeLevel = (string)($room['scope_level'] ?? '');

$allowed = false;
if ($roomType === 'dm' || $scopeLevel === 'custom') {
  $allowed = isMember($db, $roomId, $userId);
} else {
  $allowed = canAccessScopeRoom($user, $room);
}
if (!$allowed) respond(403, ['error' => 'Not allowed']);

/** ---------- Build download base URL ---------- */
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$basePath = rtrim(str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? '/')), '/');
$downloadBase = $scheme . '://' . $host . $basePath . '/download-attachment.php';

/** ---------- Fetch messages (paginated) ---------- */
$where = "m.room_id = :rid";
$params = [':rid' => $roomId];

if ($beforeId > 0) {
  $where .= " AND m.id < :beforeId";
  $params[':beforeId'] = $beforeId;
}

/**
 * We fetch newest first for pagination, then reverse in PHP so UI shows oldest->newest.
 * Attachments: if you allow multiple per message, return attachments[].
 */
$sql = "
  SELECT
    m.id,
    m.room_id AS roomId,
    m.user_id AS senderId,
    COALESCE(m.sender_name, u.name) AS senderName,
    m.body,
    m.created_at AS createdAt,

    a.id AS attachmentId,
    a.file_name AS attachmentFileName,
    a.mime_type AS attachmentMimeType,
    a.file_size AS attachmentFileSize
  FROM pth_party_messages m
  LEFT JOIN users u ON u.id = m.user_id
  LEFT JOIN pth_party_message_attachments a
    ON a.message_id = m.id
   AND (a.is_deleted = 0 OR a.is_deleted IS NULL)
  WHERE $where
  ORDER BY m.id DESC
  LIMIT $limit
";

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

/** ---------- Collapse by message id ---------- */
$byId = [];

foreach ($rows as $r) {
  $mid = (string)$r['id'];

  if (!isset($byId[$mid])) {
    $byId[$mid] = [
      'id'         => $mid,
      'roomId'     => (string)$r['roomId'],
      'senderId'   => (string)($r['senderId'] ?? ''),
      'senderName' => $r['senderName'] ?? null,
      'body'       => $r['body'],
      'createdAt'  => $r['createdAt'],
      'attachment' => null,
      // If you want multi: 'attachments' => []
    ];
  }

  if (!empty($r['attachmentId'])) {
    $aid = (string)$r['attachmentId'];
    $byId[$mid]['attachment'] = [
      'id' => $aid,
      'fileName' => (string)$r['attachmentFileName'],
      'mimeType' => (string)$r['attachmentMimeType'],
      'fileSize' => (int)$r['attachmentFileSize'],
      'downloadUrl' => $downloadBase . '?id=' . rawurlencode($aid),
    ];
  }
}

/** Reverse back to ascending time (oldest to newest) */
$messages = array_values($byId);
$messages = array_reverse($messages);

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