package dev.lions.unionflow.server.repository;

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

/**
 * Repository pour les feedbacks d'événements
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-16
 */
@ApplicationScoped
public class FeedbackEvenementRepository
    implements PanacheRepositoryBase<FeedbackEvenement, UUID> {

  /**
   * Trouve un feedback par membre et événement
   *
   * @param membreId UUID du membre
   * @param evenementId UUID de l'événement
   * @return Optional de FeedbackEvenement
   */
  public Optional<FeedbackEvenement> findByMembreAndEvenement(
      UUID membreId, UUID evenementId) {
    return find("membre.id = ?1 and evenement.id = ?2 and actif = true", membreId, evenementId)
        .firstResultOptional();
  }

  /**
   * Liste tous les feedbacks d'un événement (publiés uniquement)
   *
   * @param evenementId UUID de l'événement
   * @return Liste des feedbacks publiés
   */
  public List<FeedbackEvenement> findPubliesByEvenement(UUID evenementId) {
    return find(
            "evenement.id = ?1 and moderationStatut = 'PUBLIE' and actif = true order by dateFeedback desc",
            evenementId)
        .list();
  }

  /**
   * Liste tous les feedbacks d'un événement (tous statuts)
   *
   * @param evenementId UUID de l'événement
   * @return Liste de tous les feedbacks
   */
  public List<FeedbackEvenement> findAllByEvenement(UUID evenementId) {
    return find("evenement.id = ?1 and actif = true order by dateFeedback desc", evenementId)
        .list();
  }

  /**
   * Calcule la note moyenne d'un événement
   *
   * @param evenementId UUID de l'événement
   * @return Note moyenne (ou 0.0 si aucun feedback)
   */
  public Double calculateAverageNote(UUID evenementId) {
    Double avg =
        find(
                "select avg(f.note) from FeedbackEvenement f where f.evenement.id = ?1 and f.moderationStatut = 'PUBLIE' and f.actif = true",
                evenementId)
            .project(Double.class)
            .firstResult();
    return avg != null ? avg : 0.0;
  }

  /**
   * Compte le nombre de feedbacks publiés pour un événement
   *
   * @param evenementId UUID de l'événement
   * @return Nombre de feedbacks publiés
   */
  public long countPubliesByEvenement(UUID evenementId) {
    return count(
        "evenement.id = ?1 and moderationStatut = 'PUBLIE' and actif = true", evenementId);
  }

  /**
   * Liste les feedbacks en attente de modération
   *
   * @return Liste des feedbacks en attente
   */
  public List<FeedbackEvenement> findEnAttente() {
    return find(
            "moderationStatut = 'EN_ATTENTE' and actif = true order by dateFeedback desc")
        .list();
  }
}
