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

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 TypeObjetIntentionPaiement")
class TypeObjetIntentionPaiementTest {

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

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

    @Test
    @DisplayName("Test toutes les valeurs enum")
    void testToutesValeurs() {
      TypeObjetIntentionPaiement[] values = TypeObjetIntentionPaiement.values();
      assertThat(values).hasSize(5);
      assertThat(values).containsExactly(
          TypeObjetIntentionPaiement.COTISATION,
          TypeObjetIntentionPaiement.ADHESION,
          TypeObjetIntentionPaiement.EVENEMENT,
          TypeObjetIntentionPaiement.ABONNEMENT_UNIONFLOW,
          TypeObjetIntentionPaiement.DEPOT_EPARGNE);
    }

    @Test
    @DisplayName("Test valueOf - toutes les constantes")
    void testValueOf() {
      assertThat(TypeObjetIntentionPaiement.valueOf("COTISATION")).isEqualTo(TypeObjetIntentionPaiement.COTISATION);
      assertThat(TypeObjetIntentionPaiement.valueOf("ADHESION")).isEqualTo(TypeObjetIntentionPaiement.ADHESION);
      assertThat(TypeObjetIntentionPaiement.valueOf("EVENEMENT")).isEqualTo(TypeObjetIntentionPaiement.EVENEMENT);
      assertThat(TypeObjetIntentionPaiement.valueOf("ABONNEMENT_UNIONFLOW")).isEqualTo(TypeObjetIntentionPaiement.ABONNEMENT_UNIONFLOW);
      assertThat(TypeObjetIntentionPaiement.valueOf("DEPOT_EPARGNE")).isEqualTo(TypeObjetIntentionPaiement.DEPOT_EPARGNE);

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

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

    @Test
    @DisplayName("Test getLibelle valeurs exactes")
    void testGetLibelleValeursExactes() {
      assertThat(TypeObjetIntentionPaiement.COTISATION.getLibelle()).isEqualTo("Cotisation membre");
      assertThat(TypeObjetIntentionPaiement.ADHESION.getLibelle()).isEqualTo("Frais d'adhésion");
      assertThat(TypeObjetIntentionPaiement.EVENEMENT.getLibelle()).isEqualTo("Participation événement");
      assertThat(TypeObjetIntentionPaiement.ABONNEMENT_UNIONFLOW.getLibelle()).isEqualTo("Abonnement forfait UnionFlow");
      assertThat(TypeObjetIntentionPaiement.DEPOT_EPARGNE.getLibelle()).isEqualTo("Dépôt compte épargne");
    }

    @Test
    @DisplayName("Test name()")
    void testName() {
      assertThat(TypeObjetIntentionPaiement.COTISATION.name()).isEqualTo("COTISATION");
      assertThat(TypeObjetIntentionPaiement.ABONNEMENT_UNIONFLOW.name()).isEqualTo("ABONNEMENT_UNIONFLOW");
    }
  }
}
