<?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 'PHPSESSID';
}

function getUserId(): int {
  $uid = (int)($_SESSION['user_id'] ?? 0);
  if ($uid <= 0) $uid = (int)($_SESSION['SESS_MEMBER_ID'] ?? 0);
  return $uid;
}

function canAccessConversation(array $conv, int $userId): bool {
  $cid = (string)($conv['id'] ?? '');
  $vid = (int)($conv['visitor_id'] ?? 0);
  $agentId = (int)($conv['agent_id'] ?? 0);

  // visitor
  if ($userId > 0 && $vid > 0 && $userId === $vid) return true;

  // session-based access (anonymous)
  if (!empty($_SESSION['support_conversations']) && is_array($_SESSION['support_conversations'])) {
    if (!empty($_SESSION['support_conversations'][$cid])) return true;
  }

  // staff agent
  if ($userId > 0 && $agentId > 0 && $userId === $agentId) return true;

  // optionally allow any logged-in staff (admin session) to view
  if (!empty($_COOKIE['PHPSESSADM']) && $userId > 0) return true;

  return false;
}

require_once __DIR__ . '/../conn.php';

session_name(pickSessionName());
session_start();
$userId = getUserId();

$conversationId = (string)($_GET['conversationId'] ?? '');
if ($conversationId === '' || !ctype_digit($conversationId)) {
  respond(400, ['error' => 'conversationId is required']);
}
$limit = (int)($_GET['limit'] ?? 50);
if ($limit < 1) $limit = 50;
if ($limit > 200) $limit = 200;

$beforeId = (string)($_GET['beforeId'] ?? '');
$beforeClause = '';
$params = [':cid' => (int)$conversationId, ':lim' => $limit];
if ($beforeId !== '' && ctype_digit($beforeId)) {
  $beforeClause = 'AND id < :beforeId';
  $params[':beforeId'] = (int)$beforeId;
}

try {
  $convStmt = $db->prepare("SELECT * FROM pth_support_conversations WHERE id = :cid LIMIT 1");
  $convStmt->execute([':cid' => (int)$conversationId]);
  $conv = $convStmt->fetch(PDO::FETCH_ASSOC);

  if (!$conv) respond(404, ['error' => 'Conversation not found']);
  if (!canAccessConversation($conv, $userId)) respond(403, ['error' => 'Not allowed']);

  $msgStmt = $db->prepare("
    SELECT
      id,
      conversation_id AS conversationId,
      sender_type AS senderType,
      sender_id AS senderId,
      sender_name AS senderName,
      body,
      created_at AS createdAt
    FROM pth_support_messages
    WHERE conversation_id = :cid
      $beforeClause
    ORDER BY id DESC
    LIMIT :lim
  ");

  // PDO needs bindValue for LIMIT
  $msgStmt->bindValue(':cid', (int)$conversationId, PDO::PARAM_INT);
  if (isset($params[':beforeId'])) $msgStmt->bindValue(':beforeId', (int)$params[':beforeId'], PDO::PARAM_INT);
  $msgStmt->bindValue(':lim', $limit, PDO::PARAM_INT);

  $msgStmt->execute();
  $rows = $msgStmt->fetchAll(PDO::FETCH_ASSOC);

  // return in chronological order
  $rows = array_reverse($rows);

  respond(200, [
    'ok' => true,
    'conversation' => [
      'id' => (string)$conv['id'],
      'state' => $conv['state'],
      'agentId' => $conv['agent_id'] ? (string)$conv['agent_id'] : null,
      'agentName' => $conv['agent_name'] ?? null,
      'visitorId' => $conv['visitor_id'] ? (string)$conv['visitor_id'] : null,
    ],
    'messages' => array_map(fn($r) => [
      'id' => (string)$r['id'],
      'conversationId' => (string)$r['conversationId'],
      'senderType' => $r['senderType'],
      'senderId' => $r['senderId'] ? (string)$r['senderId'] : null,
      'senderName' => $r['senderName'],
      'body' => $r['body'],
      'createdAt' => $r['createdAt'],
    ], $rows),
  ]);

} catch (Throwable $e) {
  respond(500, ['error' => 'Failed to load messages', 'message' => $e->getMessage()]);
}
