package com.lions.dev.resource; import com.lions.dev.dto.response.notifications.NotificationResponseDTO; import com.lions.dev.entity.notification.Notification; import com.lions.dev.service.NotificationService; import jakarta.inject.Inject; import jakarta.transaction.Transactional; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.jboss.logging.Logger; /** * Ressource REST pour la gestion des notifications dans le système AfterWork. * * Cette classe expose des endpoints pour créer, récupérer, mettre à jour * et supprimer des notifications. * * Tous les logs nécessaires pour la traçabilité sont intégrés. */ @Path("/notifications") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Tag(name = "Notifications", description = "Opérations liées à la gestion des notifications") public class NotificationResource { @Inject NotificationService notificationService; private static final Logger LOG = Logger.getLogger(NotificationResource.class); /** * Récupère toutes les notifications d'un utilisateur. * * @param userId L'ID de l'utilisateur * @return Liste des notifications de l'utilisateur */ @GET @Path("/user/{userId}") @Operation( summary = "Récupérer les notifications d'un utilisateur", description = "Retourne la liste de toutes les notifications d'un utilisateur, triées par date de création décroissante") public Response getNotificationsByUserId(@PathParam("userId") UUID userId) { LOG.info("[LOG] Récupération des notifications pour l'utilisateur ID : " + userId); try { List notifications = notificationService.getNotificationsByUserId(userId); List responseDTOs = notifications.stream() .map(NotificationResponseDTO::new) .collect(Collectors.toList()); LOG.info("[LOG] " + responseDTOs.size() + " notification(s) récupérée(s) pour l'utilisateur ID : " + userId); return Response.ok(responseDTOs).build(); } catch (Exception e) { LOG.error("[ERROR] Erreur lors de la récupération des notifications : " + e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"message\": \"Erreur lors de la récupération des notifications.\"}") .build(); } } /** * Récupère les notifications d'un utilisateur avec pagination. * * @param userId L'ID de l'utilisateur * @param page Le numéro de la page (0-indexé) * @param size La taille de la page * @return Liste paginée des notifications */ @GET @Path("/user/{userId}/paginated") @Operation( summary = "Récupérer les notifications d'un utilisateur avec pagination", description = "Retourne une liste paginée des notifications d'un utilisateur") public Response getNotificationsByUserIdWithPagination( @PathParam("userId") UUID userId, @QueryParam("page") @DefaultValue("0") int page, @QueryParam("size") @DefaultValue("10") int size) { LOG.info("[LOG] Récupération paginée des notifications pour l'utilisateur ID : " + userId); try { List notifications = notificationService.getNotificationsByUserIdWithPagination(userId, page, size); List responseDTOs = notifications.stream() .map(NotificationResponseDTO::new) .collect(Collectors.toList()); return Response.ok(responseDTOs).build(); } catch (Exception e) { LOG.error("[ERROR] Erreur lors de la récupération paginée des notifications : " + e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"message\": \"Erreur lors de la récupération des notifications.\"}") .build(); } } /** * Marque une notification comme lue. * * @param notificationId L'ID de la notification * @return La notification mise à jour */ @PUT @Path("/{id}/read") @Transactional @Operation( summary = "Marquer une notification comme lue", description = "Marque une notification spécifique comme lue") public Response markAsRead(@PathParam("id") UUID notificationId) { LOG.info("[LOG] Marquage de la notification ID : " + notificationId + " comme lue"); try { Notification notification = notificationService.markAsRead(notificationId); NotificationResponseDTO responseDTO = new NotificationResponseDTO(notification); return Response.ok(responseDTO).build(); } catch (IllegalArgumentException e) { LOG.warn("[WARN] Notification non trouvée : " + e.getMessage()); return Response.status(Response.Status.NOT_FOUND) .entity("{\"message\": \"Notification non trouvée.\"}") .build(); } catch (Exception e) { LOG.error("[ERROR] Erreur lors du marquage de la notification : " + e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"message\": \"Erreur lors du marquage de la notification.\"}") .build(); } } /** * Marque toutes les notifications d'un utilisateur comme lues. * * @param userId L'ID de l'utilisateur * @return Nombre de notifications mises à jour */ @PUT @Path("/user/{userId}/mark-all-read") @Transactional @Operation( summary = "Marquer toutes les notifications comme lues", description = "Marque toutes les notifications d'un utilisateur comme lues") public Response markAllAsRead(@PathParam("userId") UUID userId) { LOG.info("[LOG] Marquage de toutes les notifications comme lues pour l'utilisateur ID : " + userId); try { int updated = notificationService.markAllAsRead(userId); return Response.ok("{\"message\": \"" + updated + " notification(s) marquée(s) comme lue(s).\"}").build(); } catch (Exception e) { LOG.error("[ERROR] Erreur lors du marquage de toutes les notifications : " + e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"message\": \"Erreur lors du marquage des notifications.\"}") .build(); } } /** * Supprime une notification. * * @param notificationId L'ID de la notification * @return Réponse de confirmation */ @DELETE @Path("/{id}") @Transactional @Operation( summary = "Supprimer une notification", description = "Supprime une notification spécifique") public Response deleteNotification(@PathParam("id") UUID notificationId) { LOG.info("[LOG] Suppression de la notification ID : " + notificationId); try { boolean deleted = notificationService.deleteNotification(notificationId); if (deleted) { return Response.noContent().build(); } else { return Response.status(Response.Status.NOT_FOUND) .entity("{\"message\": \"Notification non trouvée.\"}") .build(); } } catch (Exception e) { LOG.error("[ERROR] Erreur lors de la suppression de la notification : " + e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"message\": \"Erreur lors de la suppression de la notification.\"}") .build(); } } /** * Récupère une notification par son ID. * * @param notificationId L'ID de la notification * @return La notification trouvée */ @GET @Path("/{id}") @Operation( summary = "Récupérer une notification par ID", description = "Retourne les détails d'une notification spécifique") public Response getNotificationById(@PathParam("id") UUID notificationId) { LOG.info("[LOG] Récupération de la notification ID : " + notificationId); try { Notification notification = notificationService.getNotificationById(notificationId); NotificationResponseDTO responseDTO = new NotificationResponseDTO(notification); return Response.ok(responseDTO).build(); } catch (IllegalArgumentException e) { LOG.warn("[WARN] Notification non trouvée : " + e.getMessage()); return Response.status(Response.Status.NOT_FOUND) .entity("{\"message\": \"Notification non trouvée.\"}") .build(); } catch (Exception e) { LOG.error("[ERROR] Erreur lors de la récupération de la notification : " + e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"message\": \"Erreur lors de la récupération de la notification.\"}") .build(); } } /** * Compte le nombre de notifications non lues d'un utilisateur. * * @param userId L'ID de l'utilisateur * @return Le nombre de notifications non lues */ @GET @Path("/user/{userId}/unread-count") @Operation( summary = "Compter les notifications non lues", description = "Retourne le nombre de notifications non lues d'un utilisateur") public Response getUnreadCount(@PathParam("userId") UUID userId) { LOG.info("[LOG] Comptage des notifications non lues pour l'utilisateur ID : " + userId); try { long count = notificationService.countUnreadNotifications(userId); return Response.ok("{\"count\": " + count + "}").build(); } catch (Exception e) { LOG.error("[ERROR] Erreur lors du comptage des notifications : " + e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"message\": \"Erreur lors du comptage des notifications.\"}") .build(); } } }