package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.SystemAlert;
import io.quarkus.arc.Unremovable;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.TypedQuery;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * Repository pour l'entité SystemAlert
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-15
 */
@ApplicationScoped
@Unremovable
public class SystemAlertRepository extends BaseRepository<SystemAlert> {

    public SystemAlertRepository() {
        super(SystemAlert.class);
    }

    /**
     * Récupérer toutes les alertes actives (non acquittées)
     */
    public List<SystemAlert> findActiveAlerts() {
        TypedQuery<SystemAlert> query = entityManager.createQuery(
                "SELECT a FROM SystemAlert a WHERE a.acknowledged = false ORDER BY a.timestamp DESC",
                SystemAlert.class
        );
        return query.getResultList();
    }

    /**
     * Récupérer toutes les alertes acquittées
     */
    public List<SystemAlert> findAcknowledgedAlerts() {
        TypedQuery<SystemAlert> query = entityManager.createQuery(
                "SELECT a FROM SystemAlert a WHERE a.acknowledged = true ORDER BY a.timestamp DESC",
                SystemAlert.class
        );
        return query.getResultList();
    }

    /**
     * Récupérer les alertes par niveau
     */
    public List<SystemAlert> findByLevel(String level) {
        TypedQuery<SystemAlert> query = entityManager.createQuery(
                "SELECT a FROM SystemAlert a WHERE a.level = :level ORDER BY a.timestamp DESC",
                SystemAlert.class
        );
        query.setParameter("level", level);
        return query.getResultList();
    }

    /**
     * Récupérer les alertes critiques non acquittées
     */
    public List<SystemAlert> findCriticalUnacknowledged() {
        TypedQuery<SystemAlert> query = entityManager.createQuery(
                "SELECT a FROM SystemAlert a WHERE a.level = 'CRITICAL' AND a.acknowledged = false ORDER BY a.timestamp DESC",
                SystemAlert.class
        );
        return query.getResultList();
    }

    /**
     * Récupérer les alertes par source
     */
    public List<SystemAlert> findBySource(String source) {
        TypedQuery<SystemAlert> query = entityManager.createQuery(
                "SELECT a FROM SystemAlert a WHERE a.source = :source ORDER BY a.timestamp DESC",
                SystemAlert.class
        );
        query.setParameter("source", source);
        return query.getResultList();
    }

    /**
     * Acquitter une alerte
     */
    public void acknowledgeAlert(UUID alertId, String acknowledgedBy) {
        SystemAlert alert = findById(alertId);
        if (alert != null) {
            alert.setAcknowledged(true);
            alert.setAcknowledgedBy(acknowledgedBy);
            alert.setAcknowledgedAt(LocalDateTime.now());
            persist(alert);
        }
    }

    /**
     * Compter les alertes actives
     */
    public long countActive() {
        TypedQuery<Long> query = entityManager.createQuery(
                "SELECT COUNT(a) FROM SystemAlert a WHERE a.acknowledged = false",
                Long.class
        );
        return query.getSingleResult();
    }

    /**
     * Compter les alertes dans les dernières 24h
     */
    public long countLast24h() {
        LocalDateTime yesterday = LocalDateTime.now().minusHours(24);
        TypedQuery<Long> query = entityManager.createQuery(
                "SELECT COUNT(a) FROM SystemAlert a WHERE a.timestamp >= :yesterday",
                Long.class
        );
        query.setParameter("yesterday", yesterday);
        return query.getSingleResult();
    }

    /**
     * Compter les alertes acquittées dans les dernières 24h
     */
    public long countAcknowledgedLast24h() {
        LocalDateTime yesterday = LocalDateTime.now().minusHours(24);
        TypedQuery<Long> query = entityManager.createQuery(
                "SELECT COUNT(a) FROM SystemAlert a WHERE a.acknowledged = true AND a.timestamp >= :yesterday",
                Long.class
        );
        query.setParameter("yesterday", yesterday);
        return query.getSingleResult();
    }

    /**
     * Supprimer les alertes plus anciennes qu'une date donnée (rotation)
     */
    public int deleteOlderThan(LocalDateTime threshold) {
        return entityManager.createQuery(
                "DELETE FROM SystemAlert a WHERE a.timestamp < :threshold"
        )
        .setParameter("threshold", threshold)
        .executeUpdate();
    }

    /**
     * Récupérer les alertes dans une période
     */
    public List<SystemAlert> findByTimestampBetween(LocalDateTime start, LocalDateTime end) {
        TypedQuery<SystemAlert> query = entityManager.createQuery(
                "SELECT a FROM SystemAlert a WHERE a.timestamp BETWEEN :start AND :end ORDER BY a.timestamp DESC",
                SystemAlert.class
        );
        query.setParameter("start", start);
        query.setParameter("end", end);
        return query.getResultList();
    }
}
