package dev.lions.unionflow.server.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

/**
 * Entrée d'audit trail enrichi (SYSCOHADA + AUDSCGIE OHADA).
 *
 * <p>Trace les opérations financières, le lifecycle membres, les changements de configuration,
 * avec le contexte multi-org (rôle actif + organisation active) + vérifications de séparation des
 * pouvoirs (SoD).
 *
 * <p>Cette entité ne dérive PAS de {@link BaseEntity} car elle représente un enregistrement
 * immuable d'historique : ses propres champs d'audit ({@code operationAt}, {@code userId}) sont
 * la donnée à tracer.
 *
 * @since 2026-04-25 — exigences SYSCOHADA + Instruction BCEAO 003-03-2025 (audit KYC)
 */
@Entity
@Table(name = "audit_trail_operations")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AuditTrailOperation {

  @Id
  @GeneratedValue(strategy = GenerationType.UUID)
  @Column(name = "id", updatable = false, nullable = false)
  private UUID id;

  // Acteur
  @NotNull
  @Column(name = "user_id", nullable = false)
  private UUID userId;

  @Column(name = "user_email", length = 255)
  private String userEmail;

  @Column(name = "role_actif", length = 50)
  private String roleActif;

  @Column(name = "organisation_active_id")
  private UUID organisationActiveId;

  // Action
  @NotBlank
  @Column(name = "action_type", nullable = false, length = 50)
  private String actionType;

  @NotBlank
  @Column(name = "entity_type", nullable = false, length = 100)
  private String entityType;

  @Column(name = "entity_id")
  private UUID entityId;

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

  // Contexte
  @Column(name = "ip_address", length = 45)
  private String ipAddress;

  @Column(name = "user_agent", length = 500)
  private String userAgent;

  @Column(name = "request_id")
  private UUID requestId;

  // Données (JSONB)
  @JdbcTypeCode(SqlTypes.JSON)
  @Column(name = "payload_avant", columnDefinition = "jsonb")
  private String payloadAvant;

  @JdbcTypeCode(SqlTypes.JSON)
  @Column(name = "payload_apres", columnDefinition = "jsonb")
  private String payloadApres;

  @JdbcTypeCode(SqlTypes.JSON)
  @Column(name = "metadata", columnDefinition = "jsonb")
  private String metadata;

  // SoD
  @Column(name = "sod_check_passed")
  private Boolean sodCheckPassed;

  @Column(name = "sod_violations", length = 500)
  private String sodViolations;

  @NotNull
  @Column(name = "operation_at", nullable = false)
  @Builder.Default
  private LocalDateTime operationAt = LocalDateTime.now();
}
