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

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * Request To Pay (RTP) — message ISO 20022 {@code pain.013.001} mappé vers la Business API
 * PI-SPI.
 *
 * <p>Permet à une institution (SFD UnionFlow) d'<strong>initier une demande de paiement</strong>
 * vers un membre, plutôt que d'attendre que le membre pousse le paiement. Cas d'usage parfait
 * pour les <strong>appels de cotisation</strong> :
 *
 * <ol>
 *   <li>La SFD émet un RTP avec le montant et l'échéance ;
 *   <li>Le membre reçoit la notification dans son app Mobile Money / banque ;
 *   <li>Il valide ou refuse en un clic ;
 *   <li>Si validé → flux pacs.008 standard, mais initié par le débiteur sans saisie manuelle.
 * </ol>
 *
 * <p>La réponse est un message {@code pain.014.001} indiquant le statut (ACCEPTED / REFUSED /
 * EXPIRED) — modélisé par {@link PispiRtpResponse}.
 *
 * <p>Référence : {@code https://developer.pispi.bceao.int/guides/rtp-overview}.
 *
 * @since 2026-04-25
 */
public record PispiRtpRequest(
    String rtpId,                       // identifiant unique de la demande RTP
    String creditorInstitutionCode,     // SFD UnionFlow (créancier)
    String creditorAccountNumber,
    String creditorName,
    String debtorAlias,                 // tel/email du débiteur (résolu via l'API alias)
    BigDecimal amount,                  // montant FCFA
    String currency,                    // toujours "XOF" en UEMOA
    String purpose,                     // ex: "COTISATION_OCT_2026"
    String description,                 // ex: "Cotisation mensuelle octobre 2026"
    LocalDateTime requestedExecutionDate,
    LocalDateTime expiryDate            // au-delà : RTP expiré, débiteur ne peut plus accepter
) {

  /** Validation minimale avant envoi. */
  public void validate() {
    if (rtpId == null || rtpId.isBlank()) {
      throw new IllegalArgumentException("RTP id manquant");
    }
    if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
      throw new IllegalArgumentException("Montant RTP doit être positif");
    }
    if (debtorAlias == null || debtorAlias.isBlank()) {
      throw new IllegalArgumentException("Alias débiteur manquant");
    }
    if (currency == null || !"XOF".equals(currency)) {
      throw new IllegalArgumentException("Seul XOF est supporté en UEMOA");
    }
    if (expiryDate != null && requestedExecutionDate != null
        && expiryDate.isBefore(requestedExecutionDate)) {
      throw new IllegalArgumentException("Date expiration avant date exécution demandée");
    }
  }
}
