package dev.lions.unionflow.server.entity;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;

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

/**
 * Tests simples pour l'entité Membre
 * 
 * @author Lions Dev Team
 * @since 2025-01-10
 */
@DisplayName("Tests simples Membre")
class MembreSimpleTest {

    @Test
    @DisplayName("Test de création d'un membre avec builder")
    void testCreationMembreAvecBuilder() {
        // Given & When
        Membre membre = 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();

        // Then
        assertThat(membre).isNotNull();
        assertThat(membre.getNumeroMembre()).isEqualTo("UF2025-TEST01");
        assertThat(membre.getPrenom()).isEqualTo("Jean");
        assertThat(membre.getNom()).isEqualTo("Dupont");
        assertThat(membre.getEmail()).isEqualTo("jean.dupont@test.com");
        assertThat(membre.getTelephone()).isEqualTo("221701234567");
        assertThat(membre.getDateNaissance()).isEqualTo(LocalDate.of(1990, 5, 15));
        assertThat(membre.getActif()).isTrue();
    }

    @Test
    @DisplayName("Test de la méthode getNomComplet")
    void testGetNomComplet() {
        // Given
        Membre membre = Membre.builder()
                .prenom("Jean")
                .nom("Dupont")
                .build();

        // When
        String nomComplet = membre.getNomComplet();

        // Then
        assertThat(nomComplet).isEqualTo("Jean Dupont");
    }

    @Test
    @DisplayName("Test de la méthode isMajeur - Majeur")
    void testIsMajeurMajeur() {
        // Given
        Membre membre = Membre.builder()
                .dateNaissance(LocalDate.of(1990, 5, 15))
                .build();

        // When
        boolean majeur = membre.isMajeur();

        // Then
        assertThat(majeur).isTrue();
    }

    @Test
    @DisplayName("Test de la méthode isMajeur - Mineur")
    void testIsMajeurMineur() {
        // Given
        Membre membre = Membre.builder()
                .dateNaissance(LocalDate.now().minusYears(17))
                .build();

        // When
        boolean majeur = membre.isMajeur();

        // Then
        assertThat(majeur).isFalse();
    }

    @Test
    @DisplayName("Test de la méthode getAge")
    void testGetAge() {
        // Given
        Membre membre = Membre.builder()
                .dateNaissance(LocalDate.now().minusYears(25))
                .build();

        // When
        int age = membre.getAge();

        // Then
        assertThat(age).isEqualTo(25);
    }

    @Test
    @DisplayName("Test de création d'un membre sans builder")
    void testCreationMembreSansBuilder() {
        // Given & When
        Membre membre = new Membre();
        membre.setNumeroMembre("UF2025-TEST02");
        membre.setPrenom("Marie");
        membre.setNom("Martin");
        membre.setEmail("marie.martin@test.com");
        membre.setActif(true);

        // Then
        assertThat(membre).isNotNull();
        assertThat(membre.getNumeroMembre()).isEqualTo("UF2025-TEST02");
        assertThat(membre.getPrenom()).isEqualTo("Marie");
        assertThat(membre.getNom()).isEqualTo("Martin");
        assertThat(membre.getEmail()).isEqualTo("marie.martin@test.com");
        assertThat(membre.getActif()).isTrue();
    }

    @Test
    @DisplayName("Test des annotations JPA")
    void testAnnotationsJPA() {
        // Given & When & Then
        assertThat(Membre.class.getAnnotation(jakarta.persistence.Entity.class)).isNotNull();
        assertThat(Membre.class.getAnnotation(jakarta.persistence.Table.class)).isNotNull();
        assertThat(Membre.class.getAnnotation(jakarta.persistence.Table.class).name()).isEqualTo("membres");
    }

    @Test
    @DisplayName("Test des annotations Lombok")
    void testAnnotationsLombok() {
        // Given & When & Then
        // Vérifier que les annotations Lombok sont présentes (peuvent être null selon la compilation)
        // Nous testons plutôt que les méthodes générées existent
        assertThat(Membre.builder()).isNotNull();

        Membre membre = new Membre();
        assertThat(membre.toString()).isNotNull();
        assertThat(membre.hashCode()).isNotZero();
    }

    @Test
    @DisplayName("Test de l'héritage PanacheEntity")
    void testHeritageePanacheEntity() {
        // Given & When & Then
        assertThat(io.quarkus.hibernate.orm.panache.PanacheEntity.class)
                .isAssignableFrom(Membre.class);
    }

    @Test
    @DisplayName("Test des méthodes héritées de PanacheEntity")
    void testMethodesHeriteesPanacheEntity() throws NoSuchMethodException {
        // Given & When & Then
        // Vérifier que les méthodes de PanacheEntity sont disponibles
        assertThat(Membre.class.getMethod("persist")).isNotNull();
        assertThat(Membre.class.getMethod("delete")).isNotNull();
        assertThat(Membre.class.getMethod("isPersistent")).isNotNull();
    }

    @Test
    @DisplayName("Test de toString")
    void testToString() {
        // Given
        Membre membre = Membre.builder()
                .numeroMembre("UF2025-TEST01")
                .prenom("Jean")
                .nom("Dupont")
                .email("jean.dupont@test.com")
                .actif(true)
                .build();

        // When
        String toString = membre.toString();

        // Then
        assertThat(toString).isNotNull();
        assertThat(toString).contains("Jean");
        assertThat(toString).contains("Dupont");
        assertThat(toString).contains("UF2025-TEST01");
        assertThat(toString).contains("jean.dupont@test.com");
    }

    @Test
    @DisplayName("Test de hashCode")
    void testHashCode() {
        // Given
        Membre membre1 = Membre.builder()
                .numeroMembre("UF2025-TEST01")
                .prenom("Jean")
                .nom("Dupont")
                .email("jean.dupont@test.com")
                .build();

        Membre membre2 = Membre.builder()
                .numeroMembre("UF2025-TEST01")
                .prenom("Jean")
                .nom("Dupont")
                .email("jean.dupont@test.com")
                .build();

        // When & Then
        assertThat(membre1.hashCode()).isNotZero();
        assertThat(membre2.hashCode()).isNotZero();
    }

    @Test
    @DisplayName("Test des propriétés nulles")
    void testProprietesNulles() {
        // Given
        Membre membre = new Membre();

        // When & Then
        assertThat(membre.getNumeroMembre()).isNull();
        assertThat(membre.getPrenom()).isNull();
        assertThat(membre.getNom()).isNull();
        assertThat(membre.getEmail()).isNull();
        assertThat(membre.getTelephone()).isNull();
        assertThat(membre.getDateNaissance()).isNull();
        assertThat(membre.getDateAdhesion()).isNull();
        // Le champ actif a une valeur par défaut à true dans l'entité
        // assertThat(membre.getActif()).isNull();
    }

    @Test
    @DisplayName("Test de la méthode preUpdate")
    void testPreUpdate() {
        // Given
        Membre membre = new Membre();
        assertThat(membre.getDateModification()).isNull();

        // When
        membre.preUpdate();

        // Then
        assertThat(membre.getDateModification()).isNotNull();
    }
}
