authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $filters = $request->validated(); $page = (int) ($filters['page'] ?? 1); $perPage = (int) ($filters['per_page'] ?? 20); $this->authorize('viewAny', Message::class); $role = $this->queryService->getUserRoleName($guard); $messages = $this->queryService->inbox($guard, $filters, $page, $perPage); $collection = new MessageCollection($messages); $meta = $collection->with($request)['meta'] ?? null; return $this->success([ 'role' => $role, 'messages' => $collection->toArray($request), 'meta' => $meta, ]); } public function inbox(MessageIndexRequest $request): JsonResponse { return $this->listMessages($request, 'inbox'); } public function sent(MessageIndexRequest $request): JsonResponse { return $this->listMessages($request, 'sent'); } public function drafts(MessageIndexRequest $request): JsonResponse { return $this->listMessages($request, 'drafts'); } public function trash(MessageIndexRequest $request): JsonResponse { return $this->listMessages($request, 'trash'); } public function show(int $id): JsonResponse { $message = $this->queryService->findForUser($id); if (! $message) { return $this->error('Message not found.', Response::HTTP_NOT_FOUND); } $this->authorize('view', $message); $userId = (int) (auth()->id() ?? 0); if ($message->recipient_id === $userId) { $this->commandService->markRead($message); $message->refresh(); } return $this->success([ 'message' => new MessageResource($message), ]); } public function store(MessageSendRequest $request): JsonResponse { $guard = $this->authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $this->authorize('create', Message::class); try { $message = $this->commandService->create($guard, $request->validated(), $request->file('attachment')); } catch (\Throwable $e) { Log::error('Message send failed: '.$e->getMessage()); return $this->error($e->getMessage(), Response::HTTP_BAD_REQUEST); } return $this->success([ 'message' => new MessageResource($message->fresh(['sender', 'recipient'])), ], 'Message sent.', Response::HTTP_CREATED); } public function receive(): JsonResponse { $guard = $this->authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $messages = $this->queryService->receivedAndMarkRead($guard); return $this->success([ 'messages' => (new MessageCollection(collect($messages)))->toArray(request()), ]); } public function recipients(string $type): JsonResponse { $type = strtolower(trim($type)); $data = match ($type) { 'teacher' => $this->recipientService->teachers(), 'parent' => $this->recipientService->parents(), default => null, }; if ($data === null) { return $this->error('Invalid recipient type.', Response::HTTP_BAD_REQUEST); } $payload = array_map(fn ($row) => (new RecipientResource($row))->toArray(request()), $data); return $this->success([ 'recipients' => $payload, ]); } public function update(MessageUpdateRequest $request, int $id): JsonResponse { $message = Message::query()->find($id); if (! $message) { return $this->error('Message not found.', Response::HTTP_NOT_FOUND); } $this->authorize('update', $message); try { $updated = $this->commandService->update($message, $request->validated()); } catch (\Throwable $e) { Log::error('Message update failed: '.$e->getMessage()); return $this->error('Unable to update message.', Response::HTTP_INTERNAL_SERVER_ERROR); } return $this->success([ 'message' => new MessageResource($updated->load(['sender', 'recipient'])), ], 'Message updated.'); } public function destroy(int $id): JsonResponse { $message = Message::query()->find($id); if (! $message) { return $this->error('Message not found.', Response::HTTP_NOT_FOUND); } $this->authorize('delete', $message); try { $trashed = $this->commandService->trash($message); } catch (\Throwable $e) { Log::error('Message delete failed: '.$e->getMessage()); return $this->error('Unable to delete message.', Response::HTTP_INTERNAL_SERVER_ERROR); } if (! $trashed) { return $this->error('Unable to delete message.', Response::HTTP_INTERNAL_SERVER_ERROR); } return $this->success(null, 'Message deleted.'); } private function listMessages(MessageIndexRequest $request, string $bucket): JsonResponse { $guard = $this->authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $filters = $request->validated(); $page = (int) ($filters['page'] ?? 1); $perPage = (int) ($filters['per_page'] ?? 20); $this->authorize('viewAny', Message::class); $paginator = match ($bucket) { 'sent' => $this->queryService->sent($guard, $filters, $page, $perPage), 'drafts' => $this->queryService->drafts($guard, $filters, $page, $perPage), 'trash' => $this->queryService->trash($guard, $filters, $page, $perPage), default => $this->queryService->inbox($guard, $filters, $page, $perPage), }; $collection = new MessageCollection($paginator); $meta = $collection->with($request)['meta'] ?? null; return $this->success([ 'messages' => $collection->toArray($request), 'meta' => $meta, ]); } private function authenticatedUserIdOrUnauthorized(): int|JsonResponse { $userId = (int) (auth()->id() ?? 0); if ($userId <= 0) { return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED); } return $userId; } }