package dev.lions.unionflow.server.entity;

import dev.lions.unionflow.server.api.enums.solidarite.StatutAide;
import dev.lions.unionflow.server.api.enums.solidarite.TypeAide;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

/** Entité représentant une demande d'aide dans le système de solidarité */
@Entity
@Table(name = "demandes_aide")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class DemandeAide extends BaseEntity {

  @Column(name = "titre", nullable = false, length = 200)
  private String titre;

  @Column(name = "description", nullable = false, columnDefinition = "TEXT")
  private String description;

  @Enumerated(EnumType.STRING)
  @Column(name = "type_aide", nullable = false)
  private TypeAide typeAide;

  @Enumerated(EnumType.STRING)
  @Column(name = "statut", nullable = false)
  private StatutAide statut;

  @Column(name = "montant_demande", precision = 10, scale = 2)
  private BigDecimal montantDemande;

  @Column(name = "montant_approuve", precision = 10, scale = 2)
  private BigDecimal montantApprouve;

  @Column(name = "date_demande", nullable = false)
  private LocalDateTime dateDemande;

  @Column(name = "date_evaluation")
  private LocalDateTime dateEvaluation;

  @Column(name = "date_versement")
  private LocalDateTime dateVersement;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "demandeur_id", nullable = false)
  private Membre demandeur;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "evaluateur_id")
  private Membre evaluateur;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "organisation_id", nullable = false)
  private Organisation organisation;

  @Column(name = "justification", columnDefinition = "TEXT")
  private String justification;

  @Column(name = "commentaire_evaluation", columnDefinition = "TEXT")
  private String commentaireEvaluation;

  @Column(name = "urgence", nullable = false)
  @Builder.Default
  private Boolean urgence = false;

  @Column(name = "documents_fournis")
  private String documentsFournis;

  // ========================================================
  // Workflow v2 (P1-NEW-3, 2026-04-25) — DEPOSE → ENQUETE → AVIS_COMITE → DECISION_CA → PAYE → CLOTURE
  // ========================================================

  /** Étape actuelle dans le workflow v2 (DEPOSE par défaut). */
  @Column(name = "etape", length = 30)
  @Builder.Default
  private String etape = "DEPOSE";

  /** Animateur de zone responsable de l'enquête sociale (étape ENQUETE). */
  @Column(name = "animateur_zone_id")
  private java.util.UUID animateurZoneId;

  /** Rapport rédigé par l'animateur après visite (étape ENQUETE). */
  @Column(name = "rapport_enquete_sociale", columnDefinition = "TEXT")
  private String rapportEnqueteSociale;

  @Column(name = "date_enquete")
  private LocalDateTime dateEnquete;

  /** Géolocalisation GPS de l'enquête (preuve de visite terrain). */
  @Column(name = "gps_enquete_lat", precision = 10, scale = 7)
  private java.math.BigDecimal gpsEnqueteLat;

  @Column(name = "gps_enquete_lon", precision = 10, scale = 7)
  private java.math.BigDecimal gpsEnqueteLon;

  /** Avis du comité social ou commission solidarité (étape AVIS_COMITE). */
  @Column(name = "avis_comite_social", columnDefinition = "TEXT")
  private String avisComiteSocial;

  @Column(name = "date_avis_comite")
  private LocalDateTime dateAvisComite;

  /** Lien vers le PV CA dans lequel la décision a été votée (étape DECISION_CA). */
  @Column(name = "decision_ca_id")
  private java.util.UUID decisionCaId;

  @Column(name = "date_decision_ca")
  private LocalDateTime dateDecisionCa;

  @Column(name = "date_paie")
  private LocalDateTime datePaie;

  @Column(name = "reference_paiement", length = 100)
  private String referencePaiement;

  @PrePersist
  protected void onCreate() {
    super.onCreate(); // Appelle le onCreate de BaseEntity
    if (dateDemande == null) {
      dateDemande = LocalDateTime.now();
    }
    if (statut == null) {
      statut = StatutAide.EN_ATTENTE;
    }
    if (urgence == null) {
      urgence = false;
    }
  }

  @PreUpdate
  protected void onUpdate() {
    // Méthode appelée avant mise à jour
  }

  /** Vérifie si la demande est en attente */
  public boolean isEnAttente() {
    return StatutAide.EN_ATTENTE.equals(statut);
  }

  /** Vérifie si la demande est approuvée */
  public boolean isApprouvee() {
    return StatutAide.APPROUVEE.equals(statut);
  }

  /** Vérifie si la demande est rejetée */
  public boolean isRejetee() {
    return StatutAide.REJETEE.equals(statut);
  }

  /** Vérifie si la demande est urgente */
  public boolean isUrgente() {
    return Boolean.TRUE.equals(urgence);
  }

  /** Calcule le pourcentage d'approbation par rapport au montant demandé */
  public BigDecimal getPourcentageApprobation() {
    if (montantDemande == null || montantDemande.compareTo(BigDecimal.ZERO) == 0) {
      return BigDecimal.ZERO;
    }
    if (montantApprouve == null) {
      return BigDecimal.ZERO;
    }
    return montantApprouve
        .divide(montantDemande, 4, RoundingMode.HALF_UP)
        .multiply(BigDecimal.valueOf(100));
  }
}
