package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.EcritureComptable;
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
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é EcritureComptable
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@ApplicationScoped
public class EcritureComptableRepository implements PanacheRepositoryBase<EcritureComptable, UUID> {

  /**
   * Trouve une écriture comptable par son UUID
   *
   * @param id UUID de l'écriture comptable
   * @return Écriture comptable ou Optional.empty()
   */
  public Optional<EcritureComptable> findEcritureComptableById(UUID id) {
    return find("id = ?1 AND actif = true", id).firstResultOptional();
  }

  /**
   * Trouve une écriture par son numéro de pièce
   *
   * @param numeroPiece Numéro de pièce
   * @return Écriture ou Optional.empty()
   */
  public Optional<EcritureComptable> findByNumeroPiece(String numeroPiece) {
    return find("numeroPiece = ?1 AND actif = true", numeroPiece).firstResultOptional();
  }

  /**
   * Trouve les écritures d'un journal
   *
   * @param journalId ID du journal
   * @return Liste des écritures
   */
  public List<EcritureComptable> findByJournalId(UUID journalId) {
    return find("journal.id = ?1 AND actif = true ORDER BY dateEcriture DESC, numeroPiece ASC", journalId)
        .list();
  }

  /**
   * Trouve les écritures d'une organisation
   *
   * @param organisationId ID de l'organisation
   * @return Liste des écritures
   */
  public List<EcritureComptable> findByOrganisationId(UUID organisationId) {
    return find(
            "organisation.id = ?1 AND actif = true ORDER BY dateEcriture DESC, numeroPiece ASC",
            organisationId)
        .list();
  }

  /**
   * Trouve les écritures d'un paiement
   *
   * @param paiementId ID du paiement
   * @return Liste des écritures
   */
  public List<EcritureComptable> findByPaiementId(UUID paiementId) {
    return find("paiement.id = ?1 AND actif = true ORDER BY dateEcriture DESC", paiementId).list();
  }

  /**
   * Trouve les écritures dans une période
   *
   * @param dateDebut Date de début
   * @param dateFin Date de fin
   * @return Liste des écritures
   */
  public List<EcritureComptable> findByPeriode(LocalDate dateDebut, LocalDate dateFin) {
    return find(
            "dateEcriture >= ?1 AND dateEcriture <= ?2 AND actif = true ORDER BY dateEcriture DESC, numeroPiece ASC",
            dateDebut,
            dateFin)
        .list();
  }

  /**
   * Trouve les écritures non pointées
   *
   * @return Liste des écritures non pointées
   */
  public List<EcritureComptable> findNonPointees() {
    return find("pointe = false AND actif = true ORDER BY dateEcriture ASC").list();
  }

  /**
   * Trouve les écritures avec un lettrage spécifique
   *
   * @param lettrage Lettrage
   * @return Liste des écritures
   */
  public List<EcritureComptable> findByLettrage(String lettrage) {
    return find("lettrage = ?1 AND actif = true ORDER BY dateEcriture DESC", lettrage).list();
  }

  /**
   * Trouve les écritures d'une organisation dans une période (pour rapports PDF SYSCOHADA).
   */
  public List<EcritureComptable> findByOrganisationAndDateRange(
      UUID organisationId, LocalDate dateDebut, LocalDate dateFin) {
    return find(
            "organisation.id = ?1 AND dateEcriture >= ?2 AND dateEcriture <= ?3 AND actif = true"
                + " ORDER BY dateEcriture ASC, numeroPiece ASC",
            organisationId,
            dateDebut,
            dateFin)
        .list();
  }
}



