package dev.lions.unionflow.server.api.dto.formuleabonnement;

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

import dev.lions.unionflow.server.api.dto.formuleabonnement.FormuleAbonnementDTO.StatutFormule;
import dev.lions.unionflow.server.api.dto.formuleabonnement.FormuleAbonnementDTO.TypeFormule;
import java.math.BigDecimal;
import java.time.LocalDate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

/**
 * Tests unitaires complets pour FormuleAbonnementDTO.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2025-01-10
 */
@DisplayName("Tests FormuleAbonnementDTO")
class FormuleAbonnementDTOBasicTest {

  private FormuleAbonnementDTO formule;

  @BeforeEach
  void setUp() {
    formule = new FormuleAbonnementDTO();
  }

  @Nested
  @DisplayName("Tests de construction")
  class ConstructionTests {

    @Test
    @DisplayName("Constructeur par défaut - Initialisation correcte")
    void testConstructeurParDefaut() {
      FormuleAbonnementDTO newFormule = new FormuleAbonnementDTO();

      assertThat(newFormule.getId()).isNotNull();
      assertThat(newFormule.getDateCreation()).isNotNull();
      assertThat(newFormule.isActif()).isTrue();
      assertThat(newFormule.getVersion()).isEqualTo(0L);
      assertThat(newFormule.getDevise()).isEqualTo("XOF");
      assertThat(newFormule.getStatut()).isEqualTo(StatutFormule.ACTIVE);
      assertThat(newFormule.getType()).isEqualTo(TypeFormule.BASIC);
      assertThat(newFormule.getSupportTechnique()).isTrue();
      assertThat(newFormule.getFonctionnalitesAvancees()).isFalse();
      assertThat(newFormule.getApiAccess()).isFalse();
      assertThat(newFormule.getRapportsPersonnalises()).isFalse();
      assertThat(newFormule.getIntegrationsTierces()).isFalse();
      assertThat(newFormule.getSauvegardeAutomatique()).isTrue();
      assertThat(newFormule.getMultiLangues()).isFalse();
      assertThat(newFormule.getPersonnalisationInterface()).isFalse();
      assertThat(newFormule.getFormationIncluse()).isFalse();
      assertThat(newFormule.getPopulaire()).isFalse();
      assertThat(newFormule.getRecommandee()).isFalse();
      assertThat(newFormule.getPeriodeEssaiJours()).isEqualTo(0);
      assertThat(newFormule.getHeuresFormation()).isEqualTo(0);
      assertThat(newFormule.getOrdreAffichage()).isEqualTo(1);
    }

    @Test
    @DisplayName("Constructeur avec paramètres")
    void testConstructeurAvecParametres() {
      String nom = "Formule Premium";
      String code = "PREMIUM";
      TypeFormule type = TypeFormule.PREMIUM;
      BigDecimal prixMensuel = new BigDecimal("50000.00");

      FormuleAbonnementDTO newFormule = new FormuleAbonnementDTO(nom, code, type, prixMensuel);

      assertThat(newFormule.getNom()).isEqualTo(nom);
      assertThat(newFormule.getCode()).isEqualTo(code);
      assertThat(newFormule.getType()).isEqualTo(type);
      assertThat(newFormule.getPrixMensuel()).isEqualTo(prixMensuel);
      // Vérifier que les valeurs par défaut sont toujours appliquées
      assertThat(newFormule.getDevise()).isEqualTo("XOF");
      assertThat(newFormule.getStatut()).isEqualTo(StatutFormule.ACTIVE);
    }
  }

  @Nested
  @DisplayName("Tests getters/setters")
  class GettersSettersTests {

    @Test
    @DisplayName("Test getters/setters - Propriétés de base")
    void testGettersSettersProprietesBase() {
      // Données de test
      String nom = "Formule Standard";
      String code = "STANDARD";
      String description = "Description de la formule standard";
      TypeFormule type = TypeFormule.STANDARD;
      StatutFormule statut = StatutFormule.ACTIVE;
      BigDecimal prixMensuel = new BigDecimal("25000.00");
      BigDecimal prixAnnuel = new BigDecimal("250000.00");
      String devise = "EUR";

      // Test des setters
      formule.setNom(nom);
      formule.setCode(code);
      formule.setDescription(description);
      formule.setType(type);
      formule.setStatut(statut);
      formule.setPrixMensuel(prixMensuel);
      formule.setPrixAnnuel(prixAnnuel);
      formule.setDevise(devise);

      // Test des getters
      assertThat(formule.getNom()).isEqualTo(nom);
      assertThat(formule.getCode()).isEqualTo(code);
      assertThat(formule.getDescription()).isEqualTo(description);
      assertThat(formule.getType()).isEqualTo(type);
      assertThat(formule.getStatut()).isEqualTo(statut);
      assertThat(formule.getPrixMensuel()).isEqualTo(prixMensuel);
      assertThat(formule.getPrixAnnuel()).isEqualTo(prixAnnuel);
      assertThat(formule.getDevise()).isEqualTo(devise);
    }

    @Test
    @DisplayName("Test getters/setters - Limites et capacités")
    void testGettersSettersLimitesCapacites() {
      // Données de test
      Integer maxMembres = 100;
      Integer maxAdministrateurs = 10;
      BigDecimal espaceStockageGB = new BigDecimal("50.5");
      Boolean supportTechnique = true;
      String niveauSupport = "PREMIUM";

      // Test des setters
      formule.setMaxMembres(maxMembres);
      formule.setMaxAdministrateurs(maxAdministrateurs);
      formule.setEspaceStockageGB(espaceStockageGB);
      formule.setSupportTechnique(supportTechnique);
      formule.setNiveauSupport(niveauSupport);

      // Test des getters
      assertThat(formule.getMaxMembres()).isEqualTo(maxMembres);
      assertThat(formule.getMaxAdministrateurs()).isEqualTo(maxAdministrateurs);
      assertThat(formule.getEspaceStockageGB()).isEqualTo(espaceStockageGB);
      assertThat(formule.getSupportTechnique()).isEqualTo(supportTechnique);
      assertThat(formule.getNiveauSupport()).isEqualTo(niveauSupport);
    }

    @Test
    @DisplayName("Test getters/setters - Fonctionnalités")
    void testGettersSettersFonctionnalites() {
      // Données de test
      Boolean fonctionnalitesAvancees = true;
      Boolean apiAccess = true;
      Boolean rapportsPersonnalises = true;
      Boolean integrationsTierces = true;
      Boolean sauvegardeAutomatique = false;
      Boolean multiLangues = true;
      Boolean personnalisationInterface = true;
      Boolean formationIncluse = true;
      Integer heuresFormation = 20;

      // Test des setters
      formule.setFonctionnalitesAvancees(fonctionnalitesAvancees);
      formule.setApiAccess(apiAccess);
      formule.setRapportsPersonnalises(rapportsPersonnalises);
      formule.setIntegrationsTierces(integrationsTierces);
      formule.setSauvegardeAutomatique(sauvegardeAutomatique);
      formule.setMultiLangues(multiLangues);
      formule.setPersonnalisationInterface(personnalisationInterface);
      formule.setFormationIncluse(formationIncluse);
      formule.setHeuresFormation(heuresFormation);

      // Test des getters
      assertThat(formule.getFonctionnalitesAvancees()).isEqualTo(fonctionnalitesAvancees);
      assertThat(formule.getApiAccess()).isEqualTo(apiAccess);
      assertThat(formule.getRapportsPersonnalises()).isEqualTo(rapportsPersonnalises);
      assertThat(formule.getIntegrationsTierces()).isEqualTo(integrationsTierces);
      assertThat(formule.getSauvegardeAutomatique()).isEqualTo(sauvegardeAutomatique);
      assertThat(formule.getMultiLangues()).isEqualTo(multiLangues);
      assertThat(formule.getPersonnalisationInterface()).isEqualTo(personnalisationInterface);
      assertThat(formule.getFormationIncluse()).isEqualTo(formationIncluse);
      assertThat(formule.getHeuresFormation()).isEqualTo(heuresFormation);
    }

    @Test
    @DisplayName("Test getters/setters - Marketing et affichage")
    void testGettersSettersMarketingAffichage() {
      // Données de test
      Boolean populaire = true;
      Boolean recommandee = false;
      Integer periodeEssaiJours = 30;
      LocalDate dateDebutValidite = LocalDate.of(2025, 1, 1);
      LocalDate dateFinValidite = LocalDate.of(2025, 12, 31);
      Integer ordreAffichage = 5;
      String couleur = "#FF5733";
      String icone = "premium-icon";
      String notes = "Notes administratives pour cette formule";

      // Test des setters
      formule.setPopulaire(populaire);
      formule.setRecommandee(recommandee);
      formule.setPeriodeEssaiJours(periodeEssaiJours);
      formule.setDateDebutValidite(dateDebutValidite);
      formule.setDateFinValidite(dateFinValidite);
      formule.setOrdreAffichage(ordreAffichage);
      formule.setCouleur(couleur);
      formule.setIcone(icone);
      formule.setNotes(notes);

      // Test des getters
      assertThat(formule.getPopulaire()).isEqualTo(populaire);
      assertThat(formule.getRecommandee()).isEqualTo(recommandee);
      assertThat(formule.getPeriodeEssaiJours()).isEqualTo(periodeEssaiJours);
      assertThat(formule.getDateDebutValidite()).isEqualTo(dateDebutValidite);
      assertThat(formule.getDateFinValidite()).isEqualTo(dateFinValidite);
      assertThat(formule.getOrdreAffichage()).isEqualTo(ordreAffichage);
      assertThat(formule.getCouleur()).isEqualTo(couleur);
      assertThat(formule.getIcone()).isEqualTo(icone);
      assertThat(formule.getNotes()).isEqualTo(notes);
    }
  }

  @Nested
  @DisplayName("Tests des méthodes métier")
  class MethodesMetierTests {

    @Test
    @DisplayName("Test méthodes de statut")
    void testMethodesStatut() {
      // Test isActive
      formule.setStatut(StatutFormule.ACTIVE);
      assertThat(formule.isActive()).isTrue();

      formule.setStatut(StatutFormule.INACTIVE);
      assertThat(formule.isActive()).isFalse();

      // Test isInactive
      formule.setStatut(StatutFormule.INACTIVE);
      assertThat(formule.isInactive()).isTrue();

      formule.setStatut(StatutFormule.ACTIVE);
      assertThat(formule.isInactive()).isFalse();

      // Test isArchivee
      formule.setStatut(StatutFormule.ARCHIVEE);
      assertThat(formule.isArchivee()).isTrue();

      formule.setStatut(StatutFormule.ACTIVE);
      assertThat(formule.isArchivee()).isFalse();
    }

    @Test
    @DisplayName("Test méthode isValide")
    void testIsValide() {
      // Formule active sans dates de validité
      formule.setStatut(StatutFormule.ACTIVE);
      assertThat(formule.isValide()).isTrue();

      // Formule inactive
      formule.setStatut(StatutFormule.INACTIVE);
      assertThat(formule.isValide()).isFalse();

      // Formule active avec date de début future
      formule.setStatut(StatutFormule.ACTIVE);
      formule.setDateDebutValidite(LocalDate.now().plusDays(1));
      assertThat(formule.isValide()).isFalse();

      // Formule active avec date de fin passée
      formule.setDateDebutValidite(null);
      formule.setDateFinValidite(LocalDate.now().minusDays(1));
      assertThat(formule.isValide()).isFalse();

      // Formule active dans la période de validité
      formule.setDateDebutValidite(LocalDate.now().minusDays(1));
      formule.setDateFinValidite(LocalDate.now().plusDays(1));
      assertThat(formule.isValide()).isTrue();
    }

    @Test
    @DisplayName("Test calculs économie annuelle")
    void testCalculsEconomieAnnuelle() {
      // Cas avec prix null
      formule.setPrixMensuel(null);
      formule.setPrixAnnuel(null);
      assertThat(formule.getEconomieAnnuelle()).isEqualTo(BigDecimal.ZERO);
      assertThat(formule.getPourcentageEconomieAnnuelle()).isEqualTo(0);

      // Cas avec seulement prix mensuel null
      formule.setPrixMensuel(null);
      formule.setPrixAnnuel(new BigDecimal("100000.00"));
      assertThat(formule.getEconomieAnnuelle()).isEqualTo(BigDecimal.ZERO);
      assertThat(formule.getPourcentageEconomieAnnuelle()).isEqualTo(0);

      // Cas avec seulement prix annuel null
      formule.setPrixMensuel(new BigDecimal("10000.00"));
      formule.setPrixAnnuel(null);
      assertThat(formule.getEconomieAnnuelle()).isEqualTo(BigDecimal.ZERO);
      assertThat(formule.getPourcentageEconomieAnnuelle()).isEqualTo(0);

      // Cas avec économie
      formule.setPrixMensuel(new BigDecimal("10000.00"));
      formule.setPrixAnnuel(new BigDecimal("100000.00"));
      BigDecimal economieAttendue = new BigDecimal("20000.00"); // 12*10000 - 100000
      assertThat(formule.getEconomieAnnuelle()).isEqualTo(economieAttendue);
      assertThat(formule.getPourcentageEconomieAnnuelle()).isEqualTo(17); // 20000/120000 * 100 = 16.67 arrondi à 17

      // Cas sans économie
      formule.setPrixMensuel(new BigDecimal("10000.00"));
      formule.setPrixAnnuel(new BigDecimal("120000.00"));
      assertThat(formule.getEconomieAnnuelle()).isEqualByComparingTo(BigDecimal.ZERO);
      assertThat(formule.getPourcentageEconomieAnnuelle()).isEqualTo(0);
    }

    @Test
    @DisplayName("Test méthodes de vérification")
    void testMethodesVerification() {
      // Test hasPeriodeEssai
      formule.setPeriodeEssaiJours(null);
      assertThat(formule.hasPeriodeEssai()).isFalse();

      formule.setPeriodeEssaiJours(0);
      assertThat(formule.hasPeriodeEssai()).isFalse();

      formule.setPeriodeEssaiJours(30);
      assertThat(formule.hasPeriodeEssai()).isTrue();

      // Test hasFormation
      formule.setFormationIncluse(null);
      formule.setHeuresFormation(null);
      assertThat(formule.hasFormation()).isFalse();

      formule.setFormationIncluse(true);
      formule.setHeuresFormation(0);
      assertThat(formule.hasFormation()).isFalse();

      formule.setFormationIncluse(true);
      formule.setHeuresFormation(10);
      assertThat(formule.hasFormation()).isTrue();

      formule.setFormationIncluse(false);
      formule.setHeuresFormation(10);
      assertThat(formule.hasFormation()).isFalse();

      // Test cas spécifique : formationIncluse=true mais heuresFormation=null
      formule.setFormationIncluse(true);
      formule.setHeuresFormation(null);
      assertThat(formule.hasFormation()).isFalse();

      // Test isMiseEnAvant
      formule.setPopulaire(null);
      formule.setRecommandee(null);
      assertThat(formule.isMiseEnAvant()).isFalse();

      formule.setPopulaire(true);
      formule.setRecommandee(false);
      assertThat(formule.isMiseEnAvant()).isTrue();

      formule.setPopulaire(false);
      formule.setRecommandee(true);
      assertThat(formule.isMiseEnAvant()).isTrue();
    }

    @Test
    @DisplayName("Test getBadge")
    void testGetBadge() {
      // Cas populaire
      formule.setPopulaire(true);
      formule.setRecommandee(false);
      formule.setPeriodeEssaiJours(0);
      assertThat(formule.getBadge()).isEqualTo("POPULAIRE");

      // Cas recommandée
      formule.setPopulaire(false);
      formule.setRecommandee(true);
      assertThat(formule.getBadge()).isEqualTo("RECOMMANDÉE");

      // Cas essai gratuit
      formule.setPopulaire(false);
      formule.setRecommandee(false);
      formule.setPeriodeEssaiJours(30);
      assertThat(formule.getBadge()).isEqualTo("ESSAI GRATUIT");

      // Cas aucun badge
      formule.setPopulaire(false);
      formule.setRecommandee(false);
      formule.setPeriodeEssaiJours(0);
      assertThat(formule.getBadge()).isNull();
    }

    @Test
    @DisplayName("Test getScoreFonctionnalites")
    void testGetScoreFonctionnalites() {
      // Toutes les fonctionnalités null (cas total == 0)
      formule.setSupportTechnique(null);
      formule.setSauvegardeAutomatique(null);
      formule.setFonctionnalitesAvancees(null);
      formule.setApiAccess(null);
      formule.setRapportsPersonnalises(null);
      formule.setIntegrationsTierces(null);
      formule.setMultiLangues(null);
      formule.setPersonnalisationInterface(null);
      assertThat(formule.getScoreFonctionnalites()).isEqualTo(0);

      // Toutes les fonctionnalités désactivées
      formule.setSupportTechnique(false);
      formule.setSauvegardeAutomatique(false);
      formule.setFonctionnalitesAvancees(false);
      formule.setApiAccess(false);
      formule.setRapportsPersonnalises(false);
      formule.setIntegrationsTierces(false);
      formule.setMultiLangues(false);
      formule.setPersonnalisationInterface(false);
      assertThat(formule.getScoreFonctionnalites()).isEqualTo(0);

      // Toutes les fonctionnalités activées
      formule.setSupportTechnique(true);
      formule.setSauvegardeAutomatique(true);
      formule.setFonctionnalitesAvancees(true);
      formule.setApiAccess(true);
      formule.setRapportsPersonnalises(true);
      formule.setIntegrationsTierces(true);
      formule.setMultiLangues(true);
      formule.setPersonnalisationInterface(true);
      assertThat(formule.getScoreFonctionnalites()).isEqualTo(100);

      // Test cas intermédiaire : seulement quelques fonctionnalités
      formule.setSupportTechnique(true);  // +10
      formule.setSauvegardeAutomatique(false);
      formule.setFonctionnalitesAvancees(true);  // +15
      formule.setApiAccess(false);
      formule.setRapportsPersonnalises(false);
      formule.setIntegrationsTierces(false);
      formule.setMultiLangues(false);
      formule.setPersonnalisationInterface(false);
      // Score = (10 + 15) * 100 / 100 = 25
      assertThat(formule.getScoreFonctionnalites()).isEqualTo(25);

      // Test spécifique pour couvrir toutes les branches de l'expression ternaire
      // Cas où score = 0 mais total > 0 (toutes fonctionnalités false)
      formule.setSupportTechnique(false);
      formule.setSauvegardeAutomatique(false);
      formule.setFonctionnalitesAvancees(false);
      formule.setApiAccess(false);
      formule.setRapportsPersonnalises(false);
      formule.setIntegrationsTierces(false);
      formule.setMultiLangues(false);
      formule.setPersonnalisationInterface(false);
      // total = 100, score = 0, donc (0 * 100) / 100 = 0
      assertThat(formule.getScoreFonctionnalites()).isEqualTo(0);

      // Test avec un seul élément activé pour vérifier la division
      formule.setSupportTechnique(true);  // score = 10, total = 100
      formule.setSauvegardeAutomatique(false);
      formule.setFonctionnalitesAvancees(false);
      formule.setApiAccess(false);
      formule.setRapportsPersonnalises(false);
      formule.setIntegrationsTierces(false);
      formule.setMultiLangues(false);
      formule.setPersonnalisationInterface(false);
      // Score = (10 * 100) / 100 = 10
      assertThat(formule.getScoreFonctionnalites()).isEqualTo(10);
    }

    @Test
    @DisplayName("Test getCssClass")
    void testGetCssClass() {
      // Type null
      formule.setType(null);
      assertThat(formule.getCssClass()).isEqualTo("formule-default");

      // Types spécifiques
      formule.setType(TypeFormule.BASIC);
      assertThat(formule.getCssClass()).isEqualTo("formule-basic");

      formule.setType(TypeFormule.STANDARD);
      assertThat(formule.getCssClass()).isEqualTo("formule-standard");

      formule.setType(TypeFormule.PREMIUM);
      assertThat(formule.getCssClass()).isEqualTo("formule-premium");

      formule.setType(TypeFormule.ENTERPRISE);
      assertThat(formule.getCssClass()).isEqualTo("formule-enterprise");
    }

    @Test
    @DisplayName("Test méthodes d'action")
    void testMethodesAction() {
      // Test activer
      formule.setStatut(StatutFormule.INACTIVE);
      formule.activer();
      assertThat(formule.getStatut()).isEqualTo(StatutFormule.ACTIVE);

      // Test désactiver
      formule.setStatut(StatutFormule.ACTIVE);
      formule.desactiver();
      assertThat(formule.getStatut()).isEqualTo(StatutFormule.INACTIVE);

      // Test archiver
      formule.setStatut(StatutFormule.ACTIVE);
      formule.archiver();
      assertThat(formule.getStatut()).isEqualTo(StatutFormule.ARCHIVEE);
    }

    @Test
    @DisplayName("Test enums")
    void testEnums() {
      // Test TypeFormule
      assertThat(TypeFormule.BASIC.getLibelle()).isEqualTo("Formule Basique");
      assertThat(TypeFormule.STANDARD.getLibelle()).isEqualTo("Formule Standard");
      assertThat(TypeFormule.PREMIUM.getLibelle()).isEqualTo("Formule Premium");
      assertThat(TypeFormule.ENTERPRISE.getLibelle()).isEqualTo("Formule Entreprise");

      // Test StatutFormule
      assertThat(StatutFormule.ACTIVE.getLibelle()).isEqualTo("Active");
      assertThat(StatutFormule.INACTIVE.getLibelle()).isEqualTo("Inactive");
      assertThat(StatutFormule.ARCHIVEE.getLibelle()).isEqualTo("Archivée");
      assertThat(StatutFormule.BIENTOT_DISPONIBLE.getLibelle()).isEqualTo("Bientôt Disponible");
    }

    @Test
    @DisplayName("Test toString")
    void testToString() {
      formule.setNom("Test Formule");
      formule.setCode("TEST");
      formule.setType(TypeFormule.PREMIUM);
      formule.setPrixMensuel(new BigDecimal("25000.00"));
      formule.setPrixAnnuel(new BigDecimal("250000.00"));
      formule.setDevise("XOF");
      formule.setStatut(StatutFormule.ACTIVE);
      formule.setPopulaire(true);
      formule.setRecommandee(false);

      String result = formule.toString();
      assertThat(result).isNotNull();
      assertThat(result).contains("FormuleAbonnementDTO");
      assertThat(result).contains("nom='Test Formule'");
      assertThat(result).contains("code='TEST'");
      assertThat(result).contains("type=PREMIUM");
      assertThat(result).contains("prixMensuel=25000.00");
      assertThat(result).contains("prixAnnuel=250000.00");
      assertThat(result).contains("devise='XOF'");
      assertThat(result).contains("statut=ACTIVE");
      assertThat(result).contains("populaire=true");
      assertThat(result).contains("recommandee=false");
    }

    @Test
    @DisplayName("Test branches supplémentaires isValide")
    void testBranchesSupplementairesIsValide() {
      // Test avec dateDebutValidite dans le futur
      formule.setStatut(StatutFormule.ACTIVE);
      formule.setDateDebutValidite(LocalDate.now().plusDays(1));
      formule.setDateFinValidite(null);
      assertThat(formule.isValide()).isFalse();

      // Test avec dateFinValidite dans le passé
      formule.setStatut(StatutFormule.ACTIVE);
      formule.setDateDebutValidite(null);
      formule.setDateFinValidite(LocalDate.now().minusDays(1));
      assertThat(formule.isValide()).isFalse();

      // Test avec les deux dates null et statut actif
      formule.setStatut(StatutFormule.ACTIVE);
      formule.setDateDebutValidite(null);
      formule.setDateFinValidite(null);
      assertThat(formule.isValide()).isTrue();

      // Test avec statut inactif
      formule.setStatut(StatutFormule.INACTIVE);
      assertThat(formule.isValide()).isFalse();
    }

    @Test
    @DisplayName("Test branches supplémentaires getEconomieAnnuelle")
    void testBranchesSupplementairesGetEconomieAnnuelle() {
      // Test avec prixMensuel null
      formule.setPrixMensuel(null);
      formule.setPrixAnnuel(BigDecimal.valueOf(1000));
      assertThat(formule.getEconomieAnnuelle()).isEqualByComparingTo(BigDecimal.ZERO);

      // Test avec prixAnnuel null
      formule.setPrixMensuel(BigDecimal.valueOf(100));
      formule.setPrixAnnuel(null);
      assertThat(formule.getEconomieAnnuelle()).isEqualByComparingTo(BigDecimal.ZERO);

      // Test avec les deux null
      formule.setPrixMensuel(null);
      formule.setPrixAnnuel(null);
      assertThat(formule.getEconomieAnnuelle()).isEqualByComparingTo(BigDecimal.ZERO);
    }

    @Test
    @DisplayName("Test branches supplémentaires getPourcentageEconomieAnnuelle")
    void testBranchesSupplementairesPourcentageEconomie() {
      // Test avec prixMensuel zéro
      formule.setPrixMensuel(BigDecimal.ZERO);
      formule.setPrixAnnuel(BigDecimal.valueOf(1000));
      assertThat(formule.getPourcentageEconomieAnnuelle()).isEqualTo(0);

      // Test avec calcul normal
      formule.setPrixMensuel(BigDecimal.valueOf(100));
      formule.setPrixAnnuel(BigDecimal.valueOf(1000));
      // 100*12 = 1200, économie = 1200-1000 = 200, pourcentage = 200*100/1200 = 16.67 arrondi à 17
      assertThat(formule.getPourcentageEconomieAnnuelle()).isEqualTo(17);
    }
  }
}
