package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.MembreRole;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * Repository pour l'entité MembreRole
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@ApplicationScoped
public class MembreRoleRepository implements PanacheRepository<MembreRole> {

  /**
   * Trouve une attribution membre-role par son UUID
   *
   * @param id UUID de l'attribution
   * @return Attribution ou Optional.empty()
   */
  public Optional<MembreRole> findMembreRoleById(UUID id) {
    return find("id = ?1 AND actif = true", id).firstResultOptional();
  }

  /**
   * Trouve tous les rôles d'un membre
   *
   * @param membreId ID du membre
   * @return Liste des attributions de rôles
   */
  public List<MembreRole> findByMembreId(UUID membreId) {
    return find("membreOrganisation.membre.id = ?1 AND actif = true", membreId).list();
  }

  /**
   * Trouve tous les rôles actifs d'un membre (dans la période valide)
   *
   * @param membreId ID du membre
   * @return Liste des attributions de rôles actives
   */
  public List<MembreRole> findActifsByMembreId(UUID membreId) {
    LocalDate aujourdhui = LocalDate.now();
    return find(
            "membreOrganisation.membre.id = ?1 AND actif = true"
                + " AND (dateDebut IS NULL OR dateDebut <= ?2)"
                + " AND (dateFin IS NULL OR dateFin >= ?2)",
            membreId,
            aujourdhui)
        .list();
  }

  /**
   * Trouve tous les membres ayant un rôle spécifique
   *
   * @param roleId ID du rôle
   * @return Liste des attributions de rôles
   */
  public List<MembreRole> findByRoleId(UUID roleId) {
    return find("role.id = ?1 AND actif = true", roleId).list();
  }

  /**
   * Trouve une attribution spécifique membre-role
   *
   * @param membreId ID du membre
   * @param roleId ID du rôle
   * @return Attribution ou null
   */
  public MembreRole findByMembreAndRole(UUID membreId, UUID roleId) {
    return find("membreOrganisation.membre.id = ?1 AND role.id = ?2", membreId, roleId)
        .firstResult();
  }
}

