package dev.lions.unionflow.server.payment.pispi.dto;

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

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

class PispiRtpRequestTest {

  private PispiRtpRequest validRequest() {
    return new PispiRtpRequest(
        "RTP-001",
        "SFD-CIV-001",
        "ACC-1234",
        "Mutuelle X",
        "+22507123456@unionflow",
        new BigDecimal("5000"),
        "XOF",
        "COTISATION",
        "Cotisation oct 2026",
        LocalDateTime.now().plusDays(1),
        LocalDateTime.now().plusDays(7));
  }

  @Test
  @DisplayName("Request valide → validate() ne throw pas")
  void validRequestPasses() {
    validRequest().validate();
  }

  @Test
  @DisplayName("RTP id manquant → IllegalArgumentException")
  void rtpIdMissing() {
    PispiRtpRequest r = new PispiRtpRequest(
        "", "SFD", "ACC", "Mutuelle", "+225@unionflow",
        new BigDecimal("5000"), "XOF", "P", "D", null, null);
    assertThatThrownBy(r::validate)
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessageContaining("RTP id");
  }

  @Test
  @DisplayName("Montant <= 0 → IllegalArgumentException")
  void montantNonPositif() {
    PispiRtpRequest r = new PispiRtpRequest(
        "RTP-1", "SFD", "ACC", "Mutuelle", "+225@unionflow",
        BigDecimal.ZERO, "XOF", "P", "D", null, null);
    assertThatThrownBy(r::validate)
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessageContaining("positif");

    PispiRtpRequest neg = new PispiRtpRequest(
        "RTP-1", "SFD", "ACC", "Mutuelle", "+225@unionflow",
        new BigDecimal("-100"), "XOF", "P", "D", null, null);
    assertThatThrownBy(neg::validate).isInstanceOf(IllegalArgumentException.class);
  }

  @Test
  @DisplayName("Alias débiteur manquant → IllegalArgumentException")
  void aliasDebiteurMissing() {
    PispiRtpRequest r = new PispiRtpRequest(
        "RTP-1", "SFD", "ACC", "Mutuelle", "",
        new BigDecimal("5000"), "XOF", "P", "D", null, null);
    assertThatThrownBy(r::validate).hasMessageContaining("Alias débiteur");
  }

  @Test
  @DisplayName("Devise non-XOF → IllegalArgumentException")
  void deviseNonXof() {
    PispiRtpRequest r = new PispiRtpRequest(
        "RTP-1", "SFD", "ACC", "Mutuelle", "+225@unionflow",
        new BigDecimal("5000"), "EUR", "P", "D", null, null);
    assertThatThrownBy(r::validate).hasMessageContaining("XOF");
  }

  @Test
  @DisplayName("Date expiration avant date exécution → IllegalArgumentException")
  void expiryAvantExecution() {
    LocalDateTime exec = LocalDateTime.now().plusDays(7);
    LocalDateTime expiry = LocalDateTime.now().plusDays(2);
    PispiRtpRequest r = new PispiRtpRequest(
        "RTP-1", "SFD", "ACC", "Mutuelle", "+225@unionflow",
        new BigDecimal("5000"), "XOF", "P", "D", exec, expiry);
    assertThatThrownBy(r::validate).hasMessageContaining("expiration");
  }
}

