package dev.lions.unionflow.server.service; import dev.lions.unionflow.server.entity.Membre; import dev.lions.unionflow.server.entity.MembreSuivi; import dev.lions.unionflow.server.repository.MembreRepository; import dev.lions.unionflow.server.repository.MembreSuiviRepository; 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 la gestion du suivi entre membres (Réseau). */ @ApplicationScoped public class MembreSuiviService { private static final Logger LOG = Logger.getLogger(MembreSuiviService.class); @Inject MembreSuiviRepository membreSuiviRepository; @Inject MembreRepository membreRepository; /** * Suit un membre. Si déjà suivi, reste suivi. * * @param currentUserEmail email du membre connecté * @param suiviId id du membre à suivre (utilisateur) * @return true si le membre est suivi après l’appel */ @Transactional public boolean follow(String currentUserEmail, UUID suiviId) { Membre follower = membreRepository.findByEmail(currentUserEmail) .orElseThrow(() -> new IllegalArgumentException("Membre connecté introuvable")); UUID followerId = follower.getId(); if (followerId.equals(suiviId)) { throw new IllegalArgumentException("Impossible de se suivre soi-même"); } if (membreRepository.findByIdOptional(suiviId).isEmpty()) { throw new IllegalArgumentException("Membre cible introuvable"); } if (membreSuiviRepository.findByFollowerAndSuivi(followerId, suiviId).isPresent()) { LOG.infof("Déjà suivi: %s -> %s", followerId, suiviId); return true; } MembreSuivi suivi = MembreSuivi.builder() .followerUtilisateurId(followerId) .suiviUtilisateurId(suiviId) .build(); membreSuiviRepository.persist(suivi); LOG.infof("Suivi ajouté: %s -> %s", followerId, suiviId); return true; } /** * Ne plus suivre un membre. * * @param currentUserEmail email du membre connecté * @param suiviId id du membre à ne plus suivre * @return false (plus suivi) */ @Transactional public boolean unfollow(String currentUserEmail, UUID suiviId) { Membre follower = membreRepository.findByEmail(currentUserEmail) .orElseThrow(() -> new IllegalArgumentException("Membre connecté introuvable")); UUID followerId = follower.getId(); membreSuiviRepository.findByFollowerAndSuivi(followerId, suiviId) .ifPresent(membreSuiviRepository::delete); LOG.infof("Suivi supprimé: %s -> %s", followerId, suiviId); return false; } /** * Indique si le membre connecté suit le membre cible. */ public boolean isFollowing(String currentUserEmail, UUID suiviId) { Membre follower = membreRepository.findByEmail(currentUserEmail).orElse(null); if (follower == null) return false; return membreSuiviRepository.findByFollowerAndSuivi(follower.getId(), suiviId).isPresent(); } /** * Liste des ids des membres suivis par l’utilisateur connecté. */ public List getFollowedIds(String currentUserEmail) { Membre follower = membreRepository.findByEmail(currentUserEmail).orElse(null); if (follower == null) return List.of(); return membreSuiviRepository.findByFollower(follower.getId()).stream() .map(MembreSuivi::getSuiviUtilisateurId) .collect(Collectors.toList()); } }