package dev.lions.unionflow.server.entity;

import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

/**
 * Rapport trimestriel agrégé généré par/pour le Contrôleur Interne d'une organisation.
 *
 * <p>Source documentaire pour :
 * <ul>
 *   <li>Présentation lors des AG (rapport moral / financier / technique)</li>
 *   <li>Inspections BCEAO Instruction 001-03-2025 (LBC/FT)</li>
 *   <li>Audits ARTCI Décision 2025-1312 (DPO / sécurité données)</li>
 * </ul>
 *
 * <p>Cycle de vie : {@code DRAFT} → {@code SIGNE} (hash SHA-256 calculé) → {@code ARCHIVE}.
 *
 * @since 2026-04-25 (P2-NEW-3)
 */
@Entity
@Table(name = "rapports_trimestriels_controleur_interne",
    uniqueConstraints = @UniqueConstraint(
        name = "uq_rapport_trim_org_annee_trim",
        columnNames = {"organisation_id", "annee", "trimestre"}),
    indexes = {
        @Index(name = "idx_rapport_trim_org", columnList = "organisation_id"),
        @Index(name = "idx_rapport_trim_annee_trim", columnList = "annee,trimestre"),
        @Index(name = "idx_rapport_trim_statut", columnList = "statut")
    })
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class RapportTrimestrielControleurInterne extends BaseEntity {

  @Column(name = "organisation_id", nullable = false)
  private UUID organisationId;

  @Min(2024)
  @Max(2099)
  @Column(name = "annee", nullable = false)
  private Integer annee;

  @Min(1)
  @Max(4)
  @Column(name = "trimestre", nullable = false)
  private Integer trimestre;

  @Column(name = "date_generation", nullable = false)
  private LocalDateTime dateGeneration;

  @Builder.Default
  @Column(name = "statut", nullable = false, length = 20)
  private String statut = "DRAFT";

  @Builder.Default
  @Min(0)
  @Max(100)
  @Column(name = "score_conformite", nullable = false)
  private Integer scoreConformite = 0;

  /** Snapshot agrégé en JSON (compliance score, DOS count, KYC %, etc.). */
  @JdbcTypeCode(SqlTypes.JSON)
  @Column(name = "contenu_jsonb", columnDefinition = "jsonb")
  private JsonNode contenuJsonb;

  /** PDF généré par OpenPDF. Null avant génération. */
  @Column(name = "pdf_bytes")
  private byte[] pdfBytes;

  /** UUID du membre Contrôleur Interne signataire. */
  @Column(name = "signataire_id")
  private UUID signataireId;

  @Column(name = "date_signature")
  private LocalDateTime dateSignature;

  /** Hash SHA-256 du contenu_jsonb calculé à la signature — immuable ensuite. */
  @Column(name = "hash_sha256", length = 64)
  private String hashSha256;
}
