package dev.lions.unionflow.server.entity;

import dev.lions.unionflow.server.api.enums.messagerie.StatutConversation;
import dev.lions.unionflow.server.api.enums.messagerie.TypeConversation;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.util.UUID;

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

@DisplayName("Conversation")
class ConversationTest {

    private static Membre newMembre() {
        Membre m = new Membre();
        m.setId(UUID.randomUUID());
        m.setNumeroMembre("M1");
        m.setPrenom("Alpha");
        m.setNom("Diallo");
        m.setEmail("alpha@test.com");
        m.setDateNaissance(LocalDate.now());
        return m;
    }

    private static Organisation newOrg() {
        Organisation org = new Organisation();
        org.setId(UUID.randomUUID());
        org.setNom("Tontine Test");
        return org;
    }

    @Test
    @DisplayName("getters/setters — tous les champs")
    void gettersSetters() {
        Conversation conv = new Conversation();
        Organisation org = newOrg();
        conv.setOrganisation(org);
        conv.setTypeConversation(TypeConversation.DIRECTE);
        conv.setStatut(StatutConversation.ACTIVE);
        conv.setTitre("Discussion");
        conv.setNombreMessages(5);

        assertThat(conv.getOrganisation()).isEqualTo(org);
        assertThat(conv.getTypeConversation()).isEqualTo(TypeConversation.DIRECTE);
        assertThat(conv.getStatut()).isEqualTo(StatutConversation.ACTIVE);
        assertThat(conv.getTitre()).isEqualTo("Discussion");
        assertThat(conv.getNombreMessages()).isEqualTo(5);
    }

    @Test
    @DisplayName("estActive — ACTIVE → true")
    void estActive_active() {
        Conversation conv = buildMinimal();
        conv.setStatut(StatutConversation.ACTIVE);
        assertThat(conv.estActive()).isTrue();
    }

    @Test
    @DisplayName("estActive — ARCHIVEE → false")
    void estActive_archivee() {
        Conversation conv = buildMinimal();
        conv.setStatut(StatutConversation.ARCHIVEE);
        assertThat(conv.estActive()).isFalse();
    }

    @Test
    @DisplayName("archiver — passe le statut à ARCHIVEE")
    void archiver() {
        Conversation conv = buildMinimal();
        conv.setStatut(StatutConversation.ACTIVE);
        conv.archiver();
        assertThat(conv.getStatut()).isEqualTo(StatutConversation.ARCHIVEE);
        assertThat(conv.estActive()).isFalse();
    }

    @Test
    @DisplayName("enregistrerNouveauMessage — incrémente le compteur et met à jour la date")
    void enregistrerNouveauMessage() {
        Conversation conv = buildMinimal();
        conv.setNombreMessages(3);
        conv.enregistrerNouveauMessage();
        assertThat(conv.getNombreMessages()).isEqualTo(4);
        assertThat(conv.getDernierMessageAt()).isNotNull();
    }

    @Test
    @DisplayName("enregistrerNouveauMessage — part de null")
    void enregistrerNouveauMessage_partDeNull() {
        Conversation conv = buildMinimal();
        conv.setNombreMessages(null);
        conv.enregistrerNouveauMessage();
        assertThat(conv.getNombreMessages()).isEqualTo(1);
    }

    @Test
    @DisplayName("onCreate — initialise statut et nombreMessages si null")
    void onCreate_initDefaults() {
        Conversation conv = new Conversation();
        conv.setOrganisation(newOrg());
        conv.setTypeConversation(TypeConversation.DIRECTE);

        conv.onCreate();

        assertThat(conv.getStatut()).isEqualTo(StatutConversation.ACTIVE);
        assertThat(conv.getNombreMessages()).isEqualTo(0);
        assertThat(conv.getDateCreation()).isNotNull();
        assertThat(conv.getActif()).isTrue();
    }

    @Test
    @DisplayName("ROLE_CANAL — roleCible renseigné")
    void roleCanalType() {
        Conversation conv = buildMinimal();
        conv.setTypeConversation(TypeConversation.ROLE_CANAL);
        conv.setRoleCible("TRESORIER");
        conv.setTitre("Trésorier");

        assertThat(conv.getTypeConversation()).isEqualTo(TypeConversation.ROLE_CANAL);
        assertThat(conv.getRoleCible()).isEqualTo("TRESORIER");
    }

    @Test
    @DisplayName("participants initialisé à liste vide (builder default)")
    void participants_initializedEmpty() {
        Conversation conv = Conversation.builder()
            .organisation(newOrg())
            .typeConversation(TypeConversation.DIRECTE)
            .build();
        assertThat(conv.getParticipants()).isNotNull().isEmpty();
        assertThat(conv.getMessages()).isNotNull().isEmpty();
    }

    @Test
    @DisplayName("equals et hashCode")
    void equalsHashCode() {
        UUID id = UUID.randomUUID();
        Organisation org = newOrg();

        Conversation a = buildMinimal();
        a.setId(id);
        a.setOrganisation(org);
        Conversation b = buildMinimal();
        b.setId(id);
        b.setOrganisation(org);

        assertThat(a).isEqualTo(b);
        assertThat(a.hashCode()).isEqualTo(b.hashCode());
    }

    @Test
    @DisplayName("toString non null")
    void toString_nonNull() {
        assertThat(buildMinimal().toString()).isNotNull().isNotEmpty();
    }

    private Conversation buildMinimal() {
        Conversation conv = new Conversation();
        conv.setOrganisation(newOrg());
        conv.setTypeConversation(TypeConversation.DIRECTE);
        conv.setStatut(StatutConversation.ACTIVE);
        conv.setNombreMessages(0);
        return conv;
    }
}
