/// Modèle complet de données pour un membre
/// Aligné avec le backend MembreDTO
library membre_complete_model;

import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

part 'membre_complete_model.g.dart';

/// Énumération des genres
enum Genre {
  @JsonValue('HOMME')
  homme,
  @JsonValue('FEMME')
  femme,
  @JsonValue('AUTRE')
  autre,
}

/// Énumération des statuts de membre
enum StatutMembre {
  @JsonValue('ACTIF')
  actif,
  @JsonValue('INACTIF')
  inactif,
  @JsonValue('SUSPENDU')
  suspendu,
  @JsonValue('EN_ATTENTE_VALIDATION')
  enAttente,
}

/// Niveau de vigilance KYC (LCB-FT)
enum NiveauVigilanceKyc {
  @JsonValue('SIMPLIFIE')
  simplifie,
  @JsonValue('RENFORCE')
  renforce,
}

/// Statut KYC (vérification identité)
enum StatutKyc {
  @JsonValue('NON_VERIFIE')
  nonVerifie,
  @JsonValue('EN_COURS')
  enCours,
  @JsonValue('VERIFIE')
  verifie,
  @JsonValue('REFUSE')
  refuse,
}

/// Modèle complet d'un membre
@JsonSerializable()
class MembreCompletModel extends Equatable {
  /// Identifiant unique
  final String? id;

  /// Nom de famille
  final String nom;

  /// Prénom
  final String prenom;

  /// Email (unique)
  final String email;

  /// Téléphone
  final String? telephone;

  /// Téléphone Wave (mobile money)
  @JsonKey(name: 'telephoneWave')
  final String? telephoneWave;

  /// Date de naissance
  @JsonKey(name: 'dateNaissance')
  final DateTime? dateNaissance;

  /// Genre
  final Genre? genre;

  /// Adresse complète
  final String? adresse;

  /// Ville
  final String? ville;

  /// Code postal
  @JsonKey(name: 'codePostal')
  final String? codePostal;

  /// Région
  final String? region;

  /// Pays
  final String? pays;

  /// Profession
  final String? profession;

  /// Nationalité
  final String? nationalite;

  /// URL de la photo
  final String? photo;

  /// Statut du membre
  @JsonKey(name: 'statutCompte')
  final StatutMembre statut;

  /// Rôle dans l'organisation
  final String? role;

  /// ID de l'organisation
  @JsonKey(name: 'organisationId')
  final String? organisationId;

  /// Nom de l'organisation (pour affichage)
  @JsonKey(name: 'organisationNom')
  final String? organisationNom;

  /// Date d'adhésion
  @JsonKey(name: 'dateAdhesion')
  final DateTime? dateAdhesion;

  /// Date de fin d'adhésion
  @JsonKey(name: 'dateFinAdhesion')
  final DateTime? dateFinAdhesion;

  /// Membre du bureau
  @JsonKey(name: 'membreBureau')
  final bool membreBureau;

  /// Est responsable
  final bool responsable;

  /// Fonction au bureau
  @JsonKey(name: 'fonctionBureau')
  final String? fonctionBureau;

  /// Numéro de membre (unique)
  @JsonKey(name: 'numeroMembre')
  final String? numeroMembre;

  /// Cotisation à jour
  @JsonKey(name: 'cotisationAJour')
  final bool cotisationAJour;

  /// Nombre d'événements participés
  @JsonKey(name: 'nombreEvenementsParticipes')
  final int nombreEvenementsParticipes;

  /// Dernière activité
  @JsonKey(name: 'derniereActivite')
  final DateTime? derniereActivite;

  /// Statut matrimonial (CELIBATAIRE, MARIE, DIVORCE, VEUF)
  @JsonKey(name: 'statutMatrimonial')
  final String? statutMatrimonial;

  /// Type de pièce d'identité (CNI, PASSEPORT, PERMIS_CONDUIRE, TITRE_SEJOUR)
  @JsonKey(name: 'typeIdentite')
  final String? typeIdentite;

  /// Numéro de pièce d'identité
  @JsonKey(name: 'numeroIdentite')
  final String? numeroIdentite;

  /// Notes internes
  final String? notes;

  /// Date de création
  @JsonKey(name: 'dateCreation')
  final DateTime? dateCreation;

  /// Date de modification
  @JsonKey(name: 'dateModification')
  final DateTime? dateModification;

  /// Actif
  final bool actif;

  /// Niveau de vigilance KYC (LCB-FT anti-blanchiment)
  @JsonKey(name: 'niveauVigilanceKyc')
  final NiveauVigilanceKyc? niveauVigilanceKyc;

  /// Statut de vérification KYC (Know Your Customer)
  @JsonKey(name: 'statutKyc')
  final StatutKyc? statutKyc;

  /// Date de vérification de l'identité (LCB-FT)
  @JsonKey(name: 'dateVerificationIdentite')
  final DateTime? dateVerificationIdentite;

  /// Mot de passe temporaire (retourné une seule fois à la création, null sinon)
  @JsonKey(name: 'motDePasseTemporaire')
  final String? motDePasseTemporaire;

  const MembreCompletModel({
    this.id,
    required this.nom,
    required this.prenom,
    required this.email,
    this.telephone,
    this.telephoneWave,
    this.dateNaissance,
    this.genre,
    this.adresse,
    this.ville,
    this.codePostal,
    this.region,
    this.pays,
    this.profession,
    this.nationalite,
    this.photo,
    this.statut = StatutMembre.actif,
    this.role,
    this.organisationId,
    this.organisationNom,
    this.dateAdhesion,
    this.dateFinAdhesion,
    this.membreBureau = false,
    this.responsable = false,
    this.fonctionBureau,
    this.numeroMembre,
    this.cotisationAJour = false,
    this.nombreEvenementsParticipes = 0,
    this.derniereActivite,
    this.statutMatrimonial,
    this.typeIdentite,
    this.numeroIdentite,
    this.notes,
    this.dateCreation,
    this.dateModification,
    this.actif = true,
    this.niveauVigilanceKyc,
    this.statutKyc,
    this.dateVerificationIdentite,
    this.motDePasseTemporaire,
  });

  /// Création depuis JSON
  factory MembreCompletModel.fromJson(Map<String, dynamic> json) =>
      _$MembreCompletModelFromJson(json);

  /// Conversion vers JSON
  Map<String, dynamic> toJson() => _$MembreCompletModelToJson(this);

  /// Copie avec modifications
  MembreCompletModel copyWith({
    String? id,
    String? nom,
    String? prenom,
    String? email,
    String? telephone,
    String? telephoneWave,
    DateTime? dateNaissance,
    Genre? genre,
    String? adresse,
    String? ville,
    String? codePostal,
    String? region,
    String? pays,
    String? profession,
    String? nationalite,
    String? photo,
    StatutMembre? statut,
    String? role,
    String? organisationId,
    String? organisationNom,
    DateTime? dateAdhesion,
    DateTime? dateFinAdhesion,
    bool? membreBureau,
    bool? responsable,
    String? fonctionBureau,
    String? numeroMembre,
    bool? cotisationAJour,
    int? nombreEvenementsParticipes,
    DateTime? derniereActivite,
    String? statutMatrimonial,
    String? typeIdentite,
    String? numeroIdentite,
    String? notes,
    DateTime? dateCreation,
    DateTime? dateModification,
    bool? actif,
    NiveauVigilanceKyc? niveauVigilanceKyc,
    StatutKyc? statutKyc,
    DateTime? dateVerificationIdentite,
    String? motDePasseTemporaire,
  }) {
    return MembreCompletModel(
      id: id ?? this.id,
      nom: nom ?? this.nom,
      prenom: prenom ?? this.prenom,
      email: email ?? this.email,
      telephone: telephone ?? this.telephone,
      telephoneWave: telephoneWave ?? this.telephoneWave,
      dateNaissance: dateNaissance ?? this.dateNaissance,
      genre: genre ?? this.genre,
      adresse: adresse ?? this.adresse,
      ville: ville ?? this.ville,
      codePostal: codePostal ?? this.codePostal,
      region: region ?? this.region,
      pays: pays ?? this.pays,
      profession: profession ?? this.profession,
      nationalite: nationalite ?? this.nationalite,
      photo: photo ?? this.photo,
      statut: statut ?? this.statut,
      role: role ?? this.role,
      organisationId: organisationId ?? this.organisationId,
      organisationNom: organisationNom ?? this.organisationNom,
      dateAdhesion: dateAdhesion ?? this.dateAdhesion,
      dateFinAdhesion: dateFinAdhesion ?? this.dateFinAdhesion,
      membreBureau: membreBureau ?? this.membreBureau,
      responsable: responsable ?? this.responsable,
      fonctionBureau: fonctionBureau ?? this.fonctionBureau,
      numeroMembre: numeroMembre ?? this.numeroMembre,
      cotisationAJour: cotisationAJour ?? this.cotisationAJour,
      nombreEvenementsParticipes: nombreEvenementsParticipes ?? this.nombreEvenementsParticipes,
      derniereActivite: derniereActivite ?? this.derniereActivite,
      statutMatrimonial: statutMatrimonial ?? this.statutMatrimonial,
      typeIdentite: typeIdentite ?? this.typeIdentite,
      numeroIdentite: numeroIdentite ?? this.numeroIdentite,
      notes: notes ?? this.notes,
      dateCreation: dateCreation ?? this.dateCreation,
      dateModification: dateModification ?? this.dateModification,
      actif: actif ?? this.actif,
      niveauVigilanceKyc: niveauVigilanceKyc ?? this.niveauVigilanceKyc,
      statutKyc: statutKyc ?? this.statutKyc,
      dateVerificationIdentite: dateVerificationIdentite ?? this.dateVerificationIdentite,
      motDePasseTemporaire: motDePasseTemporaire ?? this.motDePasseTemporaire,
    );
  }

  /// Nom complet
  String get nomComplet => '$prenom $nom';

  /// Initiales
  String get initiales {
    final p = prenom.isNotEmpty ? prenom[0].toUpperCase() : '';
    final n = nom.isNotEmpty ? nom[0].toUpperCase() : '';
    return '$p$n';
  }

  /// Âge calculé
  int? get age {
    if (dateNaissance == null) return null;
    final now = DateTime.now();
    int age = now.year - dateNaissance!.year;
    if (now.month < dateNaissance!.month ||
        (now.month == dateNaissance!.month && now.day < dateNaissance!.day)) {
      age--;
    }
    return age;
  }

  /// Ancienneté en jours
  int? get ancienneteJours {
    if (dateAdhesion == null) return null;
    return DateTime.now().difference(dateAdhesion!).inDays;
  }

  /// Est actif et cotisation à jour
  bool get estActifEtAJour => actif && statut == StatutMembre.actif && cotisationAJour;

  @override
  List<Object?> get props => [
        id,
        nom,
        prenom,
        email,
        telephone,
        telephoneWave,
        dateNaissance,
        genre,
        adresse,
        ville,
        codePostal,
        region,
        pays,
        profession,
        nationalite,
        photo,
        statut,
        role,
        organisationId,
        organisationNom,
        dateAdhesion,
        dateFinAdhesion,
        membreBureau,
        responsable,
        fonctionBureau,
        numeroMembre,
        cotisationAJour,
        nombreEvenementsParticipes,
        derniereActivite,
        statutMatrimonial,
        typeIdentite,
        numeroIdentite,
        notes,
        dateCreation,
        dateModification,
        actif,
        niveauVigilanceKyc,
        statutKyc,
        dateVerificationIdentite,
      ];

  @override
  String toString() =>
      'MembreCompletModel(id: $id, nom: $nomComplet, email: $email, statut: $statut)';
}

