package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.AlerteLcbFt;
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 pour la gestion des alertes LCB-FT.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-15
 */
@ApplicationScoped
public class AlerteLcbFtRepository implements PanacheRepositoryBase<AlerteLcbFt, UUID> {

    /**
     * Recherche les alertes avec filtres et pagination
     */
    public List<AlerteLcbFt> search(
            UUID organisationId,
            String typeAlerte,
            Boolean traitee,
            LocalDateTime dateDebut,
            LocalDateTime dateFin,
            int pageIndex,
            int pageSize
    ) {
        StringBuilder jpql = new StringBuilder("SELECT a FROM AlerteLcbFt a WHERE a.actif = true");

        if (organisationId != null) {
            jpql.append(" AND a.organisation.id = :organisationId");
        }

        if (typeAlerte != null && !typeAlerte.isBlank()) {
            jpql.append(" AND a.typeAlerte = :typeAlerte");
        }

        if (traitee != null) {
            jpql.append(" AND a.traitee = :traitee");
        }

        if (dateDebut != null) {
            jpql.append(" AND a.dateAlerte >= :dateDebut");
        }

        if (dateFin != null) {
            jpql.append(" AND a.dateAlerte <= :dateFin");
        }

        jpql.append(" ORDER BY a.dateAlerte DESC");

        var query = getEntityManager().createQuery(jpql.toString(), AlerteLcbFt.class);

        if (organisationId != null) {
            query.setParameter("organisationId", organisationId);
        }

        if (typeAlerte != null && !typeAlerte.isBlank()) {
            query.setParameter("typeAlerte", typeAlerte);
        }

        if (traitee != null) {
            query.setParameter("traitee", traitee);
        }

        if (dateDebut != null) {
            query.setParameter("dateDebut", dateDebut);
        }

        if (dateFin != null) {
            query.setParameter("dateFin", dateFin);
        }

        query.setFirstResult(pageIndex * pageSize);
        query.setMaxResults(pageSize);

        return query.getResultList();
    }

    /**
     * Compte le nombre d'alertes avec filtres
     */
    public long count(
            UUID organisationId,
            String typeAlerte,
            Boolean traitee,
            LocalDateTime dateDebut,
            LocalDateTime dateFin
    ) {
        StringBuilder jpql = new StringBuilder("SELECT COUNT(a) FROM AlerteLcbFt a WHERE a.actif = true");

        if (organisationId != null) {
            jpql.append(" AND a.organisation.id = :organisationId");
        }

        if (typeAlerte != null && !typeAlerte.isBlank()) {
            jpql.append(" AND a.typeAlerte = :typeAlerte");
        }

        if (traitee != null) {
            jpql.append(" AND a.traitee = :traitee");
        }

        if (dateDebut != null) {
            jpql.append(" AND a.dateAlerte >= :dateDebut");
        }

        if (dateFin != null) {
            jpql.append(" AND a.dateAlerte <= :dateFin");
        }

        var query = getEntityManager().createQuery(jpql.toString(), Long.class);

        if (organisationId != null) {
            query.setParameter("organisationId", organisationId);
        }

        if (typeAlerte != null && !typeAlerte.isBlank()) {
            query.setParameter("typeAlerte", typeAlerte);
        }

        if (traitee != null) {
            query.setParameter("traitee", traitee);
        }

        if (dateDebut != null) {
            query.setParameter("dateDebut", dateDebut);
        }

        if (dateFin != null) {
            query.setParameter("dateFin", dateFin);
        }

        return query.getSingleResult();
    }

    /**
     * Compte les alertes non traitées pour une organisation
     */
    public long countNonTraitees(UUID organisationId) {
        if (organisationId == null) {
            return count("traitee = false and actif = true");
        }
        return count("organisation.id = ?1 and traitee = false and actif = true", organisationId);
    }
}
