<?php
declare(strict_types=1);

require_once __DIR__ . '/_cors.php';

/** Helpers */
function fail(int $code, string $msg, array $extra = []): void {
  http_response_code($code);
  header('Content-Type: application/json; charset=utf-8');
  echo json_encode(array_merge(['error' => $msg], $extra), 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;
}

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 access national rooms (recommended for ops)
  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;
}

/** DB */
$connPath = __DIR__ . '/conn.php';
if (!file_exists($connPath)) fail(500, 'conn.php not found');
require_once $connPath; // expects $db (PDO)

/** Session */
$sessionName = pickSessionName();
if (!$sessionName) fail(401, 'Not authenticated (no valid session cookie)');
session_name($sessionName);
session_start();

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

/** Input */
$idRaw = trim((string)($_GET['id'] ?? ''));
if ($idRaw === '' || !ctype_digit($idRaw)) fail(400, 'id is required and must be numeric');
$attachmentId = (int)$idRaw;

/** Load attachment */
$q = $db->prepare("
  SELECT
    id,
    room_id,
    file_name,
    mime_type,
    file_size,
    storage_path,
    stored_name
  FROM pth_party_message_attachments
  WHERE id = :id
    AND (is_deleted = 0 OR is_deleted IS NULL)
  LIMIT 1
");
$q->execute([':id' => $attachmentId]);
$att = $q->fetch(PDO::FETCH_ASSOC);
if (!$att) fail(404, 'Attachment not found');

$roomId = (int)$att['room_id'];

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

/** Load user context */
$uq = $db->prepare("
  SELECT id, role, county_id, constituency_id, ward_id, polling_station_id
  FROM users
  WHERE id = :uid
  LIMIT 1
");
$uq->execute([':uid'=>$userId]);
$user = $uq->fetch(PDO::FETCH_ASSOC);
if (!$user) fail(401, '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) fail(403, 'Not allowed');

/** Resolve file path
 * RECOMMENDED:
 * - store relative storage_path like "uploads/chat/{roomId}/{storedName}"
 * - map it to disk using your project root
 */
$storagePath = (string)($att['storage_path'] ?? '');
if ($storagePath === '') fail(404, 'File missing on server');

// if storagePath is relative, convert to absolute
if ($storagePath[0] !== '/' && !preg_match('#^[A-Za-z]:\\\\#', $storagePath)) {
  // this file is in /api maybe; adjust root to match your project
  $abs = realpath(__DIR__ . '/../') . '/' . ltrim($storagePath, '/');
  $path = $abs;
} else {
  $path = $storagePath;
}

if ($path === '' || !is_file($path)) fail(404, 'File missing on server');

$mime = (string)($att['mime_type'] ?? '');
$name = (string)($att['file_name'] ?? 'file');
$size = (int)($att['file_size'] ?? filesize($path));

header('Content-Type: ' . ($mime ?: 'application/octet-stream'));
header('Content-Length: ' . $size);

// inline for images/pdf, attachment for others
$inline = false;
if ($mime !== '' && str_starts_with($mime, 'image/')) $inline = true;
if ($mime === 'application/pdf') $inline = true;

$disposition = $inline ? 'inline' : 'attachment';
header('Content-Disposition: ' . $disposition . '; filename="' . addslashes($name) . '"');
header('X-Content-Type-Options: nosniff');

readfile($path);
exit;
