package dev.lions.unionflow.server.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

/**
 * Table de liaison entre Membre et Role
 * Permet à un membre d'avoir plusieurs rôles avec dates de début/fin
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@Entity
@Table(
    name = "membres_roles",
    indexes = {
      @Index(name = "idx_mr_membre_org",   columnList = "membre_organisation_id"),
      @Index(name = "idx_mr_organisation", columnList = "organisation_id"),
      @Index(name = "idx_mr_role",         columnList = "role_id"),
      @Index(name = "idx_mr_actif",        columnList = "actif")
    },
    uniqueConstraints = {
      @UniqueConstraint(
          name = "uk_mr_membre_org_role",
          columnNames = {"membre_organisation_id", "role_id"})
    })
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class MembreRole extends BaseEntity {

  /** Lien membership (utilisateur dans le contexte de son organisation) */
  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "membre_organisation_id", nullable = false)
  private MembreOrganisation membreOrganisation;

  /** Organisation dans laquelle ce rôle est actif (dénormalisé pour les requêtes) */
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "organisation_id")
  private Organisation organisation;

  /** Rôle */
  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "role_id", nullable = false)
  private Role role;

  /** Date de début d'attribution */
  @Column(name = "date_debut")
  private LocalDate dateDebut;

  /** Date de fin d'attribution (null = permanent) */
  @Column(name = "date_fin")
  private LocalDate dateFin;

  /** Commentaire sur l'attribution */
  @Column(name = "commentaire", length = 500)
  private String commentaire;

  /** Méthode métier pour vérifier si l'attribution est active */
  public boolean isActif() {
    if (!Boolean.TRUE.equals(getActif())) {
      return false;
    }
    LocalDate aujourdhui = LocalDate.now();
    if (dateDebut != null && aujourdhui.isBefore(dateDebut)) {
      return false;
    }
    if (dateFin != null && aujourdhui.isAfter(dateFin)) {
      return false;
    }
    return true;
  }

  /** Callback JPA avant la persistance */
  @PrePersist
  protected void onCreate() {
    super.onCreate();
    if (dateDebut == null) {
      dateDebut = LocalDate.now();
    }
  }
}

