package dev.lions.unionflow.server.repository;

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

  /**
   * Trouve un journal comptable par son UUID
   *
   * @param id UUID du journal comptable
   * @return Journal comptable ou Optional.empty()
   */
  public Optional<JournalComptable> findJournalComptableById(UUID id) {
    return find("id = ?1 AND actif = true", id).firstResultOptional();
  }

  /**
   * Trouve un journal par son code
   *
   * @param code Code du journal
   * @return Journal ou Optional.empty()
   */
  public Optional<JournalComptable> findByCode(String code) {
    return find("code = ?1 AND actif = true", code).firstResultOptional();
  }

  /**
   * Trouve les journaux par type
   *
   * @param type Type de journal
   * @return Liste des journaux
   */
  public List<JournalComptable> findByType(TypeJournalComptable type) {
    return find("typeJournal = ?1 AND actif = true ORDER BY code ASC", type).list();
  }

  /**
   * Trouve les journaux ouverts
   *
   * @return Liste des journaux ouverts
   */
  public List<JournalComptable> findJournauxOuverts() {
    return find("statut = ?1 AND actif = true ORDER BY code ASC", "OUVERT").list();
  }

  /**
   * Trouve les journaux pour une date donnée
   *
   * @param date Date à vérifier
   * @return Liste des journaux actifs pour cette date
   */
  public List<JournalComptable> findJournauxPourDate(LocalDate date) {
    return find(
            "(dateDebut IS NULL OR dateDebut <= ?1) AND (dateFin IS NULL OR dateFin >= ?1) AND actif = true ORDER BY code ASC",
            date)
        .list();
  }

  /**
   * Trouve tous les journaux actifs
   *
   * @return Liste des journaux actifs
   */
  public List<JournalComptable> findAllActifs() {
    return find("actif = true ORDER BY code ASC").list();
  }

  /**
   * Trouve le journal d'une organisation par type (ex: VENTES pour cotisations).
   */
  public Optional<JournalComptable> findByOrganisationAndType(UUID organisationId, TypeJournalComptable type) {
    return find(
        "organisation.id = ?1 AND typeJournal = ?2 AND statut = 'OUVERT' AND actif = true",
        organisationId, type).firstResultOptional();
  }
}



