package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.Message;
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
import io.quarkus.panache.common.Page;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * Repository pour les messages de la messagerie.
 *
 * @author UnionFlow Team
 * @version 4.0
 * @since 2026-04-13
 */
@ApplicationScoped
public class MessageRepository implements PanacheRepositoryBase<Message, UUID> {

    /**
     * Trouve un message par son ID avec Optional.
     */
    public Optional<Message> findMessageById(UUID id) {
        return find("id", id).firstResultOptional();
    }

    /**
     * Récupère les messages d'une conversation, paginés, du plus récent au plus ancien.
     *
     * @param conversationId ID de la conversation
     * @param page           numéro de page (0-based)
     * @param size           nombre de messages par page
     */
    public List<Message> findByConversationPagine(UUID conversationId, int page, int size) {
        return find(
            "conversation.id = ?1 AND actif = true ORDER BY dateCreation DESC",
            conversationId
        ).page(Page.of(page, size)).list();
    }

    /**
     * Compte les messages non lus dans une conversation pour un membre donné.
     * Un message est non lu si sa dateCreation est postérieure au luJusqua du participant.
     */
    public long countNonLus(UUID conversationId, UUID membreId) {
        return count(
            "SELECT COUNT(m) FROM Message m, ConversationParticipant p " +
            "WHERE m.conversation.id = ?1 " +
            "AND p.conversation.id = ?1 " +
            "AND p.membre.id = ?2 " +
            "AND m.actif = true " +
            "AND (p.luJusqua IS NULL OR m.dateCreation > p.luJusqua) " +
            "AND m.expediteur.id <> ?2",
            conversationId, membreId
        );
    }

    /**
     * Récupère les messages non supprimés d'une conversation (pour les tests).
     */
    public List<Message> findActifsByConversation(UUID conversationId) {
        return find(
            "conversation.id = ?1 AND actif = true ORDER BY dateCreation ASC",
            conversationId
        ).list();
    }

    /**
     * Trouve le dernier message actif d'une conversation.
     */
    public Optional<Message> findDernierMessage(UUID conversationId) {
        return find(
            "conversation.id = ?1 AND actif = true ORDER BY dateCreation DESC",
            conversationId
        ).firstResultOptional();
    }
}
