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

@DisplayName("Tests pour TypeEvenement")
class TypeEvenementTest {

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

    @Test
    @DisplayName("Test toutes les valeurs enum")
    void testToutesValeurs() {
      TypeEvenement[] values = TypeEvenement.values();
      assertThat(values).hasSize(8);
      assertThat(values).containsExactly(
          TypeEvenement.CHECKOUT_COMPLETE,
          TypeEvenement.CHECKOUT_CANCELLED,
          TypeEvenement.CHECKOUT_EXPIRED,
          TypeEvenement.PAYOUT_COMPLETE,
          TypeEvenement.PAYOUT_FAILED,
          TypeEvenement.BALANCE_UPDATED,
          TypeEvenement.TRANSACTION_CREATED,
          TypeEvenement.TRANSACTION_UPDATED);
    }

    @ParameterizedTest
    @EnumSource(TypeEvenement.class)
    @DisplayName("Test getCodeWave pour toutes les valeurs")
    void testGetCodeWave(TypeEvenement type) {
      assertThat(type.getCodeWave()).isNotNull().isNotEmpty();
    }

    @ParameterizedTest
    @CsvSource({
        "CHECKOUT_COMPLETE, checkout.complete",
        "CHECKOUT_CANCELLED, checkout.cancelled",
        "CHECKOUT_EXPIRED, checkout.expired",
        "PAYOUT_COMPLETE, payout.complete",
        "PAYOUT_FAILED, payout.failed",
        "BALANCE_UPDATED, balance.updated",
        "TRANSACTION_CREATED, transaction.created",
        "TRANSACTION_UPDATED, transaction.updated"
    })
    @DisplayName("Test getCodeWave avec valeurs exactes")
    void testGetCodeWaveValeursExactes(TypeEvenement type, String expectedCode) {
      assertThat(type.getCodeWave()).isEqualTo(expectedCode);
    }
  }

  @Nested
  @DisplayName("Tests fromCode")
  class FromCodeTests {

    @ParameterizedTest
    @CsvSource({
        "checkout.complete, CHECKOUT_COMPLETE",
        "checkout.cancelled, CHECKOUT_CANCELLED",
        "checkout.expired, CHECKOUT_EXPIRED",
        "payout.complete, PAYOUT_COMPLETE",
        "payout.failed, PAYOUT_FAILED",
        "balance.updated, BALANCE_UPDATED",
        "transaction.created, TRANSACTION_CREATED",
        "transaction.updated, TRANSACTION_UPDATED"
    })
    @DisplayName("fromCode - trouve le bon type")
    void testFromCode(String code, TypeEvenement expected) {
      assertThat(TypeEvenement.fromCode(code)).isEqualTo(expected);
    }

    @Test
    @DisplayName("fromCode - code inexistant")
    void testFromCodeInexistant() {
      assertThat(TypeEvenement.fromCode("inexistant")).isNull();
    }

    @Test
    @DisplayName("fromCode - code null")
    void testFromCodeNull() {
      assertThat(TypeEvenement.fromCode(null)).isNull();
    }
  }
}

