package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.AlertConfiguration;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.TestTransaction;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Tests d'intégration pour AlertConfigurationRepository.
 *
 * <p>Couvre les méthodes : getConfiguration (existing + create), updateConfiguration,
 * isCpuAlertEnabled, isMemoryAlertEnabled, getCpuThreshold, getMemoryThreshold.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-21
 */
@QuarkusTest
class AlertConfigurationRepositoryTest {

    @Inject
    AlertConfigurationRepository alertConfigurationRepository;

    // -------------------------------------------------------------------------
    // getConfiguration — création par défaut (branche else, lignes 42-45)
    // -------------------------------------------------------------------------

    @Test
    @TestTransaction
    @DisplayName("getConfiguration crée une configuration par défaut si aucune n'existe")
    void getConfiguration_noExisting_createsDefault() {
        // Supprimer toutes les configurations existantes pour tester la branche création
        alertConfigurationRepository.listAll().forEach(alertConfigurationRepository::delete);

        AlertConfiguration config = alertConfigurationRepository.getConfiguration();

        assertThat(config).isNotNull();
        assertThat(config.getId()).isNotNull();
        // Valeurs par défaut de l'entité
        assertThat(config.getCpuHighAlertEnabled()).isTrue();
        assertThat(config.getCpuThresholdPercent()).isEqualTo(80);
        assertThat(config.getMemoryLowAlertEnabled()).isTrue();
    }

    // -------------------------------------------------------------------------
    // getConfiguration — récupération existante (branche if, ligne 39)
    // -------------------------------------------------------------------------

    @Test
    @TestTransaction
    @DisplayName("getConfiguration retourne la configuration existante (branche présente)")
    void getConfiguration_existing_returnsExisting() {
        // S'assurer qu'une configuration existe
        AlertConfiguration first = alertConfigurationRepository.getConfiguration();
        assertThat(first).isNotNull();
        first.setCpuThresholdPercent(75);
        alertConfigurationRepository.persist(first);

        // Deuxième appel : doit retourner la configuration existante (branche if, ligne 39)
        AlertConfiguration second = alertConfigurationRepository.getConfiguration();
        assertThat(second).isNotNull();
        // Doit retourner la même configuration (ou au moins une valeur persistée)
        assertThat(second.getCpuThresholdPercent()).isEqualTo(75);
    }

    // -------------------------------------------------------------------------
    // updateConfiguration (lignes 52-71)
    // -------------------------------------------------------------------------

    @Test
    @TestTransaction
    @DisplayName("updateConfiguration met à jour tous les champs de la configuration")
    void updateConfiguration_updatesAllFields() {
        // S'assurer qu'une config de base existe
        alertConfigurationRepository.getConfiguration();

        AlertConfiguration update = new AlertConfiguration();
        update.setCpuHighAlertEnabled(false);
        update.setCpuThresholdPercent(90);
        update.setCpuDurationMinutes(10);
        update.setMemoryLowAlertEnabled(false);
        update.setMemoryThresholdPercent(70);
        update.setCriticalErrorAlertEnabled(false);
        update.setErrorAlertEnabled(false);
        update.setConnectionFailureAlertEnabled(false);
        update.setConnectionFailureThreshold(50);
        update.setConnectionFailureWindowMinutes(15);
        update.setEmailNotificationsEnabled(false);
        update.setPushNotificationsEnabled(true);
        update.setSmsNotificationsEnabled(true);
        update.setAlertEmailRecipients("new@unionflow.test,admin@unionflow.test");

        AlertConfiguration result = alertConfigurationRepository.updateConfiguration(update);

        assertThat(result).isNotNull();
        assertThat(result.getCpuHighAlertEnabled()).isFalse();
        assertThat(result.getCpuThresholdPercent()).isEqualTo(90);
        assertThat(result.getCpuDurationMinutes()).isEqualTo(10);
        assertThat(result.getMemoryLowAlertEnabled()).isFalse();
        assertThat(result.getMemoryThresholdPercent()).isEqualTo(70);
        assertThat(result.getCriticalErrorAlertEnabled()).isFalse();
        assertThat(result.getErrorAlertEnabled()).isFalse();
        assertThat(result.getConnectionFailureAlertEnabled()).isFalse();
        assertThat(result.getConnectionFailureThreshold()).isEqualTo(50);
        assertThat(result.getConnectionFailureWindowMinutes()).isEqualTo(15);
        assertThat(result.getEmailNotificationsEnabled()).isFalse();
        assertThat(result.getPushNotificationsEnabled()).isTrue();
        assertThat(result.getSmsNotificationsEnabled()).isTrue();
        assertThat(result.getAlertEmailRecipients()).isEqualTo("new@unionflow.test,admin@unionflow.test");
    }

    // -------------------------------------------------------------------------
    // isCpuAlertEnabled (ligne 78)
    // -------------------------------------------------------------------------

    @Test
    @TestTransaction
    @DisplayName("isCpuAlertEnabled retourne l'état d'activation de l'alerte CPU")
    void isCpuAlertEnabled_returnsConfigValue() {
        // S'assurer qu'une configuration existe avec une valeur connue
        AlertConfiguration config = alertConfigurationRepository.getConfiguration();
        boolean expected = config.getCpuHighAlertEnabled();

        boolean result = alertConfigurationRepository.isCpuAlertEnabled();

        assertThat(result).isEqualTo(expected);
    }

    // -------------------------------------------------------------------------
    // isMemoryAlertEnabled (ligne 85)
    // -------------------------------------------------------------------------

    @Test
    @TestTransaction
    @DisplayName("isMemoryAlertEnabled retourne l'état d'activation de l'alerte mémoire")
    void isMemoryAlertEnabled_returnsConfigValue() {
        AlertConfiguration config = alertConfigurationRepository.getConfiguration();
        boolean expected = config.getMemoryLowAlertEnabled();

        boolean result = alertConfigurationRepository.isMemoryAlertEnabled();

        assertThat(result).isEqualTo(expected);
    }

    // -------------------------------------------------------------------------
    // getCpuThreshold (ligne 92)
    // -------------------------------------------------------------------------

    @Test
    @TestTransaction
    @DisplayName("getCpuThreshold retourne le seuil CPU configuré")
    void getCpuThreshold_returnsConfiguredThreshold() {
        // Configurer un seuil spécifique
        AlertConfiguration update = new AlertConfiguration();
        update.setCpuHighAlertEnabled(true);
        update.setCpuThresholdPercent(65);
        update.setCpuDurationMinutes(5);
        update.setMemoryLowAlertEnabled(true);
        update.setMemoryThresholdPercent(85);
        update.setCriticalErrorAlertEnabled(true);
        update.setErrorAlertEnabled(true);
        update.setConnectionFailureAlertEnabled(true);
        update.setConnectionFailureThreshold(100);
        update.setConnectionFailureWindowMinutes(5);
        update.setEmailNotificationsEnabled(true);
        update.setPushNotificationsEnabled(false);
        update.setSmsNotificationsEnabled(false);
        update.setAlertEmailRecipients("admin@unionflow.test");
        alertConfigurationRepository.updateConfiguration(update);

        int threshold = alertConfigurationRepository.getCpuThreshold();

        assertThat(threshold).isEqualTo(65);
    }

    // -------------------------------------------------------------------------
    // getMemoryThreshold (ligne 99)
    // -------------------------------------------------------------------------

    @Test
    @TestTransaction
    @DisplayName("getMemoryThreshold retourne le seuil mémoire configuré")
    void getMemoryThreshold_returnsConfiguredThreshold() {
        AlertConfiguration update = new AlertConfiguration();
        update.setCpuHighAlertEnabled(true);
        update.setCpuThresholdPercent(80);
        update.setCpuDurationMinutes(5);
        update.setMemoryLowAlertEnabled(true);
        update.setMemoryThresholdPercent(72);
        update.setCriticalErrorAlertEnabled(true);
        update.setErrorAlertEnabled(true);
        update.setConnectionFailureAlertEnabled(true);
        update.setConnectionFailureThreshold(100);
        update.setConnectionFailureWindowMinutes(5);
        update.setEmailNotificationsEnabled(true);
        update.setPushNotificationsEnabled(false);
        update.setSmsNotificationsEnabled(false);
        update.setAlertEmailRecipients("admin@unionflow.test");
        alertConfigurationRepository.updateConfiguration(update);

        int threshold = alertConfigurationRepository.getMemoryThreshold();

        assertThat(threshold).isEqualTo(72);
    }
}
