package dev.lions.unionflow.server.entity;

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

import java.time.LocalDateTime;

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

/**
 * Tests unitaires pour l'entité FeedbackEvenement.
 * Tests purs (sans Quarkus) car les méthodes sont de la logique en mémoire.
 */
@DisplayName("FeedbackEvenement")
class FeedbackEvenementTest {

    private FeedbackEvenement buildFeedback() {
        FeedbackEvenement fb = new FeedbackEvenement();
        fb.setNote(4);
        fb.setCommentaire("Très bon événement");
        fb.setDateFeedback(LocalDateTime.now());
        fb.setModerationStatut(FeedbackEvenement.ModerationStatut.PUBLIE.name());
        return fb;
    }

    @Test
    @DisplayName("isPublie retourne true quand statut est PUBLIE")
    void isPublie_quandStatutPublie_retourneTrue() {
        FeedbackEvenement fb = buildFeedback();
        fb.setModerationStatut(FeedbackEvenement.ModerationStatut.PUBLIE.name());

        assertThat(fb.isPublie()).isTrue();
    }

    @Test
    @DisplayName("isPublie retourne false quand statut est EN_ATTENTE")
    void isPublie_quandStatutEnAttente_retourneFalse() {
        FeedbackEvenement fb = buildFeedback();
        fb.setModerationStatut(FeedbackEvenement.ModerationStatut.EN_ATTENTE.name());

        assertThat(fb.isPublie()).isFalse();
    }

    @Test
    @DisplayName("isPublie retourne false quand statut est REJETE")
    void isPublie_quandStatutRejete_retourneFalse() {
        FeedbackEvenement fb = buildFeedback();
        fb.setModerationStatut(FeedbackEvenement.ModerationStatut.REJETE.name());

        assertThat(fb.isPublie()).isFalse();
    }

    @Test
    @DisplayName("mettreEnAttente modifie le statut et la raison")
    void mettreEnAttente_modifieStatutEtRaison() {
        FeedbackEvenement fb = buildFeedback();

        fb.mettreEnAttente("Contenu inapproprié");

        assertThat(fb.getModerationStatut()).isEqualTo(FeedbackEvenement.ModerationStatut.EN_ATTENTE.name());
        assertThat(fb.getRaisonModeration()).isEqualTo("Contenu inapproprié");
        assertThat(fb.isPublie()).isFalse();
    }

    @Test
    @DisplayName("publier restaure le statut PUBLIE et efface la raison")
    void publier_restaureStatutPublieEtEffaceRaison() {
        FeedbackEvenement fb = buildFeedback();
        fb.mettreEnAttente("Raison de test");

        fb.publier();

        assertThat(fb.getModerationStatut()).isEqualTo(FeedbackEvenement.ModerationStatut.PUBLIE.name());
        assertThat(fb.getRaisonModeration()).isNull();
        assertThat(fb.isPublie()).isTrue();
    }

    @Test
    @DisplayName("rejeter modifie le statut à REJETE et stocke la raison")
    void rejeter_modifieStatutEtRaison() {
        FeedbackEvenement fb = buildFeedback();

        fb.rejeter("Commentaire offensant");

        assertThat(fb.getModerationStatut()).isEqualTo(FeedbackEvenement.ModerationStatut.REJETE.name());
        assertThat(fb.getRaisonModeration()).isEqualTo("Commentaire offensant");
        assertThat(fb.isPublie()).isFalse();
    }

    @Test
    @DisplayName("toString retourne une représentation textuelle avec membre et evenement null")
    void toString_avecMembreEtEvenementNull_retourneChaineSansException() {
        FeedbackEvenement fb = buildFeedback();
        fb.setMembre(null);
        fb.setEvenement(null);
        fb.setNote(3);

        String result = fb.toString();

        assertThat(result).isNotNull();
        assertThat(result).contains("FeedbackEvenement");
        assertThat(result).contains("null"); // membre et evenement sont null
    }

    @Test
    @DisplayName("toString retourne une représentation textuelle avec membre et evenement renseignés")
    void toString_avecMembreEtEvenement_retourneRepresentationComplete() {
        FeedbackEvenement fb = buildFeedback();
        Membre membre = new Membre();
        membre.setEmail("test@test.com");
        fb.setMembre(membre);

        Evenement evenement = new Evenement();
        evenement.setTitre("AG 2026");
        evenement.setDateDebut(LocalDateTime.now());
        fb.setEvenement(evenement);
        fb.setNote(5);

        String result = fb.toString();

        assertThat(result).isNotNull();
        assertThat(result).contains("FeedbackEvenement");
        assertThat(result).contains("test@test.com");
        assertThat(result).contains("AG 2026");
    }

    @Test
    @DisplayName("preUpdate appelle onUpdate sans exception")
    void preUpdate_sansException() {
        FeedbackEvenement fb = buildFeedback();
        // dateModification initialement null (pas d'id/version puisque pas en base)
        // preUpdate() appelle super.onUpdate() qui met dateModification à now()
        // On vérifie que l'appel ne lance pas d'exception
        fb.preUpdate();
        assertThat(fb.getDateModification()).isNotNull();
    }

    @Test
    @DisplayName("ModerationStatut enum contient les trois valeurs attendues")
    void moderationStatutEnum_contientValeurs() {
        FeedbackEvenement.ModerationStatut[] values = FeedbackEvenement.ModerationStatut.values();
        assertThat(values).hasSize(3);
        assertThat(values).contains(
                FeedbackEvenement.ModerationStatut.PUBLIE,
                FeedbackEvenement.ModerationStatut.EN_ATTENTE,
                FeedbackEvenement.ModerationStatut.REJETE);
    }

    @Test
    @DisplayName("getters et setters fonctionnent correctement")
    void gettersSetters_fonctionnentCorrectement() {
        FeedbackEvenement fb = new FeedbackEvenement();
        LocalDateTime date = LocalDateTime.of(2026, 1, 15, 10, 0);

        fb.setNote(3);
        fb.setCommentaire("Bien mais peut mieux faire");
        fb.setDateFeedback(date);
        fb.setModerationStatut(FeedbackEvenement.ModerationStatut.EN_ATTENTE.name());
        fb.setRaisonModeration("Vérification en cours");

        assertThat(fb.getNote()).isEqualTo(3);
        assertThat(fb.getCommentaire()).isEqualTo("Bien mais peut mieux faire");
        assertThat(fb.getDateFeedback()).isEqualTo(date);
        assertThat(fb.getModerationStatut()).isEqualTo("EN_ATTENTE");
        assertThat(fb.getRaisonModeration()).isEqualTo("Vérification en cours");
    }
}
