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

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

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 complets pour EvenementDTO.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2025-01-10
 */
@DisplayName("Tests EvenementDTO")
class EvenementDTOBasicTest {

  private EvenementDTO evenement;

  @BeforeEach
  void setUp() {
    evenement = new EvenementDTO();
  }

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

    @Test
    @DisplayName("Constructeur par défaut - Initialisation correcte")
    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("PLANIFIE");
      assertThat(newEvenement.getPriorite()).isEqualTo("NORMALE");
      assertThat(newEvenement.getParticipantsInscrits()).isEqualTo(0);
      assertThat(newEvenement.getParticipantsPresents()).isEqualTo(0);
      assertThat(newEvenement.getInscriptionObligatoire()).isFalse();
      assertThat(newEvenement.getEvenementPublic()).isTrue();
      assertThat(newEvenement.getRecurrent()).isFalse();
      assertThat(newEvenement.getCodeDevise()).isEqualTo("XOF");
    }

    @Test
    @DisplayName("Constructeur avec paramètres - Initialisation correcte")
    void testConstructeurAvecParametres() {
      String titre = "Réunion mensuelle";
      String typeEvenement = "REUNION_BUREAU";
      LocalDate dateDebut = LocalDate.now().plusDays(7);
      String lieu = "Salle de conférence";

      EvenementDTO newEvenement = new EvenementDTO(titre, typeEvenement, dateDebut, lieu);

      assertThat(newEvenement.getTitre()).isEqualTo(titre);
      assertThat(newEvenement.getTypeEvenement()).isEqualTo(typeEvenement);
      assertThat(newEvenement.getDateDebut()).isEqualTo(dateDebut);
      assertThat(newEvenement.getLieu()).isEqualTo(lieu);
      assertThat(newEvenement.getStatut()).isEqualTo("PLANIFIE");
    }
  }

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

    @Test
    @DisplayName("Test tous les getters/setters")
    void testTousLesGettersSetters() {
      // Données de test
      String titre = "Formation Leadership";
      String description = "Formation sur le leadership associatif";
      String typeEvenement = "FORMATION";
      String statut = "EN_COURS";
      String priorite = "HAUTE";
      LocalDate dateDebut = LocalDate.now().plusDays(1);
      LocalDate dateFin = LocalDate.now().plusDays(2);
      LocalTime heureDebut = LocalTime.of(9, 0);
      LocalTime heureFin = LocalTime.of(17, 0);
      String lieu = "Centre de formation";
      String adresse = "123 Avenue de la République";
      String ville = "Dakar";
      String region = "Dakar";
      BigDecimal latitude = new BigDecimal("14.6937");
      BigDecimal longitude = new BigDecimal("-17.4441");
      UUID associationId = UUID.randomUUID();
      String nomAssociation = "Lions Club Dakar";
      String organisateur = "Jean Dupont";
      String emailOrganisateur = "jean.dupont@example.com";
      String telephoneOrganisateur = "+221701234567";
      Integer capaciteMax = 50;
      Integer participantsInscrits = 25;
      Integer participantsPresents = 20;
      BigDecimal budget = new BigDecimal("500000.00");
      BigDecimal coutReel = new BigDecimal("450000.00");
      String codeDevise = "XOF";
      Boolean inscriptionObligatoire = true;
      LocalDate dateLimiteInscription = LocalDate.now().plusDays(5);
      Boolean evenementPublic = false;
      Boolean recurrent = true;
      String frequenceRecurrence = "MENSUELLE";
      String instructions = "Apporter un carnet de notes";
      String materielNecessaire = "Projecteur, tableau";
      String conditionsMeteo = "Intérieur";
      String imageUrl = "https://example.com/image.jpg";
      String couleurTheme = "#FF5733";
      LocalDateTime dateAnnulation = LocalDateTime.now();
      String raisonAnnulation = "Conditions météo";
      Long annulePar = 123L;
      String nomAnnulateur = "Admin";

      // Test des setters
      evenement.setTitre(titre);
      evenement.setDescription(description);
      evenement.setTypeEvenement(typeEvenement);
      evenement.setStatut(statut);
      evenement.setPriorite(priorite);
      evenement.setDateDebut(dateDebut);
      evenement.setDateFin(dateFin);
      evenement.setHeureDebut(heureDebut);
      evenement.setHeureFin(heureFin);
      evenement.setLieu(lieu);
      evenement.setAdresse(adresse);
      evenement.setVille(ville);
      evenement.setRegion(region);
      evenement.setLatitude(latitude);
      evenement.setLongitude(longitude);
      evenement.setAssociationId(associationId);
      evenement.setNomAssociation(nomAssociation);
      evenement.setOrganisateur(organisateur);
      evenement.setEmailOrganisateur(emailOrganisateur);
      evenement.setTelephoneOrganisateur(telephoneOrganisateur);
      evenement.setCapaciteMax(capaciteMax);
      evenement.setParticipantsInscrits(participantsInscrits);
      evenement.setParticipantsPresents(participantsPresents);
      evenement.setBudget(budget);
      evenement.setCoutReel(coutReel);
      evenement.setCodeDevise(codeDevise);
      evenement.setInscriptionObligatoire(inscriptionObligatoire);
      evenement.setDateLimiteInscription(dateLimiteInscription);
      evenement.setEvenementPublic(evenementPublic);
      evenement.setRecurrent(recurrent);
      evenement.setFrequenceRecurrence(frequenceRecurrence);
      evenement.setInstructions(instructions);
      evenement.setMaterielNecessaire(materielNecessaire);
      evenement.setConditionsMeteo(conditionsMeteo);
      evenement.setImageUrl(imageUrl);
      evenement.setCouleurTheme(couleurTheme);
      evenement.setDateAnnulation(dateAnnulation);
      evenement.setRaisonAnnulation(raisonAnnulation);
      evenement.setAnnulePar(annulePar);
      evenement.setNomAnnulateur(nomAnnulateur);

      // Test des getters
      assertThat(evenement.getTitre()).isEqualTo(titre);
      assertThat(evenement.getDescription()).isEqualTo(description);
      assertThat(evenement.getTypeEvenement()).isEqualTo(typeEvenement);
      assertThat(evenement.getStatut()).isEqualTo(statut);
      assertThat(evenement.getPriorite()).isEqualTo(priorite);
      assertThat(evenement.getDateDebut()).isEqualTo(dateDebut);
      assertThat(evenement.getDateFin()).isEqualTo(dateFin);
      assertThat(evenement.getHeureDebut()).isEqualTo(heureDebut);
      assertThat(evenement.getHeureFin()).isEqualTo(heureFin);
      assertThat(evenement.getLieu()).isEqualTo(lieu);
      assertThat(evenement.getAdresse()).isEqualTo(adresse);
      assertThat(evenement.getVille()).isEqualTo(ville);
      assertThat(evenement.getRegion()).isEqualTo(region);
      assertThat(evenement.getLatitude()).isEqualTo(latitude);
      assertThat(evenement.getLongitude()).isEqualTo(longitude);
      assertThat(evenement.getAssociationId()).isEqualTo(associationId);
      assertThat(evenement.getNomAssociation()).isEqualTo(nomAssociation);
      assertThat(evenement.getOrganisateur()).isEqualTo(organisateur);
      assertThat(evenement.getEmailOrganisateur()).isEqualTo(emailOrganisateur);
      assertThat(evenement.getTelephoneOrganisateur()).isEqualTo(telephoneOrganisateur);
      assertThat(evenement.getCapaciteMax()).isEqualTo(capaciteMax);
      assertThat(evenement.getParticipantsInscrits()).isEqualTo(participantsInscrits);
      assertThat(evenement.getParticipantsPresents()).isEqualTo(participantsPresents);
      assertThat(evenement.getBudget()).isEqualTo(budget);
      assertThat(evenement.getCoutReel()).isEqualTo(coutReel);
      assertThat(evenement.getCodeDevise()).isEqualTo(codeDevise);
      assertThat(evenement.getInscriptionObligatoire()).isEqualTo(inscriptionObligatoire);
      assertThat(evenement.getDateLimiteInscription()).isEqualTo(dateLimiteInscription);
      assertThat(evenement.getEvenementPublic()).isEqualTo(evenementPublic);
      assertThat(evenement.getRecurrent()).isEqualTo(recurrent);
      assertThat(evenement.getFrequenceRecurrence()).isEqualTo(frequenceRecurrence);
      assertThat(evenement.getInstructions()).isEqualTo(instructions);
      assertThat(evenement.getMaterielNecessaire()).isEqualTo(materielNecessaire);
      assertThat(evenement.getConditionsMeteo()).isEqualTo(conditionsMeteo);
      assertThat(evenement.getImageUrl()).isEqualTo(imageUrl);
      assertThat(evenement.getCouleurTheme()).isEqualTo(couleurTheme);
      assertThat(evenement.getDateAnnulation()).isEqualTo(dateAnnulation);
      assertThat(evenement.getRaisonAnnulation()).isEqualTo(raisonAnnulation);
      assertThat(evenement.getAnnulePar()).isEqualTo(annulePar);
      assertThat(evenement.getNomAnnulateur()).isEqualTo(nomAnnulateur);
    }
  }

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

    @Test
    @DisplayName("Test méthodes de statut")
    void testMethodesStatut() {
      // Test isEnCours
      evenement.setStatut("EN_COURS");
      assertThat(evenement.isEnCours()).isTrue();
      evenement.setStatut("PLANIFIE");
      assertThat(evenement.isEnCours()).isFalse();

      // Test isTermine
      evenement.setStatut("TERMINE");
      assertThat(evenement.isTermine()).isTrue();
      evenement.setStatut("PLANIFIE");
      assertThat(evenement.isTermine()).isFalse();

      // Test isAnnule
      evenement.setStatut("ANNULE");
      assertThat(evenement.isAnnule()).isTrue();
      evenement.setStatut("PLANIFIE");
      assertThat(evenement.isAnnule()).isFalse();
    }

    @Test
    @DisplayName("Test méthodes de capacité")
    void testMethodesCapacite() {
      // Test isComplet - cas avec capaciteMax null
      evenement.setCapaciteMax(null);
      evenement.setParticipantsInscrits(50);
      assertThat(evenement.isComplet()).isFalse();

      // Test isComplet - cas avec participantsInscrits null (capaciteMax définie)
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(null);
      assertThat(evenement.isComplet()).isFalse();

      // Test isComplet - cas avec les deux null
      evenement.setCapaciteMax(null);
      evenement.setParticipantsInscrits(null);
      assertThat(evenement.isComplet()).isFalse();

      // Test isComplet - cas normal complet
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(50);
      assertThat(evenement.isComplet()).isTrue();

      // Test isComplet - cas normal non complet
      evenement.setParticipantsInscrits(30);
      assertThat(evenement.isComplet()).isFalse();

      // Test getPlacesDisponibles
      assertThat(evenement.getPlacesDisponibles()).isEqualTo(20);

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

      // Test getTauxRemplissage
      evenement.setCapaciteMax(100);
      evenement.setParticipantsInscrits(75);
      assertThat(evenement.getTauxRemplissage()).isEqualTo(75);

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

    @Test
    @DisplayName("Test isComplet - branches spécifiques")
    void testIsCompletBranchesSpecifiques() {
      // Test spécifique pour la branche: capaciteMax != null && participantsInscrits == null
      // Nous devons nous assurer que capaciteMax est définie ET que participantsInscrits est null
      evenement.setCapaciteMax(100); // Défini explicitement
      evenement.setParticipantsInscrits(null); // Null explicitement

      // Cette condition devrait évaluer:
      // capaciteMax != null (true) && participantsInscrits != null (false) && ...
      // Donc retourner false à cause du court-circuit sur participantsInscrits != null
      assertThat(evenement.isComplet()).isFalse();

      // Test pour vérifier que la branche participantsInscrits != null est bien testée
      // Maintenant avec participantsInscrits défini
      evenement.setParticipantsInscrits(50); // Défini mais < capaciteMax
      assertThat(evenement.isComplet()).isFalse();

      // Et maintenant avec participantsInscrits >= capaciteMax
      evenement.setParticipantsInscrits(100); // Égal à capaciteMax
      assertThat(evenement.isComplet()).isTrue();
    }

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

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

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

    @Test
    @DisplayName("Test isInscriptionsOuvertes")
    void testIsInscriptionsOuvertes() {
      // Événement normal avec places disponibles
      evenement.setStatut("PLANIFIE");
      evenement.setCapaciteMax(50);
      evenement.setParticipantsInscrits(30);
      assertThat(evenement.isInscriptionsOuvertes()).isTrue();

      // Événement annulé
      evenement.setStatut("ANNULE");
      assertThat(evenement.isInscriptionsOuvertes()).isFalse();

      // Événement terminé
      evenement.setStatut("TERMINE");
      assertThat(evenement.isInscriptionsOuvertes()).isFalse();

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

      // Date limite dépassée
      evenement.setParticipantsInscrits(30);
      evenement.setDateLimiteInscription(LocalDate.now().minusDays(1));
      assertThat(evenement.isInscriptionsOuvertes()).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(null);
      assertThat(evenement.getDureeEnHeures()).isEqualTo(0);
    }

    @Test
    @DisplayName("Test isEvenementMultiJours")
    void testIsEvenementMultiJours() {
      LocalDate dateDebut = LocalDate.now();
      evenement.setDateDebut(dateDebut);
      evenement.setDateFin(dateDebut.plusDays(2));
      assertThat(evenement.isEvenementMultiJours()).isTrue();

      evenement.setDateFin(dateDebut);
      assertThat(evenement.isEvenementMultiJours()).isFalse();

      evenement.setDateFin(null);
      assertThat(evenement.isEvenementMultiJours()).isFalse();
    }

    @Test
    @DisplayName("Test getTypeEvenementLibelle")
    void testGetTypeEvenementLibelle() {
      evenement.setTypeEvenement("ASSEMBLEE_GENERALE");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Assemblée Générale");

      evenement.setTypeEvenement("FORMATION");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Formation");

      evenement.setTypeEvenement("ACTIVITE_SOCIALE");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Activité Sociale");

      evenement.setTypeEvenement("ACTION_CARITATIVE");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Action Caritative");

      evenement.setTypeEvenement("REUNION_BUREAU");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Réunion de Bureau");

      evenement.setTypeEvenement("CONFERENCE");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Conférence");

      evenement.setTypeEvenement("ATELIER");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Atelier");

      evenement.setTypeEvenement("CEREMONIE");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Cérémonie");

      evenement.setTypeEvenement("AUTRE");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("Autre");

      evenement.setTypeEvenement("INCONNU");
      assertThat(evenement.getTypeEvenementLibelle()).isEqualTo("INCONNU");

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

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

      evenement.setStatut("EN_COURS");
      assertThat(evenement.getStatutLibelle()).isEqualTo("En cours");

      evenement.setStatut("TERMINE");
      assertThat(evenement.getStatutLibelle()).isEqualTo("Terminé");

      evenement.setStatut("ANNULE");
      assertThat(evenement.getStatutLibelle()).isEqualTo("Annulé");

      evenement.setStatut("REPORTE");
      assertThat(evenement.getStatutLibelle()).isEqualTo("Reporté");

      evenement.setStatut("INCONNU");
      assertThat(evenement.getStatutLibelle()).isEqualTo("INCONNU");

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

    @Test
    @DisplayName("Test getPrioriteLibelle")
    void testGetPrioriteLibelle() {
      evenement.setPriorite("BASSE");
      assertThat(evenement.getPrioriteLibelle()).isEqualTo("Basse");

      evenement.setPriorite("NORMALE");
      assertThat(evenement.getPrioriteLibelle()).isEqualTo("Normale");

      evenement.setPriorite("HAUTE");
      assertThat(evenement.getPrioriteLibelle()).isEqualTo("Haute");

      evenement.setPriorite("CRITIQUE");
      assertThat(evenement.getPrioriteLibelle()).isEqualTo("Critique");

      evenement.setPriorite("INCONNU");
      assertThat(evenement.getPrioriteLibelle()).isEqualTo("INCONNU");

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

    @Test
    @DisplayName("Test getAdresseComplete")
    void testGetAdresseComplete() {
      // Adresse complète
      evenement.setLieu("Centre de conférence");
      evenement.setAdresse("123 Avenue de la République");
      evenement.setVille("Dakar");
      evenement.setRegion("Dakar");
      assertThat(evenement.getAdresseComplete())
          .isEqualTo("Centre de conférence, 123 Avenue de la République, Dakar, Dakar");

      // Adresse partielle
      evenement.setAdresse(null);
      evenement.setRegion(null);
      assertThat(evenement.getAdresseComplete()).isEqualTo("Centre de conférence, Dakar");

      // Lieu seulement
      evenement.setVille(null);
      assertThat(evenement.getAdresseComplete()).isEqualTo("Centre de conférence");

      // Aucune information
      evenement.setLieu(null);
      assertThat(evenement.getAdresseComplete()).isEmpty();
    }

    @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 méthodes budgétaires")
    void testMethodesBudgetaires() {
      // Test getEcartBudgetaire - économie
      evenement.setBudget(new BigDecimal("500000.00"));
      evenement.setCoutReel(new BigDecimal("450000.00"));
      assertThat(evenement.getEcartBudgetaire()).isEqualTo(new BigDecimal("50000.00"));
      assertThat(evenement.isBudgetDepasse()).isFalse();

      // Test getEcartBudgetaire - dépassement
      evenement.setCoutReel(new BigDecimal("550000.00"));
      assertThat(evenement.getEcartBudgetaire()).isEqualTo(new BigDecimal("-50000.00"));
      assertThat(evenement.isBudgetDepasse()).isTrue();

      // Test avec valeurs nulles
      evenement.setBudget(null);
      assertThat(evenement.getEcartBudgetaire()).isEqualTo(BigDecimal.ZERO);
      assertThat(evenement.isBudgetDepasse()).isFalse();

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

  @Test
  @DisplayName("Test toString")
  void testToString() {
    evenement.setTitre("Événement test");
    evenement.setTypeEvenement("FORMATION");
    evenement.setStatut("PLANIFIE");
    evenement.setDateDebut(LocalDate.now());
    evenement.setLieu("Salle de test");
    evenement.setParticipantsInscrits(10);
    evenement.setCapaciteMax(50);

    String result = evenement.toString();
    assertThat(result).isNotNull();
    assertThat(result).contains("EvenementDTO");
    assertThat(result).contains("titre='Événement test'");
    assertThat(result).contains("typeEvenement='FORMATION'");
    assertThat(result).contains("statut='PLANIFIE'");
    assertThat(result).contains("lieu='Salle de test'");
    assertThat(result).contains("participantsInscrits=10");
    assertThat(result).contains("capaciteMax=50");
  }

  @Test
  @DisplayName("Test branches supplémentaires getPlacesDisponibles")
  void testBranchesSupplementairesPlacesDisponibles() {
    // Test avec capaciteMax null
    evenement.setCapaciteMax(null);
    evenement.setParticipantsInscrits(10);
    assertThat(evenement.getPlacesDisponibles()).isEqualTo(0);

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

    // Test avec les deux null
    evenement.setCapaciteMax(null);
    evenement.setParticipantsInscrits(null);
    assertThat(evenement.getPlacesDisponibles()).isEqualTo(0);
  }

  @Test
  @DisplayName("Test branches supplémentaires getTauxRemplissage")
  void testBranchesSupplementairesTauxRemplissage() {
    // Test avec capaciteMax null
    evenement.setCapaciteMax(null);
    evenement.setParticipantsInscrits(10);
    assertThat(evenement.getTauxRemplissage()).isEqualTo(0);

    // Test avec capaciteMax zéro
    evenement.setCapaciteMax(0);
    evenement.setParticipantsInscrits(10);
    assertThat(evenement.getTauxRemplissage()).isEqualTo(0);

    // Test avec participantsInscrits null
    evenement.setCapaciteMax(50);
    evenement.setParticipantsInscrits(null);
    assertThat(evenement.getTauxRemplissage()).isEqualTo(0);
  }

  @Test
  @DisplayName("Test branches supplémentaires getTauxPresence")
  void testBranchesSupplementairesTauxPresence() {
    // Test avec participantsInscrits null
    evenement.setParticipantsInscrits(null);
    evenement.setParticipantsPresents(5);
    assertThat(evenement.getTauxPresence()).isEqualTo(0);

    // Test avec participantsInscrits zéro
    evenement.setParticipantsInscrits(0);
    evenement.setParticipantsPresents(5);
    assertThat(evenement.getTauxPresence()).isEqualTo(0);

    // Test avec participantsPresents null
    evenement.setParticipantsInscrits(10);
    evenement.setParticipantsPresents(null);
    assertThat(evenement.getTauxPresence()).isEqualTo(0);
  }

  @Test
  @DisplayName("Test branches supplémentaires isInscriptionsOuvertes")
  void testBranchesSupplementairesInscriptionsOuvertes() {
    // Test avec événement annulé
    evenement.setStatut("ANNULE");
    evenement.setCapaciteMax(50);
    evenement.setParticipantsInscrits(10);
    evenement.setDateLimiteInscription(LocalDate.now().plusDays(5));
    assertThat(evenement.isInscriptionsOuvertes()).isFalse();

    // Test avec événement terminé
    evenement.setStatut("TERMINE");
    assertThat(evenement.isInscriptionsOuvertes()).isFalse();

    // Test avec date limite dépassée
    evenement.setStatut("PLANIFIE");
    evenement.setDateLimiteInscription(LocalDate.now().minusDays(1));
    assertThat(evenement.isInscriptionsOuvertes()).isFalse();

    // Test avec événement complet
    evenement.setDateLimiteInscription(LocalDate.now().plusDays(5));
    evenement.setCapaciteMax(10);
    evenement.setParticipantsInscrits(10);
    assertThat(evenement.isInscriptionsOuvertes()).isFalse();
  }

  @Test
  @DisplayName("Test branches supplémentaires getDureeEnHeures")
  void testBranchesSupplementairesDureeEnHeures() {
    // Test avec heureDebut null
    evenement.setHeureDebut(null);
    evenement.setHeureFin(LocalTime.of(17, 0));
    assertThat(evenement.getDureeEnHeures()).isEqualTo(0);

    // Test avec heureFin null
    evenement.setHeureDebut(LocalTime.of(9, 0));
    evenement.setHeureFin(null);
    assertThat(evenement.getDureeEnHeures()).isEqualTo(0);

    // Test avec les deux null
    evenement.setHeureDebut(null);
    evenement.setHeureFin(null);
    assertThat(evenement.getDureeEnHeures()).isEqualTo(0);
  }

  @Test
  @DisplayName("Test branches supplémentaires getAdresseComplete")
  void testBranchesSupplementairesAdresseComplete() {
    // Test avec adresse seulement (sans lieu)
    evenement.setLieu(null);
    evenement.setAdresse("123 Avenue Test");
    evenement.setVille(null);
    evenement.setRegion(null);
    assertThat(evenement.getAdresseComplete()).isEqualTo("123 Avenue Test");

    // Test avec ville seulement (sans lieu ni adresse)
    evenement.setLieu(null);
    evenement.setAdresse(null);
    evenement.setVille("Dakar");
    evenement.setRegion(null);
    assertThat(evenement.getAdresseComplete()).isEqualTo("Dakar");

    // Test avec région seulement
    evenement.setLieu(null);
    evenement.setAdresse(null);
    evenement.setVille(null);
    evenement.setRegion("Dakar");
    assertThat(evenement.getAdresseComplete()).isEqualTo("Dakar");

    // Test avec adresse et ville (sans lieu)
    evenement.setLieu(null);
    evenement.setAdresse("123 Avenue Test");
    evenement.setVille("Dakar");
    evenement.setRegion(null);
    assertThat(evenement.getAdresseComplete()).isEqualTo("123 Avenue Test, Dakar");
  }
}
