package dev.lions.unionflow.server.repository;

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

import dev.lions.unionflow.server.entity.Membre;
import java.time.LocalDate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

/**
 * Tests pour MembreRepository
 *
 * @author Lions Dev Team
 * @since 2025-01-10
 */
@ExtendWith(MockitoExtension.class)
@DisplayName("Tests MembreRepository")
class MembreRepositoryTest {

  @Mock MembreRepository membreRepository;

  private Membre membreTest;
  private Membre membreInactif;

  @BeforeEach
  void setUp() {

    // Créer des membres de test
    membreTest =
        Membre.builder()
            .numeroMembre("UF2025-TEST01")
            .prenom("Jean")
            .nom("Dupont")
            .email("jean.dupont@test.com")
            .telephone("221701234567")
            .dateNaissance(LocalDate.of(1990, 5, 15))
            .dateAdhesion(LocalDate.now())
            .actif(true)
            .build();

    membreInactif =
        Membre.builder()
            .numeroMembre("UF2025-TEST02")
            .prenom("Marie")
            .nom("Martin")
            .email("marie.martin@test.com")
            .telephone("221701234568")
            .dateNaissance(LocalDate.of(1985, 8, 20))
            .dateAdhesion(LocalDate.now())
            .actif(false)
            .build();
  }

  @Test
  @DisplayName("Test de l'existence de la classe MembreRepository")
  void testMembreRepositoryExists() {
    // Given & When & Then
    assertThat(MembreRepository.class).isNotNull();
    assertThat(membreRepository).isNotNull();
  }

  @Test
  @DisplayName("Test des méthodes du repository")
  void testRepositoryMethods() throws NoSuchMethodException {
    // Given & When & Then
    assertThat(MembreRepository.class.getMethod("findByEmail", String.class)).isNotNull();
    assertThat(MembreRepository.class.getMethod("findByNumeroMembre", String.class)).isNotNull();
    assertThat(MembreRepository.class.getMethod("findAllActifs")).isNotNull();
    assertThat(MembreRepository.class.getMethod("countActifs")).isNotNull();
    assertThat(MembreRepository.class.getMethod("findByNomOrPrenom", String.class)).isNotNull();
  }

  @Test
  @DisplayName("Test de l'annotation ApplicationScoped")
  void testApplicationScopedAnnotation() {
    // Given & When & Then
    assertThat(
            MembreRepository.class.getAnnotation(
                jakarta.enterprise.context.ApplicationScoped.class))
        .isNotNull();
  }

  @Test
  @DisplayName("Test de l'implémentation PanacheRepository")
  void testPanacheRepositoryImplementation() {
    // Given & When & Then
    assertThat(io.quarkus.hibernate.orm.panache.PanacheRepository.class)
        .isAssignableFrom(MembreRepository.class);
  }

  @Test
  @DisplayName("Test de la création d'instance")
  void testInstanceCreation() {
    // Given & When
    MembreRepository repository = new MembreRepository();

    // Then
    assertThat(repository).isNotNull();
    assertThat(repository).isInstanceOf(io.quarkus.hibernate.orm.panache.PanacheRepository.class);
  }
}
