package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.SuggestionVote;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.TypedQuery;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * Repository pour la gestion des votes sur les suggestions
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@ApplicationScoped
public class SuggestionVoteRepository extends BaseRepository<SuggestionVote> {

    public SuggestionVoteRepository() {
        super(SuggestionVote.class);
    }

    /**
     * Vérifie si un utilisateur a déjà voté pour une suggestion
     * 
     * @param suggestionId L'ID de la suggestion
     * @param utilisateurId L'ID de l'utilisateur
     * @return true si l'utilisateur a déjà voté
     */
    public boolean aDejaVote(UUID suggestionId, UUID utilisateurId) {
        TypedQuery<Long> query = entityManager.createQuery(
            "SELECT COUNT(v) FROM SuggestionVote v " +
            "WHERE v.suggestionId = :suggestionId " +
            "AND v.utilisateurId = :utilisateurId " +
            "AND v.actif = true",
            Long.class
        );
        query.setParameter("suggestionId", suggestionId);
        query.setParameter("utilisateurId", utilisateurId);
        return query.getSingleResult() > 0;
    }

    /**
     * Trouve un vote spécifique par suggestion et utilisateur
     * 
     * @param suggestionId L'ID de la suggestion
     * @param utilisateurId L'ID de l'utilisateur
     * @return Le vote trouvé ou Optional.empty()
     */
    public Optional<SuggestionVote> trouverVote(UUID suggestionId, UUID utilisateurId) {
        TypedQuery<SuggestionVote> query = entityManager.createQuery(
            "SELECT v FROM SuggestionVote v " +
            "WHERE v.suggestionId = :suggestionId " +
            "AND v.utilisateurId = :utilisateurId " +
            "AND v.actif = true",
            SuggestionVote.class
        );
        query.setParameter("suggestionId", suggestionId);
        query.setParameter("utilisateurId", utilisateurId);
        List<SuggestionVote> results = query.getResultList();
        return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
    }

    /**
     * Compte le nombre de votes pour une suggestion
     * 
     * @param suggestionId L'ID de la suggestion
     * @return Le nombre de votes actifs
     */
    public long compterVotesParSuggestion(UUID suggestionId) {
        TypedQuery<Long> query = entityManager.createQuery(
            "SELECT COUNT(v) FROM SuggestionVote v " +
            "WHERE v.suggestionId = :suggestionId " +
            "AND v.actif = true",
            Long.class
        );
        query.setParameter("suggestionId", suggestionId);
        return query.getSingleResult();
    }

    /**
     * Liste tous les votes pour une suggestion
     * 
     * @param suggestionId L'ID de la suggestion
     * @return La liste des votes actifs
     */
    public List<SuggestionVote> listerVotesParSuggestion(UUID suggestionId) {
        TypedQuery<SuggestionVote> query = entityManager.createQuery(
            "SELECT v FROM SuggestionVote v " +
            "WHERE v.suggestionId = :suggestionId " +
            "AND v.actif = true " +
            "ORDER BY v.dateVote DESC",
            SuggestionVote.class
        );
        query.setParameter("suggestionId", suggestionId);
        return query.getResultList();
    }

    /**
     * Liste tous les votes d'un utilisateur
     * 
     * @param utilisateurId L'ID de l'utilisateur
     * @return La liste des votes actifs de l'utilisateur
     */
    public List<SuggestionVote> listerVotesParUtilisateur(UUID utilisateurId) {
        TypedQuery<SuggestionVote> query = entityManager.createQuery(
            "SELECT v FROM SuggestionVote v " +
            "WHERE v.utilisateurId = :utilisateurId " +
            "AND v.actif = true " +
            "ORDER BY v.dateVote DESC",
            SuggestionVote.class
        );
        query.setParameter("utilisateurId", utilisateurId);
        return query.getResultList();
    }
}

