false, 'ERROR' => 'missing_params', 'MESSAGE' => 'TaskID is required']); } try { if ($afterMessageID > 0) { $qMessages = queryTimed(" SELECT m.ID, m.TaskID, m.SenderUserID, m.SenderType, m.MessageBody, m.IsRead, m.CreatedOn, u.FirstName as SenderName FROM ChatMessages m LEFT JOIN Users u ON u.ID = m.SenderUserID WHERE m.TaskID = ? AND m.ID > ? ORDER BY m.CreatedOn ASC ", [$taskID, $afterMessageID]); } else { $qMessages = queryTimed(" SELECT m.ID, m.TaskID, m.SenderUserID, m.SenderType, m.MessageBody, m.IsRead, m.CreatedOn, u.FirstName as SenderName FROM ChatMessages m LEFT JOIN Users u ON u.ID = m.SenderUserID WHERE m.TaskID = ? ORDER BY m.CreatedOn ASC ", [$taskID]); } $messages = []; foreach ($qMessages as $msg) { $senderName = !empty(trim($msg['SenderName'] ?? '')) ? $msg['SenderName'] : ($msg['SenderType'] === 'customer' ? 'Customer' : 'Staff'); $messages[] = [ 'MessageID' => (int) $msg['ID'], 'TaskID' => (int) $msg['TaskID'], 'SenderUserID' => (int) $msg['SenderUserID'], 'SenderType' => $msg['SenderType'], 'SenderName' => $senderName, 'Text' => $msg['MessageBody'], 'IsRead' => ((int) $msg['IsRead']) === 1, 'CreatedOn' => toISO8601($msg['CreatedOn']), ]; } // Check if chat/task is closed $qTask = queryOne("SELECT CompletedOn FROM Tasks WHERE ID = ?", [$taskID]); $chatClosed = ($qTask && !empty(trim($qTask['CompletedOn'] ?? ''))); jsonResponse([ 'OK' => true, 'MESSAGES' => $messages, 'COUNT' => count($messages), 'CHAT_CLOSED' => $chatClosed, ]); } catch (Exception $e) { jsonResponse(['OK' => false, 'ERROR' => 'server_error', 'MESSAGE' => $e->getMessage()]); }