package com.lions.dev.service; import com.lions.dev.dto.request.friends.FriendshipCreateOneRequestDTO; import com.lions.dev.dto.request.friends.FriendshipReadFriendDetailsRequestDTO; import com.lions.dev.dto.request.friends.FriendshipReadStatusRequestDTO; import com.lions.dev.dto.response.friends.FriendshipCreateOneResponseDTO; import com.lions.dev.dto.response.friends.FriendshipReadFriendDetailsResponseDTO; import com.lions.dev.dto.response.friends.FriendshipReadStatusResponseDTO; import com.lions.dev.entity.friends.Friendship; import com.lions.dev.entity.friends.FriendshipStatus; import com.lions.dev.entity.users.Users; import com.lions.dev.exception.FriendshipNotFoundException; import com.lions.dev.exception.UserNotFoundException; import com.lions.dev.repository.FriendshipRepository; import com.lions.dev.repository.UsersRepository; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.transaction.Transactional; import org.jboss.logging.Logger; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; /** * Service pour gérer les relations d'amitié. * Contient la logique métier pour envoyer, accepter, rejeter, et supprimer des relations d'amitié. */ @ApplicationScoped public class FriendshipService { @Inject FriendshipRepository friendshipRepository; // Injecte le repository des amitiés @Inject UsersRepository usersRepository; // Injecte le repository des utilisateurs private static final Logger logger = Logger.getLogger(FriendshipService.class); /** * Envoie une demande d'amitié entre deux utilisateurs. * * @param request DTO contenant les informations sur l'utilisateur et l'ami. * @return Le DTO de la relation d'amitié créée. */ @Transactional public FriendshipCreateOneResponseDTO sendFriendRequest(FriendshipCreateOneRequestDTO request) { logger.info("[LOG] Envoi d'une demande d'amitié de l'utilisateur " + request.getUserId() + " à l'utilisateur " + request.getFriendId()); // Récupérer les utilisateurs concernés Users user = usersRepository.findById(request.getUserId()); Users friend = usersRepository.findById(request.getFriendId()); if (user == null || friend == null) { String notFoundId = user == null ? request.getUserId().toString() : request.getFriendId().toString(); logger.error("[ERROR] Utilisateur non trouvé pour l'ID : " + notFoundId); throw new UserNotFoundException("Utilisateur avec l'ID " + notFoundId + " introuvable."); } // Vérifier s'il existe déjà une relation d'amitié Friendship existingFriendship = friendshipRepository.findByUsers(user, friend).orElse(null); if (existingFriendship != null) { logger.error("[ERROR] Relation d'amitié déjà existante entre les utilisateurs."); throw new IllegalArgumentException("Relation d'amitié déjà existante."); } // Créer et persister une nouvelle relation d'amitié Friendship friendship = new Friendship(user, friend, FriendshipStatus.PENDING); friendshipRepository.persist(friendship); logger.info("[LOG] Demande d'amitié envoyée avec succès."); return new FriendshipCreateOneResponseDTO(friendship); } /** * Accepter une demande d'amitié. * * @param friendshipId ID de la demande à accepter. * @return Le DTO de la relation d'amitié acceptée. */ @Transactional public FriendshipCreateOneResponseDTO acceptFriendRequest(UUID friendshipId) { Friendship friendship = friendshipRepository.findById(friendshipId); if (friendship == null) { throw new FriendshipNotFoundException("Demande d'amitié introuvable."); } // Vérifier que la demande n'est pas déjà acceptée if (friendship.getStatus() == FriendshipStatus.ACCEPTED) { logger.error("[ERROR] Demande d'amitié déjà acceptée."); throw new IllegalArgumentException("Demande d'amitié déjà acceptée."); } // Accepter la demande friendship.setStatus(FriendshipStatus.ACCEPTED); friendshipRepository.persist(friendship); logger.info("[LOG] Demande d'amitié acceptée avec succès."); return new FriendshipCreateOneResponseDTO(friendship); } /** * Rejeter une demande d'amitié. * * @param friendshipId ID de la demande à rejeter. */ @Transactional public void rejectFriendRequest(UUID friendshipId) { Friendship friendship = friendshipRepository.findById(friendshipId); if (friendship == null) { throw new FriendshipNotFoundException("Demande d'amitié introuvable."); } friendship.setStatus(FriendshipStatus.REJECTED); friendshipRepository.persist(friendship); logger.info("[LOG] Demande d'amitié rejetée."); } /** * Supprimer une relation d'amitié. * * @param friendshipId ID de la relation à supprimer. */ @Transactional public void removeFriend(UUID friendshipId) { Friendship friendship = friendshipRepository.findById(friendshipId); if (friendship == null) { throw new FriendshipNotFoundException("Relation d'amitié introuvable."); } friendshipRepository.delete(friendship); logger.info("[LOG] Relation d'amitié supprimée."); } /** * Récupère les détails d'un ami spécifique pour un utilisateur donné. * * @param request DTO contenant l'ID de l'utilisateur et de l'ami. * @return Le DTO des détails de l'ami. */ @Transactional public FriendshipReadFriendDetailsResponseDTO getFriendDetails( FriendshipReadFriendDetailsRequestDTO request) { logger.info("[LOG] Tentative de récupération des détails de l'ami avec l'ID : " + request.getFriendId() + " pour l'utilisateur : " + request.getUserId()); // Récupération de l'utilisateur et de l'ami Users user = usersRepository.findById(request.getUserId()); Users friend = usersRepository.findById(request.getFriendId()); if (user == null) { logger.error("[ERROR] Utilisateur introuvable avec l'ID : " + request.getUserId()); throw new UserNotFoundException("Utilisateur introuvable avec l'ID " + request.getUserId()); } if (friend == null) { logger.error("[ERROR] Ami introuvable avec l'ID : " + request.getFriendId()); throw new UserNotFoundException("Ami introuvable avec l'ID " + request.getFriendId()); } // Récupérer la relation d'amitié entre les deux utilisateurs Friendship friendship = friendshipRepository.findByUsers(user, friend).orElse(null); if (friendship == null) { logger.error("[ERROR] Aucune relation d'amitié trouvée entre l'utilisateur et l'ami."); throw new FriendshipNotFoundException("Relation d'amitié introuvable."); } logger.info("[LOG] Détails de l'ami récupérés avec succès pour l'utilisateur : " + user.getId() + ", ami ID : " + friend.getId()); // Création du DTO de réponse à partir des informations de l'ami et de la relation return new FriendshipReadFriendDetailsResponseDTO( user.getId(), // ID de l'utilisateur friend.getId(), // ID de l'ami friend.getNom(), // Nom de l'ami friend.getPrenoms(), friend.getEmail(), // Email de l'ami friendship.getStatus(), // Statut de la relation friendship.getCreatedAt(), // Date de création de la relation friendship.getUpdatedAt() // Date de mise à jour de la relation ); } /** * Récupérer la liste des amis d'un utilisateur. * * @param userId ID de l'utilisateur. * @param page Numéro de la page. * @param size Taille de la page. * @return Liste paginée des relations d'amitié. */ public List listFriends(UUID userId, int page, int size) { Users user = usersRepository.findById(userId); if (user == null) { logger.error("[ERROR] Utilisateur non trouvé."); throw new UserNotFoundException("Utilisateur introuvable."); } // Récupérer les amitiés acceptées List friendships = friendshipRepository.findFriendsByUser(user, page, size); logger.info("[LOG] " + friendships.size() + " amis récupérés."); // Ajouter un log pour chaque amitié récupérée friendships.forEach(friendship -> logger.info("[LOG] Ami : " + friendship.getFriend().getEmail())); return friendships.stream() .map(friendship -> new FriendshipReadFriendDetailsResponseDTO( friendship.getUser().getId(), friendship.getFriend().getId(), friendship.getFriend().getNom(), friendship.getFriend().getPrenoms(), friendship.getFriend().getEmail(), friendship.getStatus(), friendship.getCreatedAt(), friendship.getUpdatedAt() )) .collect(Collectors.toList()); } /** * Récupérer les demandes d'amitié avec un statut spécifique. * * @param request DTO contenant les informations de filtrage (statut). * @return Liste des demandes d'amitié avec le statut spécifié. */ public List listFriendRequestsByStatus(FriendshipReadStatusRequestDTO request) { Users user = usersRepository.findById(request.getUserId()); if (user == null) { logger.error("[ERROR] Utilisateur non trouvé."); throw new UserNotFoundException("Utilisateur introuvable."); } // Récupérer les demandes d'amitié selon le statut List friendships = friendshipRepository.findByUserAndStatus(user, request.getStatus(), request.getPage() - 1, request.getSize()); logger.info("[LOG] " + friendships.size() + " demandes d'amitié récupérées."); return friendships.stream().map(FriendshipReadStatusResponseDTO::new).collect(Collectors.toList()); } }