package dev.lions.unionflow.server.entity;

import dev.lions.unionflow.server.api.enums.membre.NiveauRisqueKyc;
import dev.lions.unionflow.server.api.enums.membre.StatutKyc;
import dev.lions.unionflow.server.api.enums.membre.TypePieceIdentite;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * Dossier KYC/AML d'un membre — conformité GIABA/BCEAO LCB-FT.
 *
 * <p>Rétention 10 ans requise par le GIABA. La colonne {@code anneeReference}
 * sert à l'archivage logique par année (partitionnement futur PostgreSQL).
 *
 * <p>Un seul dossier actif ({@code actif=true}) par membre à la fois.
 * Les dossiers expirés ou archivés ont {@code actif=false}.
 */
@Entity
@Table(
    name = "kyc_dossier",
    indexes = {
        @Index(name = "idx_kyc_membre_id",     columnList = "membre_id"),
        @Index(name = "idx_kyc_statut",        columnList = "statut"),
        @Index(name = "idx_kyc_niveau_risque", columnList = "niveau_risque"),
        @Index(name = "idx_kyc_annee",         columnList = "annee_reference")
    }
)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class KycDossier extends BaseEntity {

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

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(name = "type_piece", nullable = false, length = 30)
    private TypePieceIdentite typePiece;

    @NotBlank
    @Size(max = 50)
    @Column(name = "numero_piece", nullable = false, length = 50)
    private String numeroPiece;

    @Column(name = "date_expiration_piece")
    private LocalDate dateExpirationPiece;

    @Size(max = 500)
    @Column(name = "piece_identite_recto_file_id", length = 500)
    private String pieceIdentiteRectoFileId;

    @Size(max = 500)
    @Column(name = "piece_identite_verso_file_id", length = 500)
    private String pieceIdentiteVersoFileId;

    @Size(max = 500)
    @Column(name = "justif_domicile_file_id", length = 500)
    private String justifDomicileFileId;

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(name = "statut", nullable = false, length = 20)
    @Builder.Default
    private StatutKyc statut = StatutKyc.NON_VERIFIE;

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(name = "niveau_risque", nullable = false, length = 20)
    @Builder.Default
    private NiveauRisqueKyc niveauRisque = NiveauRisqueKyc.FAIBLE;

    @Min(0) @Max(100)
    @Column(name = "score_risque", nullable = false)
    @Builder.Default
    private int scoreRisque = 0;

    @Builder.Default
    @Column(name = "est_pep", nullable = false)
    private boolean estPep = false;

    @Size(max = 5)
    @Column(name = "nationalite", length = 5)
    private String nationalite;

    @Column(name = "date_verification")
    private LocalDateTime dateVerification;

    @Column(name = "validateur_id")
    private UUID validateurId;

    @Size(max = 1000)
    @Column(name = "notes_validateur", length = 1000)
    private String notesValidateur;

    @Column(name = "annee_reference", nullable = false)
    @Builder.Default
    private int anneeReference = java.time.LocalDate.now().getYear();

    /** Pays d'origine des fonds (ISO-3) — anti-blanchiment transferts internationaux. */
    @Size(max = 3)
    @Column(name = "pays_origine_fonds", length = 3)
    private String paysOrigineFonds;

    /** URL/chemin justificatif domicile étranger (facture EDF/British Gas/etc.) pour non-résidents. */
    @Size(max = 500)
    @Column(name = "justificatif_residence_etrangere", length = 500)
    private String justificatifResidenceEtrangere;

    /**
     * Niveau de due diligence (Instr. BCEAO 001-03-2025) :
     * <ul>
     *   <li>SIMPLIFIE — risque faible, opérations limitées</li>
     *   <li>STANDARD — défaut</li>
     *   <li>RENFORCE — non-résidents, PEP, FATF grey-list</li>
     * </ul>
     */
    @Size(max = 20)
    @Column(name = "niveau_due_diligence", nullable = false, length = 20)
    @Builder.Default
    private String niveauDueDiligence = "STANDARD";

    public boolean isPieceExpiree() {
        return dateExpirationPiece != null && dateExpirationPiece.isBefore(LocalDate.now());
    }
}
