package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.Adresse;
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 l'entité Adresse
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@ApplicationScoped
public class AdresseRepository implements PanacheRepositoryBase<Adresse, UUID> {

  /**
   * Trouve une adresse par son UUID
   *
   * @param id UUID de l'adresse
   * @return Adresse ou Optional.empty()
   */
  public Optional<Adresse> findAdresseById(UUID id) {
    return find("id = ?1", id).firstResultOptional();
  }

  /**
   * Trouve toutes les adresses d'une organisation
   *
   * @param organisationId ID de l'organisation
   * @return Liste des adresses
   */
  public List<Adresse> findByOrganisationId(UUID organisationId) {
    return find("organisation.id", organisationId).list();
  }

  /**
   * Trouve l'adresse principale d'une organisation
   *
   * @param organisationId ID de l'organisation
   * @return Adresse principale ou Optional.empty()
   */
  public Optional<Adresse> findPrincipaleByOrganisationId(UUID organisationId) {
    return find("organisation.id = ?1 AND principale = true", organisationId).firstResultOptional();
  }

  /**
   * Trouve toutes les adresses d'un membre
   *
   * @param membreId ID du membre
   * @return Liste des adresses
   */
  public List<Adresse> findByMembreId(UUID membreId) {
    return find("membre.id", membreId).list();
  }

  /**
   * Trouve l'adresse principale d'un membre
   *
   * @param membreId ID du membre
   * @return Adresse principale ou Optional.empty()
   */
  public Optional<Adresse> findPrincipaleByMembreId(UUID membreId) {
    return find("membre.id = ?1 AND principale = true", membreId).firstResultOptional();
  }

  /**
   * Trouve l'adresse d'un événement
   *
   * @param evenementId ID de l'événement
   * @return Adresse ou Optional.empty()
   */
  public Optional<Adresse> findByEvenementId(UUID evenementId) {
    return find("evenement.id", evenementId).firstResultOptional();
  }

  /**
   * Trouve les adresses par type
   *
   * @param typeAdresse Type d'adresse (String code)
   * @return Liste des adresses
   */
  public List<Adresse> findByType(String typeAdresse) {
    return find("typeAdresse", typeAdresse).list();
  }

  /**
   * Trouve les adresses par ville
   *
   * @param ville Nom de la ville
   * @return Liste des adresses
   */
  public List<Adresse> findByVille(String ville) {
    return find("LOWER(ville) = LOWER(?1)", ville).list();
  }

  /**
   * Trouve les adresses par pays
   *
   * @param pays Nom du pays
   * @return Liste des adresses
   */
  public List<Adresse> findByPays(String pays) {
    return find("LOWER(pays) = LOWER(?1)", pays).list();
  }
}
