import 'package:cloud_firestore/cloud_firestore.dart'; /// Représente une invitation d'un utilisateur à rejoindre un voyage. /// /// Une invitation passe par les statuts `pending`, `accepted` ou `rejected`. /// Elle contient le contexte minimum nécessaire pour envoyer les notifications /// et appliquer la réponse (trip, expéditeur, destinataire). class TripInvitation { /// Identifiant Firestore de l'invitation. final String id; /// Identifiant du voyage concerné. final String tripId; /// Titre du voyage au moment de l'invitation. final String tripTitle; /// Identifiant de l'utilisateur qui invite. final String inviterId; /// Nom affiché de l'utilisateur qui invite. final String inviterName; /// Identifiant de l'utilisateur invité. final String inviteeId; /// Email de l'utilisateur invité (utile pour affichage et debug). final String inviteeEmail; /// Statut courant de l'invitation: `pending`, `accepted`, `rejected`. final String status; /// Date de création de l'invitation. final DateTime createdAt; /// Date de réponse (acceptation/refus), null si encore en attente. final DateTime? respondedAt; /// Crée une instance de [TripInvitation]. /// /// [status] vaut `pending` par défaut pour une nouvelle invitation. TripInvitation({ required this.id, required this.tripId, required this.tripTitle, required this.inviterId, required this.inviterName, required this.inviteeId, required this.inviteeEmail, this.status = 'pending', required this.createdAt, this.respondedAt, }); /// Crée une invitation à partir d'un document Firestore. /// /// Gère les formats `Timestamp`, `int` et `DateTime` pour les dates. factory TripInvitation.fromFirestore( DocumentSnapshot> doc, ) { final data = doc.data() ?? {}; return TripInvitation( id: doc.id, tripId: data['tripId'] as String? ?? '', tripTitle: data['tripTitle'] as String? ?? '', inviterId: data['inviterId'] as String? ?? '', inviterName: data['inviterName'] as String? ?? 'Quelqu\'un', inviteeId: data['inviteeId'] as String? ?? '', inviteeEmail: data['inviteeEmail'] as String? ?? '', status: data['status'] as String? ?? 'pending', createdAt: _parseDate(data['createdAt']) ?? DateTime.now(), respondedAt: _parseDate(data['respondedAt']), ); } /// Convertit l'invitation en map Firestore. /// /// [respondedAt] est omis si null pour éviter d'écraser inutilement la donnée. Map toMap() { final map = { 'tripId': tripId, 'tripTitle': tripTitle, 'inviterId': inviterId, 'inviterName': inviterName, 'inviteeId': inviteeId, 'inviteeEmail': inviteeEmail, 'status': status, 'createdAt': Timestamp.fromDate(createdAt), }; if (respondedAt != null) { map['respondedAt'] = Timestamp.fromDate(respondedAt!); } return map; } /// Retourne une copie avec les champs fournis. /// /// Utile pour mettre à jour un statut localement sans muter l'instance initiale. TripInvitation copyWith({ String? id, String? tripId, String? tripTitle, String? inviterId, String? inviterName, String? inviteeId, String? inviteeEmail, String? status, DateTime? createdAt, DateTime? respondedAt, }) { return TripInvitation( id: id ?? this.id, tripId: tripId ?? this.tripId, tripTitle: tripTitle ?? this.tripTitle, inviterId: inviterId ?? this.inviterId, inviterName: inviterName ?? this.inviterName, inviteeId: inviteeId ?? this.inviteeId, inviteeEmail: inviteeEmail ?? this.inviteeEmail, status: status ?? this.status, createdAt: createdAt ?? this.createdAt, respondedAt: respondedAt ?? this.respondedAt, ); } /// Convertit une valeur de date Firestore vers [DateTime]. /// /// Retourne `null` si la valeur est absente ou non reconnue. static DateTime? _parseDate(dynamic value) { if (value == null) { return null; } if (value is Timestamp) { return value.toDate(); } if (value is int) { return DateTime.fromMillisecondsSinceEpoch(value); } if (value is DateTime) { return value; } return null; } }