package dev.lions.unionflow.server.service;

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

import java.math.BigDecimal;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class AmlSeuilsTest {

  @Test
  @DisplayName("Seuils alignés Instruction BCEAO 002-03-2025")
  void seuilsConformesInstructionBceao() {
    assertThat(AmlSeuils.SEUIL_INTRA_UEMOA_FCFA).isEqualByComparingTo(new BigDecimal("10000000"));
    assertThat(AmlSeuils.SEUIL_ENTREE_SORTIE_UEMOA_FCFA).isEqualByComparingTo(new BigDecimal("5000000"));
    assertThat(AmlSeuils.SEUIL_OPERATION_ESPECE_FCFA).isEqualByComparingTo(new BigDecimal("1000000"));
  }

  @Test
  @DisplayName("Pays UEMOA = 8 États ISO 3166-1 alpha-3")
  void paysUemoaContientLes8Etats() {
    assertThat(AmlSeuils.PAYS_UEMOA)
        .containsExactlyInAnyOrder("BEN", "BFA", "CIV", "GNB", "MLI", "NER", "SEN", "TGO");
  }

  @Test
  @DisplayName("Transaction CIV → SEN (intra-UEMOA) → seuil 10M")
  void transactionIntraUemoaSeuil10M() {
    assertThat(AmlSeuils.seuilApplicable("CIV", "SEN"))
        .isEqualByComparingTo(AmlSeuils.SEUIL_INTRA_UEMOA_FCFA);
  }

  @Test
  @DisplayName("Transaction CIV → FRA (sortie UEMOA) → seuil 5M")
  void transactionSortieUemoaSeuil5M() {
    assertThat(AmlSeuils.seuilApplicable("CIV", "FRA"))
        .isEqualByComparingTo(AmlSeuils.SEUIL_ENTREE_SORTIE_UEMOA_FCFA);
  }

  @Test
  @DisplayName("Transaction USA → CIV (entrée UEMOA) → seuil 5M")
  void transactionEntreeUemoaSeuil5M() {
    assertThat(AmlSeuils.seuilApplicable("USA", "CIV"))
        .isEqualByComparingTo(AmlSeuils.SEUIL_ENTREE_SORTIE_UEMOA_FCFA);
  }

  @Test
  @DisplayName("Pays null → seuil le plus restrictif (5M)")
  void paysNullRetourneSeuilRestrictif() {
    assertThat(AmlSeuils.seuilApplicable(null, "CIV"))
        .isEqualByComparingTo(AmlSeuils.SEUIL_ENTREE_SORTIE_UEMOA_FCFA);
    assertThat(AmlSeuils.seuilApplicable("CIV", null))
        .isEqualByComparingTo(AmlSeuils.SEUIL_ENTREE_SORTIE_UEMOA_FCFA);
  }

  @Test
  @DisplayName("depasseSeuil intra-UEMOA : 9M sous seuil, 11M au-dessus")
  void depasseSeuilIntraUemoa() {
    assertThat(AmlSeuils.depasseSeuil(new BigDecimal("9000000"), "CIV", "SEN")).isFalse();
    assertThat(AmlSeuils.depasseSeuil(new BigDecimal("10000000"), "CIV", "SEN")).isFalse(); // seuil exact = pas dépassé (>)
    assertThat(AmlSeuils.depasseSeuil(new BigDecimal("11000000"), "CIV", "SEN")).isTrue();
  }

  @Test
  @DisplayName("depasseSeuil sortie UEMOA : 4M sous seuil, 6M au-dessus")
  void depasseSeuilSortieUemoa() {
    assertThat(AmlSeuils.depasseSeuil(new BigDecimal("4000000"), "CIV", "FRA")).isFalse();
    assertThat(AmlSeuils.depasseSeuil(new BigDecimal("6000000"), "CIV", "FRA")).isTrue();
  }

  @Test
  @DisplayName("depasseSeuilEspece : 999K sous seuil, 1M001 au-dessus")
  void depasseSeuilEspece() {
    assertThat(AmlSeuils.depasseSeuilEspece(new BigDecimal("999999"))).isFalse();
    assertThat(AmlSeuils.depasseSeuilEspece(new BigDecimal("1000001"))).isTrue();
  }

  @Test
  @DisplayName("Montant null jamais dépasse")
  void montantNullJamaisDepasse() {
    assertThat(AmlSeuils.depasseSeuil(null, "CIV", "SEN")).isFalse();
    assertThat(AmlSeuils.depasseSeuilEspece(null)).isFalse();
  }
}
