package dev.lions.repositories; import dev.lions.models.EmailTemplate; import dev.lions.exceptions.RepositoryException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.EntityManager; import jakarta.persistence.NoResultException; import jakarta.persistence.PersistenceContext; import jakarta.persistence.TypedQuery; import jakarta.transaction.Transactional; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.Optional; /** * Repository gérant la persistance des modèles d'emails de l'application. * Cette classe assure le stockage, la récupération et la gestion des templates * d'emails avec support multilingue et versionnement. */ @Slf4j @ApplicationScoped public class EmailTemplateRepository extends BaseRepository { @PersistenceContext private EntityManager entityManager; /** * Recherche un modèle d'email par son nom. * Cette méthode récupère la dernière version active du modèle. * * @param templateName Nom du modèle recherché * @return Modèle trouvé (Optional) */ public Optional findByName(@NotBlank String templateName) { log.debug("Recherche du modèle d'email : {}", templateName); try { TypedQuery query = entityManager.createQuery( "SELECT t FROM EmailTemplate t " + "WHERE t.templateName = :name " + "AND t.active = true " + "ORDER BY t.version DESC", EmailTemplate.class ); query.setParameter("name", templateName); query.setMaxResults(1); return Optional.of(query.getSingleResult()); } catch (NoResultException e) { log.debug("Aucun modèle trouvé pour le nom : {}", templateName); return Optional.empty(); } catch (Exception e) { throw new RepositoryException( "Erreur lors de la recherche du modèle d'email", e); } } /** * Recherche un modèle d'email par son nom et sa locale. * Permet de récupérer des modèles localisés spécifiques. * * @param templateName Nom du modèle * @param locale Code de la langue * @return Modèle trouvé (Optional) */ public Optional findByNameAndLocale( @NotBlank String templateName, @NotBlank String locale) { log.debug("Recherche du modèle d'email : {} pour la locale : {}", templateName, locale); try { TypedQuery query = entityManager.createQuery( "SELECT t FROM EmailTemplate t " + "WHERE t.templateName = :name " + "AND t.locale = :locale " + "AND t.active = true " + "ORDER BY t.version DESC", EmailTemplate.class ); query.setParameter("name", templateName); query.setParameter("locale", locale); query.setMaxResults(1); return Optional.of(query.getSingleResult()); } catch (NoResultException e) { log.debug("Aucun modèle trouvé pour le nom : {} et la locale : {}", templateName, locale); return Optional.empty(); } catch (Exception e) { throw new RepositoryException( "Erreur lors de la recherche du modèle d'email localisé", e); } } /** * Crée ou met à jour un modèle d'email. * Gère automatiquement le versionnement des modèles. * * @param template Modèle à sauvegarder * @return Modèle sauvegardé */ @Transactional @Override public EmailTemplate save(EmailTemplate template) { log.debug("Sauvegarde du modèle d'email : {}", template.getTemplateName()); try { if (template.getId() == null) { setNextVersion(template); entityManager.persist(template); } else { template = entityManager.merge(template); } entityManager.flush(); log.info("Modèle d'email sauvegardé avec succès : {}", template.getTemplateName()); return template; } catch (Exception e) { throw new RepositoryException( "Erreur lors de la sauvegarde du modèle d'email", e); } } /** * Définit la prochaine version pour un nouveau modèle. */ private void setNextVersion(EmailTemplate template) { try { TypedQuery query = entityManager.createQuery( "SELECT MAX(t.version) FROM EmailTemplate t " + "WHERE t.templateName = :name", Long.class ); query.setParameter("name", template.getTemplateName()); Long maxVersion = query.getSingleResult(); template.setVersion(maxVersion == null ? 1L : maxVersion + 1); } catch (Exception e) { throw new RepositoryException( "Erreur lors de la définition de la version du modèle", e); } } /** * Supprime tous les modèles d'un certain nom. * * @param templateName Nom des modèles à supprimer */ @Transactional public void deleteByName(@NotBlank String templateName) { log.debug("Suppression des modèles d'email : {}", templateName); try { int deletedCount = entityManager.createQuery( "DELETE FROM EmailTemplate t WHERE t.templateName = :name") .setParameter("name", templateName) .executeUpdate(); log.info("{} modèles d'email supprimés pour le nom : {}", deletedCount, templateName); } catch (Exception e) { throw new RepositoryException( "Erreur lors de la suppression des modèles d'email", e); } } /** * Vérifie l'existence d'un modèle par son nom. * * @param templateName Nom du modèle à vérifier * @return true si le modèle existe */ public boolean existsByName(@NotBlank String templateName) { log.debug("Vérification de l'existence du modèle : {}", templateName); try { Long count = entityManager.createQuery( "SELECT COUNT(t) FROM EmailTemplate t WHERE t.templateName = :name", Long.class) .setParameter("name", templateName) .getSingleResult(); return count > 0; } catch (Exception e) { throw new RepositoryException( "Erreur lors de la vérification de l'existence du modèle", e); } } }