package dev.lions.unionflow.server.repository;

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

  /**
   * Trouve une transaction par son UUID
   *
   * @param id UUID de la transaction
   * @return Transaction ou Optional.empty()
   */
  public Optional<TransactionWave> findTransactionWaveById(UUID id) {
    return find("id = ?1", id).firstResultOptional();
  }

  /**
   * Trouve une transaction par son identifiant Wave
   *
   * @param waveTransactionId Identifiant Wave
   * @return Transaction ou Optional.empty()
   */
  public Optional<TransactionWave> findByWaveTransactionId(String waveTransactionId) {
    return find("waveTransactionId = ?1", waveTransactionId).firstResultOptional();
  }

  /**
   * Trouve une transaction par son identifiant de requête
   *
   * @param waveRequestId Identifiant de requête
   * @return Transaction ou Optional.empty()
   */
  public Optional<TransactionWave> findByWaveRequestId(String waveRequestId) {
    return find("waveRequestId = ?1", waveRequestId).firstResultOptional();
  }

  /**
   * Trouve toutes les transactions d'un compte Wave
   *
   * @param compteWaveId ID du compte Wave
   * @return Liste des transactions
   */
  public List<TransactionWave> findByCompteWaveId(UUID compteWaveId) {
    return find("compteWave.id = ?1 ORDER BY dateCreation DESC", compteWaveId).list();
  }

  /**
   * Trouve les transactions par statut
   *
   * @param statut Statut de la transaction
   * @return Liste des transactions
   */
  public List<TransactionWave> findByStatut(StatutTransactionWave statut) {
    return find("statutTransaction = ?1 ORDER BY dateCreation DESC", statut).list();
  }

  /**
   * Trouve les transactions par type
   *
   * @param type Type de transaction
   * @return Liste des transactions
   */
  public List<TransactionWave> findByType(TypeTransactionWave type) {
    return find("typeTransaction = ?1 ORDER BY dateCreation DESC", type).list();
  }

  /**
   * Trouve les transactions réussies dans une période
   *
   * @param compteWaveId ID du compte Wave
   * @return Liste des transactions réussies
   */
  public List<TransactionWave> findReussiesByCompteWave(UUID compteWaveId) {
    return find(
            "compteWave.id = ?1 AND statutTransaction = ?2 ORDER BY dateCreation DESC",
            compteWaveId,
            StatutTransactionWave.REUSSIE)
        .list();
  }

  /**
   * Trouve les transactions échouées pouvant être retentées
   *
   * @return Liste des transactions échouées
   */
  public List<TransactionWave> findEchoueesRetentables() {
    return find(
            "statutTransaction IN (?1, ?2) AND (nombreTentatives IS NULL OR nombreTentatives < 5) ORDER BY dateCreation ASC",
            StatutTransactionWave.ECHOUE,
            StatutTransactionWave.EXPIRED)
        .list();
  }
}



