package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.AuditTrailOperation;
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
import jakarta.enterprise.context.ApplicationScoped;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * Repository Panache pour l'audit trail enrichi.
 *
 * @since 2026-04-25
 */
@ApplicationScoped
public class AuditTrailOperationRepository
    implements PanacheRepositoryBase<AuditTrailOperation, UUID> {

  /** Opérations d'un utilisateur dans une fenêtre temporelle. */
  public List<AuditTrailOperation> findByUserBetween(UUID userId, LocalDateTime from, LocalDateTime to) {
    return list("userId = ?1 AND operationAt BETWEEN ?2 AND ?3 ORDER BY operationAt DESC",
        userId, from, to);
  }

  /** Opérations sur une entité spécifique (ex: pour bouton "voir l'historique"). */
  public List<AuditTrailOperation> findByEntity(String entityType, UUID entityId) {
    return list("entityType = ?1 AND entityId = ?2 ORDER BY operationAt DESC",
        entityType, entityId);
  }

  /** Opérations dans le contexte d'une organisation. */
  public List<AuditTrailOperation> findByOrganisationActive(UUID organisationActiveId) {
    return list("organisationActiveId = ?1 ORDER BY operationAt DESC", organisationActiveId);
  }

  /** Violations SoD détectées (alertes compliance officer). */
  public List<AuditTrailOperation> findSoDViolations() {
    return list("sodCheckPassed = false ORDER BY operationAt DESC");
  }

  /** Opérations financières (paiements, budgets, écritures comptables) pour reporting AIRMS. */
  public List<AuditTrailOperation> findFinancialOperations(UUID organisationId, LocalDateTime from, LocalDateTime to) {
    return list(
        "organisationActiveId = ?1 AND operationAt BETWEEN ?2 AND ?3 "
            + "AND actionType IN ('PAYMENT_INITIATED', 'PAYMENT_CONFIRMED', 'PAYMENT_FAILED', "
            + "'BUDGET_APPROVED', 'AID_REQUEST_APPROVED') "
            + "ORDER BY operationAt DESC",
        organisationId, from, to);
  }

  /** N opérations les plus récentes — toutes organisations confondues (Live Feed). */
  public List<AuditTrailOperation> findRecent(int limit) {
    return find("ORDER BY operationAt DESC").page(0, Math.max(1, Math.min(limit, 500))).list();
  }

  /** N opérations les plus récentes pour une organisation. */
  public List<AuditTrailOperation> findRecentByOrganisation(UUID organisationId, int limit) {
    return find("organisationActiveId = ?1 ORDER BY operationAt DESC", organisationId)
        .page(0, Math.max(1, Math.min(limit, 500))).list();
  }

  /** N opérations les plus récentes d'un utilisateur. */
  public List<AuditTrailOperation> findRecentByUser(UUID userId, int limit) {
    return find("userId = ?1 ORDER BY operationAt DESC", userId)
        .page(0, Math.max(1, Math.min(limit, 500))).list();
  }
}
