package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.api.enums.wave.StatutWebhook;
import dev.lions.unionflow.server.api.enums.wave.TypeEvenementWebhook;
import dev.lions.unionflow.server.entity.WebhookWave;
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é WebhookWave
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@ApplicationScoped
public class WebhookWaveRepository implements PanacheRepositoryBase<WebhookWave, UUID> {

  /**
   * Trouve un webhook Wave par son UUID
   *
   * @param id UUID du webhook
   * @return Webhook ou Optional.empty()
   */
  public Optional<WebhookWave> findWebhookWaveById(UUID id) {
    return find("id = ?1", id).firstResultOptional();
  }

  /**
   * Trouve un webhook par son identifiant d'événement Wave
   *
   * @param waveEventId Identifiant d'événement
   * @return Webhook ou Optional.empty()
   */
  public Optional<WebhookWave> findByWaveEventId(String waveEventId) {
    return find("waveEventId = ?1", waveEventId).firstResultOptional();
  }

  /**
   * Trouve tous les webhooks d'une transaction
   *
   * @param transactionWaveId ID de la transaction
   * @return Liste des webhooks
   */
  public List<WebhookWave> findByTransactionWaveId(UUID transactionWaveId) {
    return find("transactionWave.id = ?1 ORDER BY dateReception DESC", transactionWaveId).list();
  }

  /**
   * Trouve tous les webhooks d'un paiement
   *
   * @param paiementId ID du paiement
   * @return Liste des webhooks
   */
  public List<WebhookWave> findByPaiementId(UUID paiementId) {
    return find("paiement.id = ?1 ORDER BY dateReception DESC", paiementId).list();
  }

  /**
   * Trouve les webhooks par statut (statutTraitement est stocké en String).
   *
   * @param statut Statut de traitement
   * @return Liste des webhooks
   */
  public List<WebhookWave> findByStatut(StatutWebhook statut) {
    return find("statutTraitement = ?1 ORDER BY dateReception DESC", statut.name()).list();
  }

  /**
   * Trouve les webhooks par type d'événement (typeEvenement est stocké en String).
   *
   * @param type Type d'événement
   * @return Liste des webhooks
   */
  public List<WebhookWave> findByType(TypeEvenementWebhook type) {
    return find("typeEvenement = ?1 ORDER BY dateReception DESC", type.name()).list();
  }

  /**
   * Trouve les webhooks en attente de traitement
   *
   * @return Liste des webhooks en attente
   */
  public List<WebhookWave> findEnAttente() {
    return find("statutTraitement = ?1 ORDER BY dateReception ASC", StatutWebhook.EN_ATTENTE.name())
        .list();
  }

  /**
   * Trouve les webhooks échoués pouvant être retentés
   *
   * @return Liste des webhooks échoués
   */
  public List<WebhookWave> findEchouesRetentables() {
    return find(
            "statutTraitement = ?1 AND (nombreTentatives IS NULL OR nombreTentatives < 5) ORDER BY dateReception ASC",
            StatutWebhook.ECHOUE.name())
        .list();
  }
}



