package dev.lions.unionflow.server.api.enums.module;

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

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.EnumSource;

@DisplayName("Tests pour TypeModule")
class TypeModuleTest {

  @Test
  @DisplayName("Test de base - enum peut être utilisé")
  void testEnumUtilisable() {
    assertThat(TypeModule.COTISATIONS).isNotNull();
    assertThat(TypeModule.CULTES_RELIGIEUX).isNotNull();
  }

  @Nested
  @DisplayName("Tests des valeurs enum")
  class TestsValeursEnum {

    @Test
    @DisplayName("Test toutes les valeurs enum")
    void testToutesValeurs() {
      TypeModule[] values = TypeModule.values();
      assertThat(values).hasSize(16);
      assertThat(values).contains(
          TypeModule.COTISATIONS,
          TypeModule.EVENEMENTS,
          TypeModule.SOLIDARITE,
          TypeModule.COMPTABILITE,
          TypeModule.DOCUMENTS,
          TypeModule.NOTIFICATIONS,
          TypeModule.CREDIT_EPARGNE,
          TypeModule.AYANTS_DROIT,
          TypeModule.TONTINE,
          TypeModule.ONG_PROJETS,
          TypeModule.COOP_AGRICOLE,
          TypeModule.VOTE_INTERNE,
          TypeModule.COLLECTE_FONDS,
          TypeModule.REGISTRE_PROFESSIONNEL,
          TypeModule.CULTES_RELIGIEUX,
          TypeModule.GOUVERNANCE_MULTI);
    }

    @Test
    @DisplayName("Test valueOf - constantes principales")
    void testValueOf() {
      assertThat(TypeModule.valueOf("COTISATIONS")).isEqualTo(TypeModule.COTISATIONS);
      assertThat(TypeModule.valueOf("SOLIDARITE")).isEqualTo(TypeModule.SOLIDARITE);
      assertThat(TypeModule.valueOf("CULTES_RELIGIEUX")).isEqualTo(TypeModule.CULTES_RELIGIEUX);
      assertThat(TypeModule.valueOf("GOUVERNANCE_MULTI")).isEqualTo(TypeModule.GOUVERNANCE_MULTI);

      assertThatThrownBy(() -> TypeModule.valueOf("INEXISTANT"))
          .isInstanceOf(IllegalArgumentException.class);
    }

    @ParameterizedTest
    @EnumSource(TypeModule.class)
    @DisplayName("Test getLibelle pour toutes les valeurs")
    void testGetLibelle(TypeModule type) {
      assertThat(type.getLibelle()).isNotNull().isNotEmpty();
    }

    @Test
    @DisplayName("Test getLibelle valeurs exactes - échantillon")
    void testGetLibelleValeursExactes() {
      assertThat(TypeModule.COTISATIONS.getLibelle()).isEqualTo("Gestion des cotisations");
      assertThat(TypeModule.CULTES_RELIGIEUX.getLibelle()).isEqualTo("Gestion cultes et dîmes");
      assertThat(TypeModule.SOLIDARITE.getLibelle()).isEqualTo("Fonds de solidarité");
    }

    @Test
    @DisplayName("Test name()")
    void testName() {
      assertThat(TypeModule.COTISATIONS.name()).isEqualTo("COTISATIONS");
      assertThat(TypeModule.CULTES_RELIGIEUX.name()).isEqualTo("CULTES_RELIGIEUX");
    }
  }
}
