package com.lions.dev.resource; import com.lions.dev.dto.request.establishment.EstablishmentMediaRequestDTO; import com.lions.dev.dto.response.establishment.EstablishmentMediaResponseDTO; import com.lions.dev.entity.establishment.EstablishmentMedia; import com.lions.dev.entity.establishment.MediaType; import com.lions.dev.service.EstablishmentMediaService; import jakarta.inject.Inject; import jakarta.transaction.Transactional; import jakarta.validation.Valid; import jakarta.ws.rs.*; import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.jboss.logging.Logger; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; /** * Ressource REST pour la gestion des médias d'établissements. * Cette classe expose des endpoints pour uploader, récupérer et supprimer des médias. */ @Path("/establishments/{establishmentId}/media") @Produces(jakarta.ws.rs.core.MediaType.APPLICATION_JSON) @Consumes(jakarta.ws.rs.core.MediaType.APPLICATION_JSON) @Tag(name = "Establishment Media", description = "Opérations liées aux médias des établissements") public class EstablishmentMediaResource { @Inject EstablishmentMediaService mediaService; private static final Logger LOG = Logger.getLogger(EstablishmentMediaResource.class); /** * Récupère tous les médias d'un établissement. */ @GET @Operation(summary = "Récupérer tous les médias d'un établissement", description = "Retourne la liste de tous les médias (photos et vidéos) d'un établissement") public Response getEstablishmentMedia(@PathParam("establishmentId") String establishmentId) { LOG.info("Récupération des médias pour l'établissement : " + establishmentId); try { UUID id = UUID.fromString(establishmentId); List medias = mediaService.getMediaByEstablishmentId(id); List responseDTOs = medias.stream() .map(EstablishmentMediaResponseDTO::new) .collect(Collectors.toList()); return Response.ok(responseDTOs).build(); } catch (IllegalArgumentException e) { LOG.error("ID d'établissement invalide : " + establishmentId); return Response.status(Response.Status.BAD_REQUEST) .entity("ID d'établissement invalide") .build(); } catch (Exception e) { LOG.error("Erreur lors de la récupération des médias", e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Erreur lors de la récupération des médias") .build(); } } /** * Upload un nouveau média pour un établissement. * Accepte un body JSON avec les informations du média. */ @POST @Transactional @Operation(summary = "Uploader un média pour un établissement", description = "Upload un nouveau média (photo ou vidéo) pour un établissement") public Response uploadMedia( @PathParam("establishmentId") String establishmentId, @Valid EstablishmentMediaRequestDTO requestDTO, @QueryParam("uploadedByUserId") String uploadedByUserIdStr) { LOG.info("Upload d'un média pour l'établissement : " + establishmentId); try { UUID id = UUID.fromString(establishmentId); // Utiliser uploadedByUserId du query param ou du DTO String userIdStr = uploadedByUserIdStr != null && !uploadedByUserIdStr.isEmpty() ? uploadedByUserIdStr : requestDTO.getUploadedByUserId(); if (userIdStr == null || userIdStr.isEmpty()) { LOG.error("uploadedByUserId est obligatoire"); return Response.status(Response.Status.BAD_REQUEST) .entity("L'ID de l'utilisateur (uploadedByUserId) est obligatoire") .build(); } UUID uploadedByUserId = UUID.fromString(userIdStr); // Valider le type de média MediaType mediaType; try { mediaType = MediaType.valueOf(requestDTO.getMediaType().toUpperCase()); } catch (IllegalArgumentException e) { return Response.status(Response.Status.BAD_REQUEST) .entity("Type de média invalide. Utilisez PHOTO ou VIDEO") .build(); } // Appeler le service avec displayOrder EstablishmentMedia media = mediaService.uploadMedia( id, requestDTO.getMediaUrl(), mediaType, uploadedByUserId, requestDTO.getThumbnailUrl(), requestDTO.getDisplayOrder() != null ? requestDTO.getDisplayOrder() : 0 ); EstablishmentMediaResponseDTO responseDTO = new EstablishmentMediaResponseDTO(media); return Response.status(Response.Status.CREATED).entity(responseDTO).build(); } catch (IllegalArgumentException e) { LOG.error("Paramètres invalides : " + e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST) .entity("Paramètres invalides : " + e.getMessage()) .build(); } catch (RuntimeException e) { LOG.error("Erreur lors de l'upload du média : " + e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST) .entity(e.getMessage()) .build(); } catch (Exception e) { LOG.error("Erreur inattendue lors de l'upload du média", e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Erreur lors de l'upload du média") .build(); } } /** * Supprime un média d'un établissement. */ @DELETE @Path("/{mediaId}") @Transactional @Operation(summary = "Supprimer un média d'un établissement", description = "Supprime un média spécifique d'un établissement") public Response deleteMedia( @PathParam("establishmentId") String establishmentId, @PathParam("mediaId") String mediaId) { LOG.info("Suppression du média " + mediaId + " de l'établissement " + establishmentId); try { UUID establishmentUuid = UUID.fromString(establishmentId); UUID mediaUuid = UUID.fromString(mediaId); mediaService.deleteMedia(establishmentUuid, mediaUuid); return Response.status(Response.Status.NO_CONTENT).build(); } catch (IllegalArgumentException e) { LOG.error("ID invalide : " + e.getMessage()); return Response.status(Response.Status.BAD_REQUEST) .entity("ID invalide") .build(); } catch (RuntimeException e) { LOG.error("Erreur lors de la suppression du média : " + e.getMessage()); return Response.status(Response.Status.BAD_REQUEST) .entity(e.getMessage()) .build(); } catch (Exception e) { LOG.error("Erreur inattendue lors de la suppression du média", e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Erreur lors de la suppression du média") .build(); } } }