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

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 StatutAbonnement")
class StatutAbonnementTest {

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

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

    @Test
    @DisplayName("Test toutes les valeurs enum")
    void testToutesValeurs() {
      StatutAbonnement[] values = StatutAbonnement.values();
      assertThat(values).hasSize(5);
      assertThat(values).containsExactly(
          StatutAbonnement.ACTIF,
          StatutAbonnement.SUSPENDU,
          StatutAbonnement.EXPIRE,
          StatutAbonnement.ANNULE,
          StatutAbonnement.EN_ATTENTE_PAIEMENT);
    }

    @Test
    @DisplayName("Test valueOf")
    void testValueOf() {
      assertThat(StatutAbonnement.valueOf("ACTIF")).isEqualTo(StatutAbonnement.ACTIF);
      assertThat(StatutAbonnement.valueOf("SUSPENDU")).isEqualTo(StatutAbonnement.SUSPENDU);
      assertThat(StatutAbonnement.valueOf("EXPIRE")).isEqualTo(StatutAbonnement.EXPIRE);
      assertThat(StatutAbonnement.valueOf("ANNULE")).isEqualTo(StatutAbonnement.ANNULE);
      assertThat(StatutAbonnement.valueOf("EN_ATTENTE_PAIEMENT")).isEqualTo(StatutAbonnement.EN_ATTENTE_PAIEMENT);

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

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

    @ParameterizedTest
    @CsvSource({
        "ACTIF, Actif",
        "SUSPENDU, Suspendu",
        "EXPIRE, Expiré",
        "ANNULE, Annulé",
        "EN_ATTENTE_PAIEMENT, En attente de paiement"
    })
    @DisplayName("Test getLibelle avec valeurs exactes")
    void testGetLibelleValeursExactes(StatutAbonnement statut, String expectedLibelle) {
      assertThat(statut.getLibelle()).isEqualTo(expectedLibelle);
    }
  }
}

