import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:equatable/equatable.dart'; import 'user_balance.dart'; import 'settlement.dart'; class GroupBalance extends Equatable { final String groupId; final List userBalances; final List settlements; final double totalExpenses; final DateTime calculatedAt; const GroupBalance({ required this.groupId, required this.userBalances, required this.settlements, required this.totalExpenses, required this.calculatedAt, }); // Constructeur factory pour créer depuis une Map factory GroupBalance.fromMap(Map map) { return GroupBalance( groupId: map['groupId'] ?? '', userBalances: (map['userBalances'] as List?) ?.map((userBalance) => UserBalance.fromMap(userBalance as Map)) .toList() ?? [], settlements: (map['settlements'] as List?) ?.map((settlement) => Settlement.fromMap(settlement as Map)) .toList() ?? [], totalExpenses: (map['totalExpenses'] as num?)?.toDouble() ?? 0.0, calculatedAt: _parseDateTime(map['calculatedAt']), ); } // Convertir en Map pour Firestore Map toMap() { return { 'groupId': groupId, 'userBalances': userBalances.map((userBalance) => userBalance.toMap()).toList(), 'settlements': settlements.map((settlement) => settlement.toMap()).toList(), 'totalExpenses': totalExpenses, 'calculatedAt': Timestamp.fromDate(calculatedAt), }; } // Méthode copyWith pour créer une copie modifiée GroupBalance copyWith({ String? groupId, List? userBalances, List? settlements, double? totalExpenses, DateTime? calculatedAt, }) { return GroupBalance( groupId: groupId ?? this.groupId, userBalances: userBalances ?? this.userBalances, settlements: settlements ?? this.settlements, totalExpenses: totalExpenses ?? this.totalExpenses, calculatedAt: calculatedAt ?? this.calculatedAt, ); } // Helper pour parser les dates de différents formats static DateTime _parseDateTime(dynamic value) { if (value is Timestamp) return value.toDate(); if (value is String) return DateTime.parse(value); if (value is DateTime) return value; if (value is int) return DateTime.fromMillisecondsSinceEpoch(value); return DateTime.now(); } // Méthodes utilitaires pour la logique métier bool get hasUnbalancedUsers => userBalances.any((balance) => !balance.isBalanced); bool get hasSettlements => settlements.isNotEmpty; double get totalSettlementAmount => settlements.fold(0.0, (sum, settlement) => sum + settlement.amount); List get creditors => userBalances.where((b) => b.shouldReceive).toList(); List get debtors => userBalances.where((b) => b.shouldPay).toList(); int get participantCount => userBalances.length; @override List get props => [groupId, calculatedAt]; @override String toString() { return 'GroupBalance(groupId: $groupId, totalExpenses: $totalExpenses, participantCount: $participantCount, calculatedAt: $calculatedAt)'; } }