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

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

import dev.lions.unionflow.server.api.dto.analytics.ReportConfigDTO.MetriqueConfigDTO;
import dev.lions.unionflow.server.api.dto.analytics.ReportConfigDTO.SectionRapportDTO;
import dev.lions.unionflow.server.api.enums.analytics.FormatExport;
import dev.lions.unionflow.server.api.enums.analytics.PeriodeAnalyse;
import dev.lions.unionflow.server.api.enums.analytics.TypeMetrique;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

@DisplayName("Tests pour ReportConfigDTO")
class ReportConfigDTOTest {

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

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

    @Test
    @DisplayName("Constructeur par défaut")
    void testConstructeurParDefaut() {
      ReportConfigDTO dto = new ReportConfigDTO();
      assertThat(dto).isNotNull();
      assertThat(dto.getRapportPublic()).isFalse();
      assertThat(dto.getRapportAutomatique()).isFalse();
      assertThat(dto.getNiveauConfidentialite()).isEqualTo(1);
      assertThat(dto.getNombreGenerations()).isEqualTo(0);
    }

    @Test
    @DisplayName("Builder pattern")
    void testBuilder() {
      UUID userId = UUID.randomUUID();
      List<MetriqueConfigDTO> metriques = Arrays.asList(
          MetriqueConfigDTO.builder()
              .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
              .position(1)
              .build());

      ReportConfigDTO dto = ReportConfigDTO.builder()
          .nom("Rapport Test")
          .typeRapport("executif")
          .periodeAnalyse(PeriodeAnalyse.CE_MOIS)
          .utilisateurCreateurId(userId)
          .metriques(metriques)
          .formatExport(FormatExport.PDF)
          .build();

      assertThat(dto.getNom()).isEqualTo("Rapport Test");
      assertThat(dto.getTypeRapport()).isEqualTo("executif");
      assertThat(dto.getPeriodeAnalyse()).isEqualTo(PeriodeAnalyse.CE_MOIS);
      assertThat(dto.getUtilisateurCreateurId()).isEqualTo(userId);
      assertThat(dto.getMetriques()).isEqualTo(metriques);
      assertThat(dto.getFormatExport()).isEqualTo(FormatExport.PDF);
    }
  }

  @Nested
  @DisplayName("Tests méthodes utilitaires")
  class MethodesUtilitairesTests {

    @Test
    @DisplayName("getNombreMetriques - avec métriques")
    void testGetNombreMetriquesAvecMetriques() {
      ReportConfigDTO dto = new ReportConfigDTO();
      List<MetriqueConfigDTO> metriques = Arrays.asList(
          MetriqueConfigDTO.builder().typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS).build(),
          MetriqueConfigDTO.builder().typeMetrique(TypeMetrique.NOMBRE_ORGANISATIONS_ACTIVES).build());
      dto.setMetriques(metriques);
      assertThat(dto.getNombreMetriques()).isEqualTo(2);
    }

    @Test
    @DisplayName("getNombreMetriques - sans métriques")
    void testGetNombreMetriquesSansMetriques() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setMetriques(null);
      assertThat(dto.getNombreMetriques()).isEqualTo(0);
    }

    @Test
    @DisplayName("getNombreSections - avec sections")
    void testGetNombreSectionsAvecSections() {
      ReportConfigDTO dto = new ReportConfigDTO();
      List<SectionRapportDTO> sections = Arrays.asList(
          SectionRapportDTO.builder().nom("Section 1").typeSection("resume").position(1).build(),
          SectionRapportDTO.builder().nom("Section 2").typeSection("metriques").position(2).build());
      dto.setSections(sections);
      assertThat(dto.getNombreSections()).isEqualTo(2);
    }

    @Test
    @DisplayName("getNombreSections - sans sections")
    void testGetNombreSectionsSansSections() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setSections(null);
      assertThat(dto.getNombreSections()).isEqualTo(0);
    }

    @Test
    @DisplayName("isPeriodePersonnalisee - période personnalisée")
    void testIsPeriodePersonnaliseeTrue() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setPeriodeAnalyse(PeriodeAnalyse.PERIODE_PERSONNALISEE);
      assertThat(dto.isPeriodePersonnalisee()).isTrue();
    }

    @Test
    @DisplayName("isPeriodePersonnalisee - période non personnalisée")
    void testIsPeriodePersonnaliseeFalse() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setPeriodeAnalyse(PeriodeAnalyse.CE_MOIS);
      assertThat(dto.isPeriodePersonnalisee()).isFalse();
    }

    @Test
    @DisplayName("isConfidentiel - niveau >= 4")
    void testIsConfidentielTrue() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setNiveauConfidentialite(4);
      assertThat(dto.isConfidentiel()).isTrue();
    }

    @Test
    @DisplayName("isConfidentiel - niveau < 4")
    void testIsConfidentielFalse() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setNiveauConfidentialite(3);
      assertThat(dto.isConfidentiel()).isFalse();
    }

    @Test
    @DisplayName("isConfidentiel - niveau null")
    void testIsConfidentielNull() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setNiveauConfidentialite(null);
      assertThat(dto.isConfidentiel()).isFalse();
    }

    @Test
    @DisplayName("necessiteGeneration - rapport automatique et prochaine génération passée")
    void testNecessiteGenerationTrue() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setRapportAutomatique(true);
      dto.setProchaineGeneration(LocalDateTime.now().minusHours(1));
      assertThat(dto.necessiteGeneration()).isTrue();
    }

    @Test
    @DisplayName("necessiteGeneration - rapport non automatique")
    void testNecessiteGenerationFalseNonAutomatique() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setRapportAutomatique(false);
      dto.setProchaineGeneration(LocalDateTime.now().minusHours(1));
      assertThat(dto.necessiteGeneration()).isFalse();
    }

    @Test
    @DisplayName("necessiteGeneration - prochaine génération future")
    void testNecessiteGenerationFalseFuture() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setRapportAutomatique(true);
      dto.setProchaineGeneration(LocalDateTime.now().plusHours(1));
      assertThat(dto.necessiteGeneration()).isFalse();
    }

    @Test
    @DisplayName("necessiteGeneration - prochaine génération null")
    void testNecessiteGenerationFalseNull() {
      ReportConfigDTO dto = new ReportConfigDTO();
      dto.setRapportAutomatique(true);
      dto.setProchaineGeneration(null);
      assertThat(dto.necessiteGeneration()).isFalse();
    }

    @ParameterizedTest
    @CsvSource({
        "1, Toutes les heures",
        "24, Quotidienne",
        "168, Hebdomadaire",
        "720, Mensuelle",
        "48, Toutes les 48 heures",
        "null, Manuelle"
    })
    @DisplayName("getFrequenceTexte - tous les cas")
    void testGetFrequenceTexte(String heuresStr, String expected) {
      ReportConfigDTO dto = new ReportConfigDTO();
      if ("null".equals(heuresStr)) {
        dto.setFrequenceGenerationHeures(null);
      } else {
        dto.setFrequenceGenerationHeures(Integer.parseInt(heuresStr));
      }
      assertThat(dto.getFrequenceTexte()).isEqualTo(expected);
    }
  }

  @Nested
  @DisplayName("Tests classe interne MetriqueConfigDTO")
  class MetriqueConfigDTOTests {

    @Test
    @DisplayName("Constructeur par défaut")
    void testConstructeurParDefaut() {
      MetriqueConfigDTO dto = new MetriqueConfigDTO();
      assertThat(dto).isNotNull();
      assertThat(dto.getTailleAffichage()).isEqualTo(2);
      assertThat(dto.getInclureGraphique()).isTrue();
      assertThat(dto.getTypeGraphique()).isEqualTo("line");
      assertThat(dto.getInclureTendance()).isTrue();
      assertThat(dto.getInclureComparaison()).isTrue();
    }

    @Test
    @DisplayName("Builder pattern")
    void testBuilder() {
      Map<String, Object> seuils = new HashMap<>();
      seuils.put("bas", 10.0);
      Map<String, Object> filtres = new HashMap<>();
      filtres.put("org", "org-1");

      MetriqueConfigDTO dto = MetriqueConfigDTO.builder()
          .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
          .libellePersonnalise("Membres Actifs")
          .position(1)
          .tailleAffichage(3)
          .couleurPersonnalisee("#FF0000")
          .inclureGraphique(false)
          .typeGraphique("bar")
          .inclureTendance(false)
          .inclureComparaison(false)
          .seuilsAlerte(seuils)
          .filtresSpecifiques(filtres)
          .build();

      assertThat(dto.getTypeMetrique()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getLibellePersonnalise()).isEqualTo("Membres Actifs");
      assertThat(dto.getPosition()).isEqualTo(1);
      assertThat(dto.getTailleAffichage()).isEqualTo(3);
      assertThat(dto.getCouleurPersonnalisee()).isEqualTo("#FF0000");
      assertThat(dto.getInclureGraphique()).isFalse();
      assertThat(dto.getTypeGraphique()).isEqualTo("bar");
      assertThat(dto.getInclureTendance()).isFalse();
      assertThat(dto.getInclureComparaison()).isFalse();
      assertThat(dto.getSeuilsAlerte()).isEqualTo(seuils);
      assertThat(dto.getFiltresSpecifiques()).isEqualTo(filtres);
    }

    @Test
    @DisplayName("Getters/setters")
    void testGettersSetters() {
      MetriqueConfigDTO dto = new MetriqueConfigDTO();
      Map<String, Object> seuils = new HashMap<>();
      Map<String, Object> filtres = new HashMap<>();

      dto.setTypeMetrique(TypeMetrique.NOMBRE_ORGANISATIONS_ACTIVES);
      dto.setLibellePersonnalise("Organisations");
      dto.setPosition(2);
      dto.setTailleAffichage(1);
      dto.setCouleurPersonnalisee("#00FF00");
      dto.setInclureGraphique(true);
      dto.setTypeGraphique("pie");
      dto.setInclureTendance(true);
      dto.setInclureComparaison(true);
      dto.setSeuilsAlerte(seuils);
      dto.setFiltresSpecifiques(filtres);

      assertThat(dto.getTypeMetrique()).isEqualTo(TypeMetrique.NOMBRE_ORGANISATIONS_ACTIVES);
      assertThat(dto.getLibellePersonnalise()).isEqualTo("Organisations");
      assertThat(dto.getPosition()).isEqualTo(2);
      assertThat(dto.getTailleAffichage()).isEqualTo(1);
      assertThat(dto.getCouleurPersonnalisee()).isEqualTo("#00FF00");
      assertThat(dto.getInclureGraphique()).isTrue();
      assertThat(dto.getTypeGraphique()).isEqualTo("pie");
      assertThat(dto.getInclureTendance()).isTrue();
      assertThat(dto.getInclureComparaison()).isTrue();
      assertThat(dto.getSeuilsAlerte()).isEqualTo(seuils);
      assertThat(dto.getFiltresSpecifiques()).isEqualTo(filtres);
    }
  }

  @Nested
  @DisplayName("Tests classe interne SectionRapportDTO")
  class SectionRapportDTOTests {

    @Test
    @DisplayName("Constructeur par défaut")
    void testConstructeurParDefaut() {
      SectionRapportDTO dto = new SectionRapportDTO();
      assertThat(dto).isNotNull();
      assertThat(dto.getVisible()).isTrue();
      assertThat(dto.getPliable()).isFalse();
    }

    @Test
    @DisplayName("Builder pattern")
    void testBuilder() {
      List<TypeMetrique> metriques = Arrays.asList(
          TypeMetrique.NOMBRE_MEMBRES_ACTIFS,
          TypeMetrique.NOMBRE_ORGANISATIONS_ACTIVES);
      Map<String, Object> config = new HashMap<>();
      config.put("key", "value");

      SectionRapportDTO dto = SectionRapportDTO.builder()
          .nom("Section Résumé")
          .description("Description de la section")
          .position(1)
          .typeSection("resume")
          .metriquesIncluses(metriques)
          .configurationSection(config)
          .visible(true)
          .pliable(true)
          .build();

      assertThat(dto.getNom()).isEqualTo("Section Résumé");
      assertThat(dto.getDescription()).isEqualTo("Description de la section");
      assertThat(dto.getPosition()).isEqualTo(1);
      assertThat(dto.getTypeSection()).isEqualTo("resume");
      assertThat(dto.getMetriquesIncluses()).isEqualTo(metriques);
      assertThat(dto.getConfigurationSection()).isEqualTo(config);
      assertThat(dto.getVisible()).isTrue();
      assertThat(dto.getPliable()).isTrue();
    }

    @Test
    @DisplayName("Getters/setters")
    void testGettersSetters() {
      SectionRapportDTO dto = new SectionRapportDTO();
      List<TypeMetrique> metriques = Arrays.asList(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      Map<String, Object> config = new HashMap<>();

      dto.setNom("Section Test");
      dto.setDescription("Description test");
      dto.setPosition(2);
      dto.setTypeSection("metriques");
      dto.setMetriquesIncluses(metriques);
      dto.setConfigurationSection(config);
      dto.setVisible(false);
      dto.setPliable(true);

      assertThat(dto.getNom()).isEqualTo("Section Test");
      assertThat(dto.getDescription()).isEqualTo("Description test");
      assertThat(dto.getPosition()).isEqualTo(2);
      assertThat(dto.getTypeSection()).isEqualTo("metriques");
      assertThat(dto.getMetriquesIncluses()).isEqualTo(metriques);
      assertThat(dto.getConfigurationSection()).isEqualTo(config);
      assertThat(dto.getVisible()).isFalse();
      assertThat(dto.getPliable()).isTrue();
    }
  }

  @Nested
  @DisplayName("Tests getters/setters complets")
  class GettersSettersCompletsTests {

    @Test
    @DisplayName("Test tous les getters/setters")
    void testTousLesGettersSetters() {
      ReportConfigDTO dto = new ReportConfigDTO();
      UUID orgId = UUID.randomUUID();
      UUID userId = UUID.randomUUID();
      List<MetriqueConfigDTO> metriques = Arrays.asList(
          MetriqueConfigDTO.builder()
              .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
              .position(1)
              .build());
      List<SectionRapportDTO> sections = Arrays.asList(
          SectionRapportDTO.builder()
              .nom("Section 1")
              .typeSection("resume")
              .position(1)
              .build());
      List<FormatExport> formats = Arrays.asList(FormatExport.PDF, FormatExport.EXCEL);
      Map<String, String> couleurs = new HashMap<>();
      couleurs.put("primary", "#FF0000");
      List<String> destinataires = Arrays.asList("email1@test.com", "email2@test.com");
      Map<String, Object> filtres = new HashMap<>();
      filtres.put("key", "value");
      List<String> tags = Arrays.asList("tag1", "tag2");

      dto.setNom("Rapport Complet");
      dto.setDescription("Description complète");
      dto.setTypeRapport("analytique");
      dto.setPeriodeAnalyse(PeriodeAnalyse.CE_MOIS);
      dto.setDateDebutPersonnalisee(LocalDateTime.of(2025, 1, 1, 0, 0));
      dto.setDateFinPersonnalisee(LocalDateTime.of(2025, 1, 31, 23, 59));
      dto.setOrganisationId(orgId);
      dto.setNomOrganisation("Org Test");
      dto.setUtilisateurCreateurId(userId);
      dto.setNomUtilisateurCreateur("User Test");
      dto.setMetriques(metriques);
      dto.setSections(sections);
      dto.setFormatExport(FormatExport.PDF);
      dto.setFormatsExportAutorises(formats);
      dto.setModeleRapport("modele1");
      dto.setConfigurationMiseEnPage("config");
      dto.setLogoPersonnalise("logo.png");
      dto.setCouleursPersonnalisees(couleurs);
      dto.setRapportPublic(true);
      dto.setRapportAutomatique(true);
      dto.setFrequenceGenerationHeures(24);
      dto.setProchaineGeneration(LocalDateTime.now().plusHours(24));
      dto.setDestinatairesEmail(destinataires);
      dto.setObjetEmail("Rapport automatique");
      dto.setCorpsEmail("Corps du rapport");
      dto.setParametresFiltrage(filtres);
      dto.setTags(tags);
      dto.setNiveauConfidentialite(3);
      dto.setDateDerniereGeneration(LocalDateTime.now().minusHours(1));
      dto.setNombreGenerations(10);
      dto.setTailleMoyenneKB(500L);
      dto.setTempsMoyenGenerationSecondes(30);

      assertThat(dto.getNom()).isEqualTo("Rapport Complet");
      assertThat(dto.getDescription()).isEqualTo("Description complète");
      assertThat(dto.getTypeRapport()).isEqualTo("analytique");
      assertThat(dto.getPeriodeAnalyse()).isEqualTo(PeriodeAnalyse.CE_MOIS);
      assertThat(dto.getDateDebutPersonnalisee()).isNotNull();
      assertThat(dto.getDateFinPersonnalisee()).isNotNull();
      assertThat(dto.getOrganisationId()).isEqualTo(orgId);
      assertThat(dto.getNomOrganisation()).isEqualTo("Org Test");
      assertThat(dto.getUtilisateurCreateurId()).isEqualTo(userId);
      assertThat(dto.getNomUtilisateurCreateur()).isEqualTo("User Test");
      assertThat(dto.getMetriques()).isEqualTo(metriques);
      assertThat(dto.getSections()).isEqualTo(sections);
      assertThat(dto.getFormatExport()).isEqualTo(FormatExport.PDF);
      assertThat(dto.getFormatsExportAutorises()).isEqualTo(formats);
      assertThat(dto.getModeleRapport()).isEqualTo("modele1");
      assertThat(dto.getConfigurationMiseEnPage()).isEqualTo("config");
      assertThat(dto.getLogoPersonnalise()).isEqualTo("logo.png");
      assertThat(dto.getCouleursPersonnalisees()).isEqualTo(couleurs);
      assertThat(dto.getRapportPublic()).isTrue();
      assertThat(dto.getRapportAutomatique()).isTrue();
      assertThat(dto.getFrequenceGenerationHeures()).isEqualTo(24);
      assertThat(dto.getProchaineGeneration()).isNotNull();
      assertThat(dto.getDestinatairesEmail()).isEqualTo(destinataires);
      assertThat(dto.getObjetEmail()).isEqualTo("Rapport automatique");
      assertThat(dto.getCorpsEmail()).isEqualTo("Corps du rapport");
      assertThat(dto.getParametresFiltrage()).isEqualTo(filtres);
      assertThat(dto.getTags()).isEqualTo(tags);
      assertThat(dto.getNiveauConfidentialite()).isEqualTo(3);
      assertThat(dto.getDateDerniereGeneration()).isNotNull();
      assertThat(dto.getNombreGenerations()).isEqualTo(10);
      assertThat(dto.getTailleMoyenneKB()).isEqualTo(500L);
      assertThat(dto.getTempsMoyenGenerationSecondes()).isEqualTo(30);
    }
  }

  @Nested
  @DisplayName("Tests Builder complet - tous les champs")
  class BuilderCompletTests {

    @Test
    @DisplayName("Builder - tous les champs")
    void testBuilderTousChamps() {
      UUID orgId = UUID.randomUUID();
      UUID userId = UUID.randomUUID();
      List<MetriqueConfigDTO> metriques = Arrays.asList(
          MetriqueConfigDTO.builder()
              .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
              .position(1)
              .build());
      List<SectionRapportDTO> sections = Arrays.asList(
          SectionRapportDTO.builder()
              .nom("Section 1")
              .typeSection("resume")
              .position(1)
              .build());
      List<FormatExport> formats = Arrays.asList(FormatExport.PDF, FormatExport.EXCEL);
      Map<String, String> couleurs = new HashMap<>();
      couleurs.put("primary", "#FF0000");
      List<String> destinataires = Arrays.asList("email1@test.com", "email2@test.com");
      Map<String, Object> filtres = new HashMap<>();
      filtres.put("key", "value");
      List<String> tags = Arrays.asList("tag1", "tag2");

      ReportConfigDTO dto = ReportConfigDTO.builder()
          .nom("Rapport Complet")
          .description("Description complète")
          .typeRapport("analytique")
          .periodeAnalyse(PeriodeAnalyse.CE_MOIS)
          .dateDebutPersonnalisee(LocalDateTime.of(2025, 1, 1, 0, 0))
          .dateFinPersonnalisee(LocalDateTime.of(2025, 1, 31, 23, 59))
          .organisationId(orgId)
          .nomOrganisation("Org Test")
          .utilisateurCreateurId(userId)
          .nomUtilisateurCreateur("User Test")
          .metriques(metriques)
          .sections(sections)
          .formatExport(FormatExport.PDF)
          .formatsExportAutorises(formats)
          .modeleRapport("modele1")
          .configurationMiseEnPage("config")
          .logoPersonnalise("logo.png")
          .couleursPersonnalisees(couleurs)
          .rapportPublic(true)
          .rapportAutomatique(true)
          .frequenceGenerationHeures(24)
          .prochaineGeneration(LocalDateTime.now().plusHours(24))
          .destinatairesEmail(destinataires)
          .objetEmail("Rapport automatique")
          .corpsEmail("Corps du rapport")
          .parametresFiltrage(filtres)
          .tags(tags)
          .niveauConfidentialite(3)
          .dateDerniereGeneration(LocalDateTime.now().minusHours(1))
          .nombreGenerations(10)
          .tailleMoyenneKB(500L)
          .tempsMoyenGenerationSecondes(30)
          .build();

      assertThat(dto.getNom()).isEqualTo("Rapport Complet");
      assertThat(dto.getDescription()).isEqualTo("Description complète");
      assertThat(dto.getTypeRapport()).isEqualTo("analytique");
      assertThat(dto.getPeriodeAnalyse()).isEqualTo(PeriodeAnalyse.CE_MOIS);
      assertThat(dto.getDateDebutPersonnalisee()).isNotNull();
      assertThat(dto.getDateFinPersonnalisee()).isNotNull();
      assertThat(dto.getOrganisationId()).isEqualTo(orgId);
      assertThat(dto.getNomOrganisation()).isEqualTo("Org Test");
      assertThat(dto.getUtilisateurCreateurId()).isEqualTo(userId);
      assertThat(dto.getNomUtilisateurCreateur()).isEqualTo("User Test");
      assertThat(dto.getMetriques()).isEqualTo(metriques);
      assertThat(dto.getSections()).isEqualTo(sections);
      assertThat(dto.getFormatExport()).isEqualTo(FormatExport.PDF);
      assertThat(dto.getFormatsExportAutorises()).isEqualTo(formats);
      assertThat(dto.getModeleRapport()).isEqualTo("modele1");
      assertThat(dto.getConfigurationMiseEnPage()).isEqualTo("config");
      assertThat(dto.getLogoPersonnalise()).isEqualTo("logo.png");
      assertThat(dto.getCouleursPersonnalisees()).isEqualTo(couleurs);
      assertThat(dto.getRapportPublic()).isTrue();
      assertThat(dto.getRapportAutomatique()).isTrue();
      assertThat(dto.getFrequenceGenerationHeures()).isEqualTo(24);
      assertThat(dto.getProchaineGeneration()).isNotNull();
      assertThat(dto.getDestinatairesEmail()).isEqualTo(destinataires);
      assertThat(dto.getObjetEmail()).isEqualTo("Rapport automatique");
      assertThat(dto.getCorpsEmail()).isEqualTo("Corps du rapport");
      assertThat(dto.getParametresFiltrage()).isEqualTo(filtres);
      assertThat(dto.getTags()).isEqualTo(tags);
      assertThat(dto.getNiveauConfidentialite()).isEqualTo(3);
      assertThat(dto.getDateDerniereGeneration()).isNotNull();
      assertThat(dto.getNombreGenerations()).isEqualTo(10);
      assertThat(dto.getTailleMoyenneKB()).isEqualTo(500L);
      assertThat(dto.getTempsMoyenGenerationSecondes()).isEqualTo(30);
    }

    @Test
    @DisplayName("Builder - valeurs par défaut")
    void testBuilderValeursParDefaut() {
      UUID userId = UUID.randomUUID();
      List<MetriqueConfigDTO> metriques = Arrays.asList(
          MetriqueConfigDTO.builder()
              .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
              .position(1)
              .build());

      ReportConfigDTO dto = ReportConfigDTO.builder()
          .nom("Rapport")
          .typeRapport("executif")
          .periodeAnalyse(PeriodeAnalyse.CE_MOIS)
          .utilisateurCreateurId(userId)
          .metriques(metriques)
          .formatExport(FormatExport.PDF)
          .build();

      assertThat(dto.getRapportPublic()).isFalse();
      assertThat(dto.getRapportAutomatique()).isFalse();
      assertThat(dto.getNiveauConfidentialite()).isEqualTo(1);
      assertThat(dto.getNombreGenerations()).isEqualTo(0);
    }

    @Test
    @DisplayName("MetriqueConfigDTO.Builder - tous les champs")
    void testMetriqueConfigDTOBuilderTousChamps() {
      Map<String, Object> seuils = new HashMap<>();
      seuils.put("bas", 10.0);
      Map<String, Object> filtres = new HashMap<>();
      filtres.put("org", "org-1");

      MetriqueConfigDTO dto = MetriqueConfigDTO.builder()
          .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
          .libellePersonnalise("Membres Actifs")
          .position(1)
          .tailleAffichage(3)
          .couleurPersonnalisee("#FF0000")
          .inclureGraphique(false)
          .typeGraphique("bar")
          .inclureTendance(false)
          .inclureComparaison(false)
          .seuilsAlerte(seuils)
          .filtresSpecifiques(filtres)
          .build();

      assertThat(dto.getTypeMetrique()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getLibellePersonnalise()).isEqualTo("Membres Actifs");
      assertThat(dto.getPosition()).isEqualTo(1);
      assertThat(dto.getTailleAffichage()).isEqualTo(3);
      assertThat(dto.getCouleurPersonnalisee()).isEqualTo("#FF0000");
      assertThat(dto.getInclureGraphique()).isFalse();
      assertThat(dto.getTypeGraphique()).isEqualTo("bar");
      assertThat(dto.getInclureTendance()).isFalse();
      assertThat(dto.getInclureComparaison()).isFalse();
      assertThat(dto.getSeuilsAlerte()).isEqualTo(seuils);
      assertThat(dto.getFiltresSpecifiques()).isEqualTo(filtres);
    }

    @Test
    @DisplayName("MetriqueConfigDTO.Builder - valeurs par défaut")
    void testMetriqueConfigDTOBuilderValeursParDefaut() {
      MetriqueConfigDTO dto = MetriqueConfigDTO.builder()
          .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
          .position(1)
          .build();

      assertThat(dto.getTailleAffichage()).isEqualTo(2);
      assertThat(dto.getInclureGraphique()).isTrue();
      assertThat(dto.getTypeGraphique()).isEqualTo("line");
      assertThat(dto.getInclureTendance()).isTrue();
      assertThat(dto.getInclureComparaison()).isTrue();
    }

    @Test
    @DisplayName("SectionRapportDTO.Builder - tous les champs")
    void testSectionRapportDTOBuilderTousChamps() {
      List<TypeMetrique> metriques = Arrays.asList(
          TypeMetrique.NOMBRE_MEMBRES_ACTIFS,
          TypeMetrique.NOMBRE_ORGANISATIONS_ACTIVES);
      Map<String, Object> config = new HashMap<>();
      config.put("key", "value");

      SectionRapportDTO dto = SectionRapportDTO.builder()
          .nom("Section Résumé")
          .description("Description de la section")
          .position(1)
          .typeSection("resume")
          .metriquesIncluses(metriques)
          .configurationSection(config)
          .visible(true)
          .pliable(true)
          .build();

      assertThat(dto.getNom()).isEqualTo("Section Résumé");
      assertThat(dto.getDescription()).isEqualTo("Description de la section");
      assertThat(dto.getPosition()).isEqualTo(1);
      assertThat(dto.getTypeSection()).isEqualTo("resume");
      assertThat(dto.getMetriquesIncluses()).isEqualTo(metriques);
      assertThat(dto.getConfigurationSection()).isEqualTo(config);
      assertThat(dto.getVisible()).isTrue();
      assertThat(dto.getPliable()).isTrue();
    }

    @Test
    @DisplayName("SectionRapportDTO.Builder - valeurs par défaut")
    void testSectionRapportDTOBuilderValeursParDefaut() {
      SectionRapportDTO dto = SectionRapportDTO.builder()
          .nom("Section")
          .typeSection("resume")
          .position(1)
          .build();

      assertThat(dto.getVisible()).isTrue();
      assertThat(dto.getPliable()).isFalse();
    }


  }
}

