package dev.lions.unionflow.server.entity;

import dev.lions.unionflow.server.api.enums.wave.StatutCompteWave;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

/**
 * Entité CompteWave pour la gestion des comptes Wave Mobile Money
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@Entity
@Table(name = "comptes_wave", indexes = {
    @Index(name = "idx_compte_wave_telephone", columnList = "numero_telephone", unique = true),
    @Index(name = "idx_compte_wave_statut", columnList = "statut_compte"),
    @Index(name = "idx_compte_wave_organisation", columnList = "organisation_id"),
    @Index(name = "idx_compte_wave_membre", columnList = "membre_id")
})
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class CompteWave extends BaseEntity {

  /** Numéro de téléphone Wave (format +225XXXXXXXX) */
  @NotBlank
  @Pattern(regexp = "^\\+225[0-9]{8}$", message = "Le numéro de téléphone Wave doit être au format +225XXXXXXXX")
  @Column(name = "numero_telephone", unique = true, nullable = false, length = 13)
  private String numeroTelephone;

  /** Statut du compte */
  @Enumerated(EnumType.STRING)
  @Builder.Default
  @Column(name = "statut_compte", nullable = false, length = 30)
  private StatutCompteWave statutCompte = StatutCompteWave.NON_VERIFIE;

  /** Identifiant Wave API (encrypté) */
  @Column(name = "wave_account_id", length = 255)
  private String waveAccountId;

  /** Clé API Wave (encryptée) */
  @Column(name = "wave_api_key", length = 500)
  private String waveApiKey;

  /** Environnement (SANDBOX ou PRODUCTION) */
  @Column(name = "environnement", length = 20)
  private String environnement;

  /** Date de dernière vérification */
  @Column(name = "date_derniere_verification")
  private java.time.LocalDateTime dateDerniereVerification;

  /** Commentaires */
  @Column(name = "commentaire", length = 500)
  private String commentaire;

  // Relations
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "organisation_id")
  private Organisation organisation;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "membre_id")
  private Membre membre;

  @JsonIgnore

  @OneToMany(mappedBy = "compteWave", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  @Builder.Default
  private List<TransactionWave> transactions = new ArrayList<>();

  /** Méthode métier pour vérifier si le compte est vérifié */
  public boolean isVerifie() {
    return StatutCompteWave.VERIFIE.equals(statutCompte);
  }

  /** Méthode métier pour vérifier si le compte peut être utilisé */
  public boolean peutEtreUtilise() {
    return StatutCompteWave.VERIFIE.equals(statutCompte);
  }

  /** Callback JPA avant la persistance */
  @PrePersist
  protected void onCreate() {
    super.onCreate();
    if (statutCompte == null) {
      statutCompte = StatutCompteWave.NON_VERIFIE;
    }
    if (environnement == null || environnement.isEmpty()) {
      environnement = "SANDBOX";
    }
  }
}
