false,'error'=>'Not authenticated']); exit; } $action = $_GET['action'] ?? ''; $userId = $_SESSION['user_id']; $isAdmin = !empty($_SESSION['is_admin']); switch ($action) { // ── User: get own messages ───────────────────────────── case 'messages': $since = (int)($_GET['since'] ?? 0); // last message id for polling $stmt = db()->prepare(" SELECT id, sender, message, is_read, created_at FROM chat_messages WHERE user_id = ? AND id > ? ORDER BY id ASC LIMIT 100 "); $stmt->execute([$userId, $since]); $msgs = $stmt->fetchAll(); // Mark admin messages as read db()->prepare("UPDATE chat_messages SET is_read=1 WHERE user_id=? AND sender='admin' AND is_read=0")->execute([$userId]); echo json_encode(['success'=>true, 'messages'=>$msgs]); break; // ── User: send message to admin ─────────────────────── case 'send': if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false]); exit; } $data = json_decode(file_get_contents('php://input'), true); $msg = trim($data['message'] ?? ''); if (empty($msg) || mb_strlen($msg) > 2000) { echo json_encode(['success'=>false,'error'=>'Invalid message']); exit; } $stmt = db()->prepare("INSERT INTO chat_messages (user_id, sender, message) VALUES (?, 'user', ?)"); $stmt->execute([$userId, $msg]); echo json_encode(['success'=>true, 'id'=>db()->lastInsertId()]); break; // ── Admin: get inbox list (one row per user, latest msg) ── case 'admin_inbox': if (!$isAdmin) { echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; } $rows = db()->query(" SELECT u.id AS user_id, u.username, u.alias, cm.message AS last_message, cm.sender AS last_sender, cm.created_at AS last_time, SUM(CASE WHEN cm2.sender='user' AND cm2.is_read=0 THEN 1 ELSE 0 END) AS unread_count FROM users u JOIN chat_messages cm ON cm.id = ( SELECT id FROM chat_messages WHERE user_id = u.id ORDER BY id DESC LIMIT 1 ) LEFT JOIN chat_messages cm2 ON cm2.user_id = u.id GROUP BY u.id, u.username, u.alias, cm.message, cm.sender, cm.created_at ORDER BY cm.created_at DESC ")->fetchAll(); echo json_encode(['success'=>true, 'inbox'=>$rows]); break; // ── Admin: get all messages for a specific user ──────── case 'admin_thread': if (!$isAdmin) { echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; } $tid = (int)($_GET['user_id'] ?? 0); $since = (int)($_GET['since'] ?? 0); if (!$tid) { echo json_encode(['success'=>false,'error'=>'user_id required']); exit; } $stmt = db()->prepare(" SELECT id, sender, message, is_read, created_at FROM chat_messages WHERE user_id = ? AND id > ? ORDER BY id ASC LIMIT 200 "); $stmt->execute([$tid, $since]); $msgs = $stmt->fetchAll(); // Mark user messages as read db()->prepare("UPDATE chat_messages SET is_read=1 WHERE user_id=? AND sender='user' AND is_read=0")->execute([$tid]); // Get user info $uStmt = db()->prepare("SELECT id, username, alias, tokens FROM users WHERE id=?"); $uStmt->execute([$tid]); $user = $uStmt->fetch(); echo json_encode(['success'=>true, 'messages'=>$msgs, 'user'=>$user]); break; // ── Admin: reply to a user ──────────────────────────── case 'admin_send': if (!$isAdmin) { echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; } if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false]); exit; } $data = json_decode(file_get_contents('php://input'), true); $tid = (int)($data['user_id'] ?? 0); $msg = trim($data['message'] ?? ''); if (!$tid || empty($msg) || mb_strlen($msg) > 2000) { echo json_encode(['success'=>false,'error'=>'Invalid']); exit; } $stmt = db()->prepare("INSERT INTO chat_messages (user_id, sender, message) VALUES (?, 'admin', ?)"); $stmt->execute([$tid, $msg]); echo json_encode(['success'=>true, 'id'=>db()->lastInsertId()]); break; // ── Unread count (for badge) ────────────────────────── case 'unread': if ($isAdmin) { $count = db()->query("SELECT COUNT(*) FROM chat_messages WHERE sender='user' AND is_read=0")->fetchColumn(); } else { $stmt = db()->prepare("SELECT COUNT(*) FROM chat_messages WHERE user_id=? AND sender='admin' AND is_read=0"); $stmt->execute([$userId]); $count = $stmt->fetchColumn(); } echo json_encode(['success'=>true, 'count'=>(int)$count]); break; default: echo json_encode(['success'=>false,'error'=>'Unknown action']); }