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

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

@DisplayName("Tests pour StatutOrganisation")
class StatutOrganisationTest {

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

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

    @Test
    @DisplayName("Test toutes les valeurs enum")
    void testToutesValeurs() {
      StatutOrganisation[] values = StatutOrganisation.values();
      assertThat(values).hasSize(5);
      assertThat(values).containsExactly(
          StatutOrganisation.ACTIVE,
          StatutOrganisation.INACTIVE,
          StatutOrganisation.SUSPENDUE,
          StatutOrganisation.EN_CREATION,
          StatutOrganisation.DISSOUTE);
    }

    @Test
    @DisplayName("Test valueOf")
    void testValueOf() {
      assertThat(StatutOrganisation.valueOf("ACTIVE")).isEqualTo(StatutOrganisation.ACTIVE);
      assertThat(StatutOrganisation.valueOf("INACTIVE")).isEqualTo(StatutOrganisation.INACTIVE);
      assertThat(StatutOrganisation.valueOf("SUSPENDUE")).isEqualTo(StatutOrganisation.SUSPENDUE);
      assertThat(StatutOrganisation.valueOf("EN_CREATION")).isEqualTo(StatutOrganisation.EN_CREATION);
      assertThat(StatutOrganisation.valueOf("DISSOUTE")).isEqualTo(StatutOrganisation.DISSOUTE);

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

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

    @ParameterizedTest
    @CsvSource({
        "ACTIVE, Active",
        "INACTIVE, Inactive",
        "SUSPENDUE, Suspendue",
        "EN_CREATION, En Création",
        "DISSOUTE, Dissoute"
    })
    @DisplayName("Test getLibelle avec valeurs exactes")
    void testGetLibelleValeursExactes(StatutOrganisation statut, String expectedLibelle) {
      assertThat(statut.getLibelle()).isEqualTo(expectedLibelle);
    }

    @Test
    @DisplayName("Test ordinal et name")
    void testOrdinalEtName() {
      assertThat(StatutOrganisation.ACTIVE.ordinal()).isEqualTo(0);
      assertThat(StatutOrganisation.INACTIVE.ordinal()).isEqualTo(1);
      assertThat(StatutOrganisation.SUSPENDUE.ordinal()).isEqualTo(2);
      assertThat(StatutOrganisation.EN_CREATION.ordinal()).isEqualTo(3);
      assertThat(StatutOrganisation.DISSOUTE.ordinal()).isEqualTo(4);

      assertThat(StatutOrganisation.ACTIVE.name()).isEqualTo("ACTIVE");
      assertThat(StatutOrganisation.INACTIVE.name()).isEqualTo("INACTIVE");
      assertThat(StatutOrganisation.SUSPENDUE.name()).isEqualTo("SUSPENDUE");
      assertThat(StatutOrganisation.EN_CREATION.name()).isEqualTo("EN_CREATION");
      assertThat(StatutOrganisation.DISSOUTE.name()).isEqualTo("DISSOUTE");
    }
  }
}

