/// Modèle de données pour les adhésions (demandes d'adhésion à une organisation)
/// Correspond à l'API AdhesionResource / AdhesionDTO
library adhesion_model;

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

part 'adhesion_model.g.dart';

/// Statut d'une demande d'adhésion
enum StatutAdhesion {
  @JsonValue('EN_ATTENTE')
  enAttente,
  @JsonValue('APPROUVEE')
  approuvee,
  @JsonValue('REJETEE')
  rejetee,
  @JsonValue('ANNULEE')
  annulee,
  @JsonValue('EN_PAIEMENT')
  enPaiement,
  @JsonValue('PAYEE')
  payee,
}

/// Modèle d'une adhésion
@JsonSerializable(explicitToJson: true)
class AdhesionModel extends Equatable {
  final String? id;
  final String? numeroReference;
  final String? membreId;
  final String? numeroMembre;
  final String? nomMembre;
  final String? emailMembre;
  final String? organisationId;
  final String? nomOrganisation;
  final DateTime? dateDemande;
  final double? fraisAdhesion;
  final double? montantPaye;
  final String? codeDevise;
  final String? statut;
  final DateTime? dateApprobation;
  final DateTime? datePaiement;
  final String? methodePaiement;
  final String? referencePaiement;
  final String? motifRejet;
  final String? observations;
  final String? approuvePar;
  final DateTime? dateCreation;
  final DateTime? dateModification;

  const AdhesionModel({
    this.id,
    this.numeroReference,
    this.membreId,
    this.numeroMembre,
    this.nomMembre,
    this.emailMembre,
    this.organisationId,
    this.nomOrganisation,
    this.dateDemande,
    this.fraisAdhesion,
    this.montantPaye,
    this.codeDevise,
    this.statut,
    this.dateApprobation,
    this.datePaiement,
    this.methodePaiement,
    this.referencePaiement,
    this.motifRejet,
    this.observations,
    this.approuvePar,
    this.dateCreation,
    this.dateModification,
  });

  factory AdhesionModel.fromJson(Map<String, dynamic> json) =>
      _$AdhesionModelFromJson(json);
  Map<String, dynamic> toJson() => _$AdhesionModelToJson(this);

  /// Montant restant à payer
  double get montantRestant {
    if (fraisAdhesion == null) return 0;
    final paye = montantPaye ?? 0;
    final restant = fraisAdhesion! - paye;
    return restant > 0 ? restant : 0;
  }

  /// Pourcentage payé
  int get pourcentagePaiement {
    if (fraisAdhesion == null || fraisAdhesion! == 0) return 0;
    if (montantPaye == null) return 0;
    return ((montantPaye! / fraisAdhesion!) * 100).round();
  }

  bool get estPayeeIntegralement =>
      fraisAdhesion != null &&
      montantPaye != null &&
      montantPaye! >= fraisAdhesion!;

  bool get estEnAttentePaiement =>
      statut == 'APPROUVEE' && !estPayeeIntegralement;

  String get statutLibelle {
    switch (statut) {
      case 'EN_ATTENTE':
        return 'En attente';
      case 'APPROUVEE':
        return 'Approuvée';
      case 'REJETEE':
        return 'Rejetée';
      case 'ANNULEE':
        return 'Annulée';
      case 'EN_PAIEMENT':
        return 'En paiement';
      case 'PAYEE':
        return 'Payée';
      default:
        return statut ?? 'Non défini';
    }
  }

  String get nomMembreComplet =>
      [nomMembre, numeroMembre].where((e) => e != null && e.isNotEmpty).join(' ').trim().isEmpty
          ? (emailMembre ?? 'Membre')
          : [nomMembre, numeroMembre].where((e) => e != null && e.isNotEmpty).join(' ').trim();

  @override
  List<Object?> get props => [
        id,
        numeroReference,
        membreId,
        organisationId,
        statut,
        dateDemande,
        fraisAdhesion,
        montantPaye,
      ];
}
