package dev.lions.unionflow.server.api.dto.evenement;

import static org.assertj.core.api.Assertions.assertThat;

import dev.lions.unionflow.server.api.enums.evenement.PrioriteEvenement;
import dev.lions.unionflow.server.api.enums.evenement.StatutEvenement;
import dev.lions.unionflow.server.api.enums.evenement.TypeEvenementMetier;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

/**
 * Tests unitaires pour EvenementDTO
 *
 * @author UnionFlow Team
 * @version 2.0
 * @since 2025-01-16
 */
@DisplayName("Tests EvenementDTO")
class EvenementDTOTest {

  private EvenementDTO evenement;

  @BeforeEach
  void setUp() {
    evenement = new EvenementDTO();
    evenement.setTitre("Formation Leadership");
    evenement.setStatut(StatutEvenement.PLANIFIE);
    evenement.setPriorite(PrioriteEvenement.NORMALE);
    evenement.setTypeEvenement(TypeEvenementMetier.FORMATION);
    evenement.setDateDebut(LocalDate.now().plusDays(30));
    evenement.setDateFin(LocalDate.now().plusDays(30));
    evenement.setHeureDebut(LocalTime.of(9, 0));
    evenement.setHeureFin(LocalTime.of(17, 0));
    evenement.setLieu("Centre de Formation");
    evenement.setCapaciteMax(50);
    evenement.setParticipantsInscrits(25);
    evenement.setBudget(new BigDecimal("500000"));
    evenement.setCoutReel(new BigDecimal("450000"));
    evenement.setCodeDevise("XOF");
    evenement.setAssociationId(UUID.randomUUID());
  }

  @Test
  @DisplayName("Test de base - classe peut être instanciée")
  void testClasseInstanciable() {
    assertThat(evenement).isNotNull();
  }

  @Nested
  @DisplayName("Tests de Construction")
  class ConstructionTests {

    @Test
    @DisplayName("Test constructeur par défaut")
    void testConstructeurParDefaut() {
      EvenementDTO newEvenement = new EvenementDTO();

      assertThat(newEvenement.getId()).isNotNull();
      assertThat(newEvenement.getDateCreation()).isNotNull();
      assertThat(newEvenement.isActif()).isTrue();
      assertThat(newEvenement.getVersion()).isEqualTo(0L);
      assertThat(newEvenement.getStatut()).isEqualTo(StatutEvenement.PLANIFIE);
      assertThat(newEvenement.getPriorite()).isEqualTo(PrioriteEvenement.NORMALE);
      assertThat(newEvenement.getParticipantsInscrits()).isEqualTo(0);
      assertThat(newEvenement.getParticipantsPresents()).isEqualTo(0);
      assertThat(newEvenement.getCodeDevise()).isEqualTo("XOF");
    }

    @Test
    @DisplayName("Test constructeur avec paramètres")
    void testConstructeurAvecParametres() {
      String titre = "Assemblée Générale";
      TypeEvenementMetier type = TypeEvenementMetier.ASSEMBLEE_GENERALE;
      LocalDate date = LocalDate.now().plusDays(15);

      EvenementDTO newEvenement = new EvenementDTO(titre, type, date, "Lieu par défaut");

      assertThat(newEvenement.getTitre()).isEqualTo(titre);
      assertThat(newEvenement.getTypeEvenement()).isEqualTo(type);
      assertThat(newEvenement.getDateDebut()).isEqualTo(date);
      assertThat(newEvenement.getStatut()).isEqualTo(StatutEvenement.PLANIFIE);
    }
  }

  @Nested
  @DisplayName("Tests des Méthodes Métier")
  class MethodesMetierTests {

    @Test
    @DisplayName("Test estEnCours")
    void testEstEnCours() {
      evenement.setStatut(StatutEvenement.EN_COURS);
      assertThat(evenement.estEnCours()).isTrue();

      evenement.setStatut(StatutEvenement.PLANIFIE);
      assertThat(evenement.estEnCours()).isFalse();
    }

    @Test
    @DisplayName("Test estTermine")
    void testEstTermine() {
      evenement.setStatut(StatutEvenement.TERMINE);
      assertThat(evenement.estTermine()).isTrue();

      evenement.setStatut(StatutEvenement.EN_COURS);
      assertThat(evenement.estTermine()).isFalse();
    }

    @Test
    @DisplayName("Test estAnnule")
    void testEstAnnule() {
      evenement.setStatut(StatutEvenement.ANNULE);
      assertThat(evenement.estAnnule()).isTrue();

      evenement.setStatut(StatutEvenement.PLANIFIE);
      assertThat(evenement.estAnnule()).isFalse();
    }

    @Test
    @DisplayName("Test estComplet")
    void testEstComplet() {
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(50);
      assertThat(evenement.estComplet()).isTrue();

      evenement.setParticipantsInscrits(49);
      assertThat(evenement.estComplet()).isFalse();

      evenement.setCapaciteMax(null);
      assertThat(evenement.estComplet()).isFalse();

      // Test avec participantsInscrits null (branche manquante)
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(null);
      assertThat(evenement.estComplet()).isFalse();
    }

    @Test
    @DisplayName("Test getPlacesDisponibles")
    void testGetPlacesDisponibles() {
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(25);
      assertThat(evenement.getPlacesDisponibles()).isEqualTo(25);

      evenement.setParticipantsInscrits(60); // Plus que la capacité
      assertThat(evenement.getPlacesDisponibles()).isEqualTo(0);

      evenement.setCapaciteMax(null);
      assertThat(evenement.getPlacesDisponibles()).isEqualTo(0);

      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(null);
      assertThat(evenement.getPlacesDisponibles()).isEqualTo(0);

      // Test avec capaciteMax == participantsInscrits
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(50);
      assertThat(evenement.getPlacesDisponibles()).isEqualTo(0);
    }

    @Test
    @DisplayName("Test getTauxRemplissage")
    void testGetTauxRemplissage() {
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(25);
      assertThat(evenement.getTauxRemplissage()).isEqualTo(50);

      evenement.setParticipantsInscrits(50);
      assertThat(evenement.getTauxRemplissage()).isEqualTo(100);

      evenement.setCapaciteMax(0);
      assertThat(evenement.getTauxRemplissage()).isEqualTo(0);

      evenement.setCapaciteMax(null);
      assertThat(evenement.getTauxRemplissage()).isEqualTo(0);

      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(null);
      assertThat(evenement.getTauxRemplissage()).isEqualTo(0);
    }

    @Test
    @DisplayName("Test getTauxPresence")
    void testGetTauxPresence() {
      evenement.setParticipantsInscrits(100);
      evenement.setParticipantsPresents(75);
      assertThat(evenement.getTauxPresence()).isEqualTo(75);

      evenement.setParticipantsPresents(100);
      assertThat(evenement.getTauxPresence()).isEqualTo(100);

      evenement.setParticipantsInscrits(0);
      assertThat(evenement.getTauxPresence()).isEqualTo(0);

      evenement.setParticipantsInscrits(null);
      assertThat(evenement.getTauxPresence()).isEqualTo(0);

      evenement.setParticipantsInscrits(100);
      evenement.setParticipantsPresents(null);
      assertThat(evenement.getTauxPresence()).isEqualTo(0);
    }

    @Test
    @DisplayName("Test sontInscriptionsOuvertes")
    void testSontInscriptionsOuvertes() {
      // Événement normal avec places disponibles
      evenement.setStatut(StatutEvenement.PLANIFIE);
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(25);
      evenement.setDateLimiteInscription(LocalDate.now().plusDays(5));
      assertThat(evenement.sontInscriptionsOuvertes()).isTrue();

      // Événement annulé
      evenement.setStatut(StatutEvenement.ANNULE);
      assertThat(evenement.sontInscriptionsOuvertes()).isFalse();

      // Événement terminé
      evenement.setStatut(StatutEvenement.TERMINE);
      assertThat(evenement.sontInscriptionsOuvertes()).isFalse();

      // Événement complet
      evenement.setStatut(StatutEvenement.PLANIFIE);
      evenement.setParticipantsInscrits(50);
      assertThat(evenement.sontInscriptionsOuvertes()).isFalse();

      // Date limite dépassée
      evenement.setParticipantsInscrits(25);
      evenement.setDateLimiteInscription(LocalDate.now().minusDays(1));
      assertThat(evenement.sontInscriptionsOuvertes()).isFalse();

      // Date limite null (inscriptions ouvertes si autres conditions OK)
      evenement.setStatut(StatutEvenement.PLANIFIE);
      evenement.setParticipantsInscrits(25);
      evenement.setDateLimiteInscription(null);
      assertThat(evenement.sontInscriptionsOuvertes()).isTrue();
    }

    @Test
    @DisplayName("Test estEvenementMultiJours")
    void testEstEvenementMultiJours() {
      evenement.setDateDebut(LocalDate.now().plusDays(1));
      evenement.setDateFin(LocalDate.now().plusDays(3));
      assertThat(evenement.estEvenementMultiJours()).isTrue();

      evenement.setDateFin(LocalDate.now().plusDays(1));
      assertThat(evenement.estEvenementMultiJours()).isFalse();

      evenement.setDateFin(null);
      assertThat(evenement.estEvenementMultiJours()).isFalse();

      // Test avec dateDebut et dateFin identiques
      evenement.setDateDebut(LocalDate.now().plusDays(1));
      evenement.setDateFin(LocalDate.now().plusDays(1));
      assertThat(evenement.estEvenementMultiJours()).isFalse();

      // Test avec dateDebut null et dateFin null
      evenement.setDateDebut(null);
      evenement.setDateFin(null);
      assertThat(evenement.estEvenementMultiJours()).isFalse();
    }

    @Test
    @DisplayName("Test getDureeEnHeures")
    void testGetDureeEnHeures() {
      evenement.setHeureDebut(LocalTime.of(9, 0));
      evenement.setHeureFin(LocalTime.of(17, 0));
      assertThat(evenement.getDureeEnHeures()).isEqualTo(8);

      evenement.setHeureDebut(LocalTime.of(10, 0));
      evenement.setHeureFin(LocalTime.of(12, 30));
      assertThat(evenement.getDureeEnHeures()).isEqualTo(2);

      evenement.setHeureDebut(null);
      assertThat(evenement.getDureeEnHeures()).isEqualTo(0);

      evenement.setHeureDebut(LocalTime.of(9, 0));
      evenement.setHeureFin(null);
      assertThat(evenement.getDureeEnHeures()).isEqualTo(0);
    }

    @Test
    @DisplayName("Test hasCoordonnees")
    void testHasCoordonnees() {
      evenement.setLatitude(new BigDecimal("14.6937"));
      evenement.setLongitude(new BigDecimal("-17.4441"));
      assertThat(evenement.hasCoordonnees()).isTrue();

      evenement.setLatitude(null);
      assertThat(evenement.hasCoordonnees()).isFalse();

      evenement.setLatitude(new BigDecimal("14.6937"));
      evenement.setLongitude(null);
      assertThat(evenement.hasCoordonnees()).isFalse();
    }

    @Test
    @DisplayName("Test estBudgetDepasse")
    void testEstBudgetDepasse() {
      evenement.setBudget(new BigDecimal("500000"));
      evenement.setCoutReel(new BigDecimal("600000"));
      assertThat(evenement.estBudgetDepasse()).isTrue();

      evenement.setCoutReel(new BigDecimal("400000"));
      assertThat(evenement.estBudgetDepasse()).isFalse();

      evenement.setCoutReel(new BigDecimal("500000"));
      assertThat(evenement.estBudgetDepasse()).isFalse();
    }
  }

  @Nested
  @DisplayName("Tests des Méthodes Utilitaires")
  class MethodesUtilitairesTests {

    @Test
    @DisplayName("Test getStatutLibelle")
    void testGetStatutLibelle() {
      evenement.setStatut(StatutEvenement.PLANIFIE);
      assertThat(evenement.getStatutLibelle()).isEqualTo("Planifié");

      evenement.setStatut(null);
      assertThat(evenement.getStatutLibelle()).isEqualTo("Non défini");
    }

    @Test
    @DisplayName("Test getPrioriteLibelle")
    void testGetPrioriteLibelle() {
      evenement.setPriorite(PrioriteEvenement.HAUTE);
      assertThat(evenement.getPrioriteLibelle()).isEqualTo("Haute");

      evenement.setPriorite(null);
      assertThat(evenement.getPrioriteLibelle()).isEqualTo("Normale");
    }

    @Test
    @DisplayName("Test getTypeEvenementLibelle")
    void testGetTypeEvenementLibelle() {
      evenement.setTypeEvenement(TypeEvenementMetier.FORMATION);
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Formation");

      evenement.setTypeEvenement(null);
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Non défini");
    }

    @Test
    @DisplayName("Test getEcartBudgetaire")
    void testGetEcartBudgetaire() {
      evenement.setBudget(new BigDecimal("500000"));
      evenement.setCoutReel(new BigDecimal("450000"));
      assertThat(evenement.getEcartBudgetaire()).isEqualTo(new BigDecimal("50000"));

      evenement.setCoutReel(new BigDecimal("550000"));
      assertThat(evenement.getEcartBudgetaire()).isEqualTo(new BigDecimal("-50000"));

      evenement.setBudget(null);
      assertThat(evenement.getEcartBudgetaire()).isEqualTo(BigDecimal.ZERO);

      evenement.setBudget(new BigDecimal("500000"));
      evenement.setCoutReel(null);
      assertThat(evenement.getEcartBudgetaire()).isEqualTo(BigDecimal.ZERO);
    }

    @Test
    @DisplayName("Test getAdresseComplete - tous les champs")
    void testGetAdresseCompleteTousChamps() {
      evenement.setLieu("Centre de Formation");
      evenement.setAdresse("123 Rue de la République");
      evenement.setVille("Dakar");
      evenement.setRegion("Dakar");

      String adresse = evenement.getAdresseComplete();
      assertThat(adresse).contains("Centre de Formation");
      assertThat(adresse).contains("123 Rue de la République");
      assertThat(adresse).contains("Dakar");
    }

    @Test
    @DisplayName("Test getAdresseComplete - seulement lieu")
    void testGetAdresseCompleteSeulementLieu() {
      evenement.setLieu("Centre de Formation");
      evenement.setAdresse(null);
      evenement.setVille(null);
      evenement.setRegion(null);

      assertThat(evenement.getAdresseComplete()).isEqualTo("Centre de Formation");
    }

    @Test
    @DisplayName("Test getAdresseComplete - lieu et adresse")
    void testGetAdresseCompleteLieuEtAdresse() {
      evenement.setLieu("Centre de Formation");
      evenement.setAdresse("123 Rue de la République");
      evenement.setVille(null);
      evenement.setRegion(null);

      assertThat(evenement.getAdresseComplete()).isEqualTo("Centre de Formation, 123 Rue de la République");
    }

    @Test
    @DisplayName("Test getAdresseComplete - tous null")
    void testGetAdresseCompleteTousNull() {
      evenement.setLieu(null);
      evenement.setAdresse(null);
      evenement.setVille(null);
      evenement.setRegion(null);

      assertThat(evenement.getAdresseComplete()).isEmpty();
    }

    @Test
    @DisplayName("Test getAdresseComplete - champs vides")
    void testGetAdresseCompleteChampsVides() {
      evenement.setLieu("   ");
      evenement.setAdresse("   ");
      evenement.setVille("   ");
      evenement.setRegion("   ");

      assertThat(evenement.getAdresseComplete()).isEmpty();
    }

    @Test
    @DisplayName("Test getAdresseComplete - lieu null mais adresse non null")
    void testGetAdresseCompleteLieuNullAdresseNonNull() {
      evenement.setLieu(null);
      evenement.setAdresse("123 Rue de la République");
      evenement.setVille(null);
      evenement.setRegion(null);

      // Quand lieu est null, adresseComplete.length() == 0, donc pas de virgule avant adresse
      assertThat(evenement.getAdresseComplete()).isEqualTo("123 Rue de la République");
    }

    @Test
    @DisplayName("Test getAdresseComplete - lieu et adresse null mais ville non null")
    void testGetAdresseCompleteLieuEtAdresseNullVilleNonNull() {
      evenement.setLieu(null);
      evenement.setAdresse(null);
      evenement.setVille("Dakar");
      evenement.setRegion(null);

      // Quand lieu et adresse sont null, adresseComplete.length() == 0, donc pas de virgule avant ville
      assertThat(evenement.getAdresseComplete()).isEqualTo("Dakar");
    }

    @Test
    @DisplayName("Test getAdresseComplete - lieu, adresse et ville null mais région non null")
    void testGetAdresseCompleteLieuAdresseVilleNullRegionNonNull() {
      evenement.setLieu(null);
      evenement.setAdresse(null);
      evenement.setVille(null);
      evenement.setRegion("Dakar");

      // Quand lieu, adresse et ville sont null, adresseComplete.length() == 0, donc pas de virgule avant région
      assertThat(evenement.getAdresseComplete()).isEqualTo("Dakar");
    }

    @Test
    @DisplayName("Test getAdresseComplete - lieu null, adresse et ville non null")
    void testGetAdresseCompleteLieuNullAdresseEtVilleNonNull() {
      evenement.setLieu(null);
      evenement.setAdresse("123 Rue de la République");
      evenement.setVille("Dakar");
      evenement.setRegion(null);

      // Quand lieu est null, première condition adresseComplete.length() > 0 est false pour adresse
      // Mais après avoir ajouté adresse, adresseComplete.length() > 0 est true pour ville
      assertThat(evenement.getAdresseComplete()).isEqualTo("123 Rue de la République, Dakar");
    }

    @Test
    @DisplayName("Test getAdresseComplete - lieu null, adresse, ville et région non null")
    void testGetAdresseCompleteLieuNullAdresseVilleRegionNonNull() {
      evenement.setLieu(null);
      evenement.setAdresse("123 Rue de la République");
      evenement.setVille("Dakar");
      evenement.setRegion("Sénégal");

      // Quand lieu est null, première condition adresseComplete.length() > 0 est false pour adresse
      // Mais après avoir ajouté adresse, adresseComplete.length() > 0 est true pour ville et région
      assertThat(evenement.getAdresseComplete()).isEqualTo("123 Rue de la République, Dakar, Sénégal");
    }
  }

  @Nested
  @DisplayName("Tests Getters/Setters complets")
  class GettersSettersTests {

    @Test
    @DisplayName("Test tous les getters/setters")
    void testTousLesGettersSetters() {
      EvenementDTO dto = new EvenementDTO();

      // Test des champs de base
      dto.setTitre("Test Événement");
      assertThat(dto.getTitre()).isEqualTo("Test Événement");

      dto.setDescription("Description test");
      assertThat(dto.getDescription()).isEqualTo("Description test");

      dto.setLieu("Lieu test");
      assertThat(dto.getLieu()).isEqualTo("Lieu test");

      dto.setAdresse("Adresse test");
      assertThat(dto.getAdresse()).isEqualTo("Adresse test");

      dto.setVille("Ville test");
      assertThat(dto.getVille()).isEqualTo("Ville test");

      dto.setRegion("Région test");
      assertThat(dto.getRegion()).isEqualTo("Région test");

      LocalDate dateDebut = LocalDate.of(2025, 6, 1);
      dto.setDateDebut(dateDebut);
      assertThat(dto.getDateDebut()).isEqualTo(dateDebut);

      LocalDate dateFin = LocalDate.of(2025, 6, 3);
      dto.setDateFin(dateFin);
      assertThat(dto.getDateFin()).isEqualTo(dateFin);

      LocalTime heureDebut = LocalTime.of(9, 0);
      dto.setHeureDebut(heureDebut);
      assertThat(dto.getHeureDebut()).isEqualTo(heureDebut);

      LocalTime heureFin = LocalTime.of(17, 0);
      dto.setHeureFin(heureFin);
      assertThat(dto.getHeureFin()).isEqualTo(heureFin);

      BigDecimal latitude = new BigDecimal("14.6937");
      dto.setLatitude(latitude);
      assertThat(dto.getLatitude()).isEqualTo(latitude);

      BigDecimal longitude = new BigDecimal("-17.4441");
      dto.setLongitude(longitude);
      assertThat(dto.getLongitude()).isEqualTo(longitude);

      UUID associationId = UUID.randomUUID();
      dto.setAssociationId(associationId);
      assertThat(dto.getAssociationId()).isEqualTo(associationId);

      dto.setNomAssociation("Association Test");
      assertThat(dto.getNomAssociation()).isEqualTo("Association Test");

      dto.setOrganisateur("Organisateur Test");
      assertThat(dto.getOrganisateur()).isEqualTo("Organisateur Test");

      dto.setEmailOrganisateur("test@example.com");
      assertThat(dto.getEmailOrganisateur()).isEqualTo("test@example.com");

      dto.setTelephoneOrganisateur("+221 77 123 45 67");
      assertThat(dto.getTelephoneOrganisateur()).isEqualTo("+221 77 123 45 67");

      dto.setCapaciteMax(100);
      assertThat(dto.getCapaciteMax()).isEqualTo(100);

      dto.setParticipantsInscrits(50);
      assertThat(dto.getParticipantsInscrits()).isEqualTo(50);

      dto.setParticipantsPresents(45);
      assertThat(dto.getParticipantsPresents()).isEqualTo(45);

      BigDecimal budget = new BigDecimal("1000000.00");
      dto.setBudget(budget);
      assertThat(dto.getBudget()).isEqualTo(budget);

      BigDecimal coutReel = new BigDecimal("950000.00");
      dto.setCoutReel(coutReel);
      assertThat(dto.getCoutReel()).isEqualTo(coutReel);

      dto.setCodeDevise("EUR");
      assertThat(dto.getCodeDevise()).isEqualTo("EUR");

      dto.setInscriptionObligatoire(true);
      assertThat(dto.getInscriptionObligatoire()).isTrue();

      LocalDate dateLimite = LocalDate.of(2025, 5, 25);
      dto.setDateLimiteInscription(dateLimite);
      assertThat(dto.getDateLimiteInscription()).isEqualTo(dateLimite);

      dto.setEvenementPublic(false);
      assertThat(dto.getEvenementPublic()).isFalse();

      dto.setRecurrent(true);
      assertThat(dto.getRecurrent()).isTrue();

      dto.setFrequenceRecurrence("MENSUELLE");
      assertThat(dto.getFrequenceRecurrence()).isEqualTo("MENSUELLE");

      dto.setInstructions("Instructions spéciales");
      assertThat(dto.getInstructions()).isEqualTo("Instructions spéciales");

      dto.setMaterielNecessaire("Matériel nécessaire");
      assertThat(dto.getMaterielNecessaire()).isEqualTo("Matériel nécessaire");

      dto.setConditionsMeteo("Conditions météo");
      assertThat(dto.getConditionsMeteo()).isEqualTo("Conditions météo");

      dto.setImageUrl("https://example.com/image.jpg");
      assertThat(dto.getImageUrl()).isEqualTo("https://example.com/image.jpg");

      dto.setCouleurTheme("#FF5733");
      assertThat(dto.getCouleurTheme()).isEqualTo("#FF5733");

      LocalDateTime dateAnnulation = LocalDateTime.of(2025, 5, 20, 10, 0);
      dto.setDateAnnulation(dateAnnulation);
      assertThat(dto.getDateAnnulation()).isEqualTo(dateAnnulation);

      dto.setRaisonAnnulation("Raison d'annulation");
      assertThat(dto.getRaisonAnnulation()).isEqualTo("Raison d'annulation");

      dto.setAnnulePar(123L);
      assertThat(dto.getAnnulePar()).isEqualTo(123L);

      dto.setNomAnnulateur("Nom Annulateur");
      assertThat(dto.getNomAnnulateur()).isEqualTo("Nom Annulateur");
    }

    @Test
    @DisplayName("Test getters/setters avec valeurs null")
    void testGettersSettersAvecNull() {
      EvenementDTO dto = new EvenementDTO();

      dto.setTitre(null);
      assertThat(dto.getTitre()).isNull();

      dto.setDescription(null);
      assertThat(dto.getDescription()).isNull();

      dto.setDateFin(null);
      assertThat(dto.getDateFin()).isNull();

      dto.setHeureDebut(null);
      assertThat(dto.getHeureDebut()).isNull();

      dto.setLatitude(null);
      assertThat(dto.getLatitude()).isNull();

      dto.setAssociationId(null);
      assertThat(dto.getAssociationId()).isNull();

      dto.setBudget(null);
      assertThat(dto.getBudget()).isNull();

      dto.setCoutReel(null);
      assertThat(dto.getCoutReel()).isNull();

      dto.setDateLimiteInscription(null);
      assertThat(dto.getDateLimiteInscription()).isNull();

      dto.setDateAnnulation(null);
      assertThat(dto.getDateAnnulation()).isNull();
    }
  }

  @Nested
  @DisplayName("Tests toString")
  class ToStringTests {

    @Test
    @DisplayName("Test toString - contient les informations essentielles")
    void testToString() {
      evenement.setTitre("Formation Leadership");
      evenement.setTypeEvenement(TypeEvenementMetier.FORMATION);
      evenement.setStatut(StatutEvenement.PLANIFIE);
      evenement.setDateDebut(LocalDate.now().plusDays(30));
      evenement.setLieu("Centre de Formation");
      evenement.setParticipantsInscrits(25);
      evenement.setCapaciteMax(50);

      String result = evenement.toString();

      assertThat(result).contains("EvenementDTO");
      assertThat(result).contains("Formation Leadership");
      assertThat(result).contains("FORMATION");
      assertThat(result).contains("PLANIFIE");
      assertThat(result).contains("Centre de Formation");
      assertThat(result).contains("25");
      assertThat(result).contains("50");
    }

    @Test
    @DisplayName("Test toString - avec valeurs null")
    void testToStringAvecNull() {
      EvenementDTO dto = new EvenementDTO();
      dto.setTitre(null);
      dto.setTypeEvenement(null);
      dto.setStatut(null);
      dto.setDateDebut(null);
      dto.setLieu(null);
      dto.setParticipantsInscrits(null);
      dto.setCapaciteMax(null);

      String result = dto.toString();

      assertThat(result).contains("EvenementDTO");
      assertThat(result).contains("null");
    }
  }
}
