package dev.lions.unionflow.server.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.*;

/**
 * Entité FeedbackEvenement représentant l'évaluation d'un membre sur un événement
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-16
 */
@Entity
@Table(
    name = "feedbacks_evenement",
    indexes = {
      @Index(name = "idx_feedback_membre", columnList = "membre_id"),
      @Index(name = "idx_feedback_evenement", columnList = "evenement_id"),
      @Index(name = "idx_feedback_date", columnList = "date_feedback")
    },
    uniqueConstraints = {
      @UniqueConstraint(
          name = "uk_feedback_membre_evenement",
          columnNames = {"membre_id", "evenement_id"})
    })
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class FeedbackEvenement extends BaseEntity {

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

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "evenement_id", nullable = false)
  private Evenement evenement;

  @NotNull
  @Min(1)
  @Max(5)
  @Column(name = "note", nullable = false)
  private Integer note;

  @Column(name = "commentaire", length = 1000)
  private String commentaire;

  @Builder.Default
  @Column(name = "date_feedback", nullable = false)
  private LocalDateTime dateFeedback = LocalDateTime.now();

  @Column(name = "moderation_statut", length = 20)
  @Builder.Default
  private String moderationStatut = ModerationStatut.PUBLIE.name();

  @Column(name = "raison_moderation", length = 500)
  private String raisonModeration;

  /** Énumération des statuts de modération */
  public enum ModerationStatut {
    PUBLIE, // Visible publiquement
    EN_ATTENTE, // En attente de modération
    REJETE // Rejeté par modération
  }

  // Méthodes utilitaires

  /** Vérifie si le feedback est publié */
  public boolean isPublie() {
    return ModerationStatut.PUBLIE.name().equals(this.moderationStatut);
  }

  /** Marque le feedback comme en attente de modération */
  public void mettreEnAttente(String raison) {
    this.moderationStatut = ModerationStatut.EN_ATTENTE.name();
    this.raisonModeration = raison;
    setDateModification(LocalDateTime.now());
  }

  /** Publie le feedback */
  public void publier() {
    this.moderationStatut = ModerationStatut.PUBLIE.name();
    this.raisonModeration = null;
    setDateModification(LocalDateTime.now());
  }

  /** Rejette le feedback */
  public void rejeter(String raison) {
    this.moderationStatut = ModerationStatut.REJETE.name();
    this.raisonModeration = raison;
    setDateModification(LocalDateTime.now());
  }

  @PreUpdate
  public void preUpdate() {
    super.onUpdate();
  }

  @Override
  public String toString() {
    return String.format(
        "FeedbackEvenement{id=%s, membre=%s, evenement=%s, note=%d, dateFeedback=%s}",
        getId(),
        membre != null ? membre.getEmail() : "null",
        evenement != null ? evenement.getTitre() : "null",
        note,
        dateFeedback);
  }
}
