package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.Evenement;
import dev.lions.unionflow.server.entity.InscriptionEvenement;
import dev.lions.unionflow.server.entity.Membre;
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 inscriptions aux événements
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-16
 */
@ApplicationScoped
public class InscriptionEvenementRepository
    implements PanacheRepositoryBase<InscriptionEvenement, UUID> {

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

  /**
   * Liste toutes les inscriptions d'un membre
   *
   * @param membreId UUID du membre
   * @return Liste des inscriptions
   */
  public List<InscriptionEvenement> findByMembre(UUID membreId) {
    return find(
            "membre.id = ?1 and actif = true order by dateInscription desc",
            membreId)
        .list();
  }

  /**
   * Liste toutes les inscriptions à un événement
   *
   * @param evenementId UUID de l'événement
   * @return Liste des inscriptions
   */
  public List<InscriptionEvenement> findByEvenement(UUID evenementId) {
    return find(
            "evenement.id = ?1 and actif = true order by dateInscription asc",
            evenementId)
        .list();
  }

  /**
   * Liste les inscriptions confirmées pour un événement
   *
   * @param evenementId UUID de l'événement
   * @return Liste des inscriptions confirmées
   */
  public List<InscriptionEvenement> findConfirmeesByEvenement(UUID evenementId) {
    return find(
            "evenement.id = ?1 and statut = 'CONFIRMEE' and actif = true order by dateInscription asc",
            evenementId)
        .list();
  }

  /**
   * Compte le nombre d'inscriptions confirmées pour un événement
   *
   * @param evenementId UUID de l'événement
   * @return Nombre d'inscriptions confirmées
   */
  public long countConfirmeesByEvenement(UUID evenementId) {
    return count(
        "evenement.id = ?1 and statut = 'CONFIRMEE' and actif = true", evenementId);
  }

  /**
   * Vérifie si un membre est inscrit à un événement
   *
   * @param membreId UUID du membre
   * @param evenementId UUID de l'événement
   * @return true si le membre est inscrit et l'inscription est confirmée
   */
  public boolean isMembreInscrit(UUID membreId, UUID evenementId) {
    return count(
            "membre.id = ?1 and evenement.id = ?2 and statut = 'CONFIRMEE' and actif = true",
            membreId,
            evenementId)
        > 0;
  }

  /**
   * Compte le nombre d'inscriptions actives d'un membre
   *
   * @param membreId UUID du membre
   * @return Nombre d'inscriptions actives
   */
  public long countByMembre(UUID membreId) {
    return count("membre.id = ?1 and actif = true", membreId);
  }

  /**
   * Supprime logiquement une inscription
   *
   * @param inscription L'inscription à supprimer
   */
  public void softDelete(InscriptionEvenement inscription) {
    inscription.setActif(false);
    persist(inscription);
  }
}
