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

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

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.HashMap;
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;
import org.junit.jupiter.params.provider.ValueSource;

@DisplayName("Tests pour DashboardWidgetDTO")
class DashboardWidgetDTOTest {

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

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

    @Test
    @DisplayName("Constructeur par défaut")
    void testConstructeurParDefaut() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();

      assertThat(dto).isNotNull();
      assertThat(dto.getOrdreAffichage()).isEqualTo(0);
      assertThat(dto.getVisible()).isTrue();
      assertThat(dto.getRedimensionnable()).isTrue();
      assertThat(dto.getDeplacable()).isTrue();
      assertThat(dto.getSupprimable()).isTrue();
      assertThat(dto.getMiseAJourAutomatique()).isTrue();
      assertThat(dto.getFrequenceMiseAJourSecondes()).isEqualTo(300);
      assertThat(dto.getAlerteActive()).isFalse();
      assertThat(dto.getNombreVues()).isEqualTo(0L);
      assertThat(dto.getNombreInteractions()).isEqualTo(0L);
      assertThat(dto.getTauxErreur()).isEqualTo(0.0);
    }

    @Test
    @DisplayName("Builder pattern")
    void testBuilder() {
      UUID userId = UUID.randomUUID();
      DashboardWidgetDTO dto = DashboardWidgetDTO.builder()
          .titre("Widget Test")
          .typeWidget("kpi")
          .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
          .utilisateurProprietaireId(userId)
          .positionX(0)
          .positionY(0)
          .largeur(4)
          .hauteur(2)
          .build();

      assertThat(dto.getTitre()).isEqualTo("Widget Test");
      assertThat(dto.getTypeWidget()).isEqualTo("kpi");
      assertThat(dto.getTypeMetrique()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getUtilisateurProprietaireId()).isEqualTo(userId);
      assertThat(dto.getPositionX()).isEqualTo(0);
      assertThat(dto.getPositionY()).isEqualTo(0);
      assertThat(dto.getLargeur()).isEqualTo(4);
      assertThat(dto.getHauteur()).isEqualTo(2);
    }
  }

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

    @Test
    @DisplayName("getLibelleMetrique - avec typeMetrique")
    void testGetLibelleMetriqueAvecType() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getLibelleMetrique()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS.getLibelle());
    }

    @Test
    @DisplayName("getLibelleMetrique - sans typeMetrique")
    void testGetLibelleMetriqueSansType() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setTypeMetrique(null);
      assertThat(dto.getLibelleMetrique()).isNull();
    }

    @Test
    @DisplayName("getUnite - avec typeMetrique")
    void testGetUniteAvecType() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getUnite()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS.getUnite());
    }

    @Test
    @DisplayName("getUnite - sans typeMetrique")
    void testGetUniteSansType() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setTypeMetrique(null);
      assertThat(dto.getUnite()).isEmpty();
    }

    @Test
    @DisplayName("getIconeAffichage - avec icône personnalisée")
    void testGetIconeAffichagePersonnalisee() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setIcone("custom_icon");
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getIconeAffichage()).isEqualTo("custom_icon");
    }

    @Test
    @DisplayName("getIconeAffichage - avec typeMetrique")
    void testGetIconeAffichageAvecType() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setIcone(null);
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getIconeAffichage()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS.getIcone());
    }

    @Test
    @DisplayName("getIconeAffichage - sans icône ni type")
    void testGetIconeAffichageParDefaut() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setIcone(null);
      dto.setTypeMetrique(null);
      assertThat(dto.getIconeAffichage()).isEqualTo("dashboard");
    }

    @Test
    @DisplayName("getIconeAffichage - icône vide (trim)")
    void testGetIconeAffichageIconeVide() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setIcone("   ");
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getIconeAffichage()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS.getIcone());
    }

    @Test
    @DisplayName("getCouleurAffichage - avec couleur personnalisée")
    void testGetCouleurAffichagePersonnalisee() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setCouleurPrincipale("#FF0000");
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getCouleurAffichage()).isEqualTo("#FF0000");
    }

    @Test
    @DisplayName("getCouleurAffichage - avec typeMetrique")
    void testGetCouleurAffichageAvecType() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setCouleurPrincipale(null);
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getCouleurAffichage()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS.getCouleur());
    }

    @Test
    @DisplayName("getCouleurAffichage - sans couleur ni type")
    void testGetCouleurAffichageParDefaut() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setCouleurPrincipale(null);
      dto.setTypeMetrique(null);
      assertThat(dto.getCouleurAffichage()).isEqualTo("#757575");
    }

    @Test
    @DisplayName("getCouleurAffichage - couleur vide (trim)")
    void testGetCouleurAffichageCouleurVide() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setCouleurPrincipale("   ");
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getCouleurAffichage()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS.getCouleur());
    }

    @Test
    @DisplayName("necessiteMiseAJour - mise à jour automatique et prochaine mise à jour passée")
    void testNecessiteMiseAJourTrue() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setMiseAJourAutomatique(true);
      dto.setProchaineMiseAJour(LocalDateTime.now().minusMinutes(1));
      assertThat(dto.necessiteMiseAJour()).isTrue();
    }

    @Test
    @DisplayName("necessiteMiseAJour - mise à jour automatique désactivée")
    void testNecessiteMiseAJourFalseDesactivee() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setMiseAJourAutomatique(false);
      dto.setProchaineMiseAJour(LocalDateTime.now().minusMinutes(1));
      assertThat(dto.necessiteMiseAJour()).isFalse();
    }

    @Test
    @DisplayName("necessiteMiseAJour - prochaine mise à jour future")
    void testNecessiteMiseAJourFalseFuture() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setMiseAJourAutomatique(true);
      dto.setProchaineMiseAJour(LocalDateTime.now().plusMinutes(1));
      assertThat(dto.necessiteMiseAJour()).isFalse();
    }

    @Test
    @DisplayName("necessiteMiseAJour - prochaine mise à jour null")
    void testNecessiteMiseAJourFalseNull() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setMiseAJourAutomatique(true);
      dto.setProchaineMiseAJour(null);
      assertThat(dto.necessiteMiseAJour()).isFalse();
    }

    @ParameterizedTest
    @CsvSource({
        "chart, true",
        "table, true",
        "gauge, true",
        "kpi, false",
        "text, false",
        "progress, false"
    })
    @DisplayName("isInteractif - tous les types")
    void testIsInteractif(String typeWidget, boolean expected) {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setTypeWidget(typeWidget);
      assertThat(dto.isInteractif()).isEqualTo(expected);
    }

    @Test
    @DisplayName("isTempsReel - fréquence <= 60 secondes")
    void testIsTempsReelTrue() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setFrequenceMiseAJourSecondes(30);
      assertThat(dto.isTempsReel()).isTrue();
    }

    @Test
    @DisplayName("isTempsReel - fréquence > 60 secondes")
    void testIsTempsReelFalse() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setFrequenceMiseAJourSecondes(300);
      assertThat(dto.isTempsReel()).isFalse();
    }

    @Test
    @DisplayName("isTempsReel - fréquence null")
    void testIsTempsReelNull() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setFrequenceMiseAJourSecondes(null);
      assertThat(dto.isTempsReel()).isFalse();
    }

    @Test
    @DisplayName("getTailleWidget - calcul correct")
    void testGetTailleWidget() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setLargeur(4);
      dto.setHauteur(3);
      assertThat(dto.getTailleWidget()).isEqualTo(12);
    }

    @Test
    @DisplayName("isWidgetGrand - taille > 6")
    void testIsWidgetGrandTrue() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setLargeur(4);
      dto.setHauteur(2);
      assertThat(dto.isWidgetGrand()).isTrue();
    }

    @Test
    @DisplayName("isWidgetGrand - taille <= 6")
    void testIsWidgetGrandFalse() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setLargeur(2);
      dto.setHauteur(2);
      assertThat(dto.isWidgetGrand()).isFalse();
    }

    @Test
    @DisplayName("hasErreursRecentes - erreur < 24h")
    void testHasErreursRecentesTrue() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setDateDerniereErreur(LocalDateTime.now().minusHours(12));
      assertThat(dto.hasErreursRecentes()).isTrue();
    }

    @Test
    @DisplayName("hasErreursRecentes - erreur > 24h")
    void testHasErreursRecentesFalse() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setDateDerniereErreur(LocalDateTime.now().minusHours(25));
      assertThat(dto.hasErreursRecentes()).isFalse();
    }

    @Test
    @DisplayName("hasErreursRecentes - date null")
    void testHasErreursRecentesNull() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setDateDerniereErreur(null);
      assertThat(dto.hasErreursRecentes()).isFalse();
    }

    @ParameterizedTest
    @CsvSource({
        "true, true, 5.0, erreur",
        "false, false, 5.0, inactif",
        "false, true, 15.0, maintenance",
        "false, true, 5.0, actif"
    })
    @DisplayName("getStatutWidget - tous les cas")
    void testGetStatutWidget(boolean hasErreursRecentes, boolean visible, double tauxErreur,
        String expected) {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      if (hasErreursRecentes) {
        dto.setDateDerniereErreur(LocalDateTime.now().minusHours(12));
      } else {
        dto.setDateDerniereErreur(LocalDateTime.now().minusHours(25)); // Plus de 24h pour être sûr
      }
      dto.setVisible(visible);
      dto.setTauxErreur(tauxErreur);
      assertThat(dto.getStatutWidget()).isEqualTo(expected);
    }

    @Test
    @DisplayName("getStatutWidget - tauxErreur exactement 10.0")
    void testGetStatutWidgetTauxErreurExactement10() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setDateDerniereErreur(LocalDateTime.now().minusHours(25)); // Pas d'erreurs récentes
      dto.setVisible(true);
      dto.setTauxErreur(10.0);
      // tauxErreur > 10.0 est false, donc devrait retourner "actif"
      assertThat(dto.getStatutWidget()).isEqualTo("actif");
    }

    @Test
    @DisplayName("getStatutWidget - tauxErreur null (via setter)")
    void testGetStatutWidgetTauxErreurNull() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setDateDerniereErreur(LocalDateTime.now().minusHours(25)); // Pas d'erreurs récentes
      dto.setVisible(true);
      dto.setTauxErreur(null);
      // Si tauxErreur est null, la condition tauxErreur > 10.0 est fausse, donc devrait retourner "actif"
      assertThat(dto.getStatutWidget()).isEqualTo("actif");
    }

    @Test
    @DisplayName("getStatutWidget - tauxErreur exactement 10.0 (limite)")
    void testGetStatutWidgetTauxErreurExactement10Limite() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setDateDerniereErreur(LocalDateTime.now().minusHours(25)); // Pas d'erreurs récentes
      dto.setVisible(true);
      dto.setTauxErreur(10.0);
      // tauxErreur > 10.0 est false (10.0 n'est pas > 10.0), donc devrait retourner "actif"
      assertThat(dto.getStatutWidget()).isEqualTo("actif");
    }

    @Test
    @DisplayName("getStatutWidget - tauxErreur 10.1 (juste au-dessus)")
    void testGetStatutWidgetTauxErreurJusteAuDessus() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      dto.setDateDerniereErreur(LocalDateTime.now().minusHours(25)); // Pas d'erreurs récentes
      dto.setVisible(true);
      dto.setTauxErreur(10.1);
      // tauxErreur > 10.0 est true, donc devrait retourner "maintenance"
      assertThat(dto.getStatutWidget()).isEqualTo("maintenance");
    }
  }

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

    @Test
    @DisplayName("Test tous les getters/setters")
    void testTousLesGettersSetters() {
      DashboardWidgetDTO dto = new DashboardWidgetDTO();
      UUID orgId = UUID.randomUUID();
      UUID userId = UUID.randomUUID();
      Map<String, Object> filtres = new HashMap<>();
      filtres.put("key", "value");
      Map<String, Object> alertes = new HashMap<>();
      alertes.put("alert", "config");
      Map<String, Object> metadonnees = new HashMap<>();
      metadonnees.put("meta", "data");

      dto.setTitre("Titre Widget");
      dto.setDescription("Description");
      dto.setTypeWidget("kpi");
      dto.setTypeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      dto.setPeriodeAnalyse(PeriodeAnalyse.CE_MOIS);
      dto.setOrganisationId(orgId);
      dto.setNomOrganisation("Org Test");
      dto.setUtilisateurProprietaireId(userId);
      dto.setNomUtilisateurProprietaire("User Test");
      dto.setPositionX(1);
      dto.setPositionY(2);
      dto.setLargeur(4);
      dto.setHauteur(3);
      dto.setOrdreAffichage(1);
      dto.setConfigurationVisuelle("config");
      dto.setCouleurPrincipale("#FF0000");
      dto.setCouleurSecondaire("#00FF00");
      dto.setIcone("icon");
      dto.setVisible(false);
      dto.setRedimensionnable(false);
      dto.setDeplacable(false);
      dto.setSupprimable(false);
      dto.setMiseAJourAutomatique(false);
      dto.setFrequenceMiseAJourSecondes(60);
      dto.setDateDerniereMiseAJour(LocalDateTime.now());
      dto.setProchaineMiseAJour(LocalDateTime.now().plusHours(1));
      dto.setDonneesWidget("data");
      dto.setConfigurationFiltres(filtres);
      dto.setConfigurationAlertes(alertes);
      dto.setSeuilAlerteBas(10.0);
      dto.setSeuilAlerteHaut(90.0);
      dto.setAlerteActive(true);
      dto.setMessageAlerte("Alerte");
      dto.setTypeAlerte("warning");
      dto.setPermissions("read");
      dto.setRolesAutorises("ADMIN");
      dto.setTemplatePersonnalise("template");
      dto.setCssPersonnalise("css");
      dto.setJavascriptPersonnalise("js");
      dto.setMetadonnees(metadonnees);
      dto.setNombreVues(100L);
      dto.setNombreInteractions(50L);
      dto.setTempsMoyenSecondes(30);
      dto.setTauxErreur(5.0);
      dto.setDateDerniereErreur(LocalDateTime.now().minusHours(1));
      dto.setMessageDerniereErreur("Erreur");

      assertThat(dto.getTitre()).isEqualTo("Titre Widget");
      assertThat(dto.getDescription()).isEqualTo("Description");
      assertThat(dto.getTypeWidget()).isEqualTo("kpi");
      assertThat(dto.getTypeMetrique()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getPeriodeAnalyse()).isEqualTo(PeriodeAnalyse.CE_MOIS);
      assertThat(dto.getOrganisationId()).isEqualTo(orgId);
      assertThat(dto.getNomOrganisation()).isEqualTo("Org Test");
      assertThat(dto.getUtilisateurProprietaireId()).isEqualTo(userId);
      assertThat(dto.getNomUtilisateurProprietaire()).isEqualTo("User Test");
      assertThat(dto.getPositionX()).isEqualTo(1);
      assertThat(dto.getPositionY()).isEqualTo(2);
      assertThat(dto.getLargeur()).isEqualTo(4);
      assertThat(dto.getHauteur()).isEqualTo(3);
      assertThat(dto.getOrdreAffichage()).isEqualTo(1);
      assertThat(dto.getConfigurationVisuelle()).isEqualTo("config");
      assertThat(dto.getCouleurPrincipale()).isEqualTo("#FF0000");
      assertThat(dto.getCouleurSecondaire()).isEqualTo("#00FF00");
      assertThat(dto.getIcone()).isEqualTo("icon");
      assertThat(dto.getVisible()).isFalse();
      assertThat(dto.getRedimensionnable()).isFalse();
      assertThat(dto.getDeplacable()).isFalse();
      assertThat(dto.getSupprimable()).isFalse();
      assertThat(dto.getMiseAJourAutomatique()).isFalse();
      assertThat(dto.getFrequenceMiseAJourSecondes()).isEqualTo(60);
      assertThat(dto.getDateDerniereMiseAJour()).isNotNull();
      assertThat(dto.getProchaineMiseAJour()).isNotNull();
      assertThat(dto.getDonneesWidget()).isEqualTo("data");
      assertThat(dto.getConfigurationFiltres()).isEqualTo(filtres);
      assertThat(dto.getConfigurationAlertes()).isEqualTo(alertes);
      assertThat(dto.getSeuilAlerteBas()).isEqualTo(10.0);
      assertThat(dto.getSeuilAlerteHaut()).isEqualTo(90.0);
      assertThat(dto.getAlerteActive()).isTrue();
      assertThat(dto.getMessageAlerte()).isEqualTo("Alerte");
      assertThat(dto.getTypeAlerte()).isEqualTo("warning");
      assertThat(dto.getPermissions()).isEqualTo("read");
      assertThat(dto.getRolesAutorises()).isEqualTo("ADMIN");
      assertThat(dto.getTemplatePersonnalise()).isEqualTo("template");
      assertThat(dto.getCssPersonnalise()).isEqualTo("css");
      assertThat(dto.getJavascriptPersonnalise()).isEqualTo("js");
      assertThat(dto.getMetadonnees()).isEqualTo(metadonnees);
      assertThat(dto.getNombreVues()).isEqualTo(100L);
      assertThat(dto.getNombreInteractions()).isEqualTo(50L);
      assertThat(dto.getTempsMoyenSecondes()).isEqualTo(30);
      assertThat(dto.getTauxErreur()).isEqualTo(5.0);
      assertThat(dto.getDateDerniereErreur()).isNotNull();
      assertThat(dto.getMessageDerniereErreur()).isEqualTo("Erreur");
    }
  }

  @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();
      LocalDateTime now = LocalDateTime.now();
      Map<String, Object> filtres = new HashMap<>();
      filtres.put("key", "value");
      Map<String, Object> alertes = new HashMap<>();
      alertes.put("alert", "config");
      Map<String, Object> metadonnees = new HashMap<>();
      metadonnees.put("meta", "data");

      DashboardWidgetDTO dto = DashboardWidgetDTO.builder()
          .titre("Widget Test Complet")
          .description("Description complète")
          .typeWidget("kpi")
          .typeMetrique(TypeMetrique.NOMBRE_MEMBRES_ACTIFS)
          .periodeAnalyse(PeriodeAnalyse.CE_MOIS)
          .organisationId(orgId)
          .nomOrganisation("Org Test")
          .utilisateurProprietaireId(userId)
          .nomUtilisateurProprietaire("User Test")
          .positionX(1)
          .positionY(2)
          .largeur(4)
          .hauteur(3)
          .ordreAffichage(1)
          .configurationVisuelle("config visuelle")
          .couleurPrincipale("#FF0000")
          .couleurSecondaire("#00FF00")
          .icone("icon")
          .visible(true)
          .redimensionnable(true)
          .deplacable(true)
          .supprimable(true)
          .miseAJourAutomatique(true)
          .frequenceMiseAJourSecondes(60)
          .dateDerniereMiseAJour(now)
          .prochaineMiseAJour(now.plusHours(1))
          .donneesWidget("donnees")
          .configurationFiltres(filtres)
          .configurationAlertes(alertes)
          .seuilAlerteBas(10.0)
          .seuilAlerteHaut(90.0)
          .alerteActive(true)
          .messageAlerte("Alerte")
          .typeAlerte("warning")
          .permissions("read")
          .rolesAutorises("ADMIN")
          .templatePersonnalise("template")
          .cssPersonnalise("css")
          .javascriptPersonnalise("js")
          .metadonnees(metadonnees)
          .nombreVues(100L)
          .nombreInteractions(50L)
          .tempsMoyenSecondes(30)
          .tauxErreur(5.0)
          .dateDerniereErreur(now.minusHours(1))
          .messageDerniereErreur("Erreur")
          .build();

      assertThat(dto.getTitre()).isEqualTo("Widget Test Complet");
      assertThat(dto.getDescription()).isEqualTo("Description complète");
      assertThat(dto.getTypeWidget()).isEqualTo("kpi");
      assertThat(dto.getTypeMetrique()).isEqualTo(TypeMetrique.NOMBRE_MEMBRES_ACTIFS);
      assertThat(dto.getPeriodeAnalyse()).isEqualTo(PeriodeAnalyse.CE_MOIS);
      assertThat(dto.getOrganisationId()).isEqualTo(orgId);
      assertThat(dto.getNomOrganisation()).isEqualTo("Org Test");
      assertThat(dto.getUtilisateurProprietaireId()).isEqualTo(userId);
      assertThat(dto.getNomUtilisateurProprietaire()).isEqualTo("User Test");
      assertThat(dto.getPositionX()).isEqualTo(1);
      assertThat(dto.getPositionY()).isEqualTo(2);
      assertThat(dto.getLargeur()).isEqualTo(4);
      assertThat(dto.getHauteur()).isEqualTo(3);
      assertThat(dto.getOrdreAffichage()).isEqualTo(1);
      assertThat(dto.getConfigurationVisuelle()).isEqualTo("config visuelle");
      assertThat(dto.getCouleurPrincipale()).isEqualTo("#FF0000");
      assertThat(dto.getCouleurSecondaire()).isEqualTo("#00FF00");
      assertThat(dto.getIcone()).isEqualTo("icon");
      assertThat(dto.getVisible()).isTrue();
      assertThat(dto.getRedimensionnable()).isTrue();
      assertThat(dto.getDeplacable()).isTrue();
      assertThat(dto.getSupprimable()).isTrue();
      assertThat(dto.getMiseAJourAutomatique()).isTrue();
      assertThat(dto.getFrequenceMiseAJourSecondes()).isEqualTo(60);
      assertThat(dto.getDateDerniereMiseAJour()).isEqualTo(now);
      assertThat(dto.getProchaineMiseAJour()).isEqualTo(now.plusHours(1));
      assertThat(dto.getDonneesWidget()).isEqualTo("donnees");
      assertThat(dto.getConfigurationFiltres()).isEqualTo(filtres);
      assertThat(dto.getConfigurationAlertes()).isEqualTo(alertes);
      assertThat(dto.getSeuilAlerteBas()).isEqualTo(10.0);
      assertThat(dto.getSeuilAlerteHaut()).isEqualTo(90.0);
      assertThat(dto.getAlerteActive()).isTrue();
      assertThat(dto.getMessageAlerte()).isEqualTo("Alerte");
      assertThat(dto.getTypeAlerte()).isEqualTo("warning");
      assertThat(dto.getPermissions()).isEqualTo("read");
      assertThat(dto.getRolesAutorises()).isEqualTo("ADMIN");
      assertThat(dto.getTemplatePersonnalise()).isEqualTo("template");
      assertThat(dto.getCssPersonnalise()).isEqualTo("css");
      assertThat(dto.getJavascriptPersonnalise()).isEqualTo("js");
      assertThat(dto.getMetadonnees()).isEqualTo(metadonnees);
      assertThat(dto.getNombreVues()).isEqualTo(100L);
      assertThat(dto.getNombreInteractions()).isEqualTo(50L);
      assertThat(dto.getTempsMoyenSecondes()).isEqualTo(30);
      assertThat(dto.getTauxErreur()).isEqualTo(5.0);
      assertThat(dto.getDateDerniereErreur()).isEqualTo(now.minusHours(1));
      assertThat(dto.getMessageDerniereErreur()).isEqualTo("Erreur");
    }

    @Test
    @DisplayName("Builder - valeurs par défaut")
    void testBuilderValeursParDefaut() {
      UUID userId = UUID.randomUUID();
      DashboardWidgetDTO dto = DashboardWidgetDTO.builder()
          .titre("Widget")
          .typeWidget("kpi")
          .utilisateurProprietaireId(userId)
          .positionX(0)
          .positionY(0)
          .largeur(4)
          .hauteur(2)
          .build();

      assertThat(dto.getOrdreAffichage()).isEqualTo(0);
      assertThat(dto.getVisible()).isTrue();
      assertThat(dto.getRedimensionnable()).isTrue();
      assertThat(dto.getDeplacable()).isTrue();
      assertThat(dto.getSupprimable()).isTrue();
      assertThat(dto.getMiseAJourAutomatique()).isTrue();
      assertThat(dto.getFrequenceMiseAJourSecondes()).isEqualTo(300);
      assertThat(dto.getAlerteActive()).isFalse();
      assertThat(dto.getNombreVues()).isEqualTo(0L);
      assertThat(dto.getNombreInteractions()).isEqualTo(0L);
      assertThat(dto.getTauxErreur()).isEqualTo(0.0);
    }

  }
}

