/// Normalise et interprète les données reçues depuis une notification push. /// /// Le parseur convertit les payloads FCM en une action unique utilisée /// par [NotificationService] pour effectuer la bonne navigation. class NotificationPayloadParser { /// Construit une action de navigation à partir d'un payload FCM. /// /// [data] peut contenir des valeurs hétérogènes; elles sont converties en /// `String` de manière défensive. Si `type` est absent, des règles de /// fallback basées sur les clés présentes (`invitationId`, `groupId`, `tripId`) /// sont appliquées. static NotificationAction parse(Map data) { final normalized = data.map( (key, value) => MapEntry(key, value?.toString()), ); final explicitType = normalized['type']; final inferredType = _inferType(normalized); final type = explicitType ?? inferredType; return NotificationAction( type: type, tripId: normalized['tripId'], groupId: normalized['groupId'], activityId: normalized['activityId'], invitationId: normalized['invitationId'], inviterName: normalized['inviterName'], tripTitle: normalized['tripTitle'], ); } /// Déduit un type de notification quand `type` est absent du payload. /// /// Priorité: invitation > message > voyage. static String _inferType(Map data) { if (data['invitationId'] != null) { return 'trip_invitation'; } if (data['groupId'] != null) { return 'message'; } if (data['tripId'] != null) { return 'trip'; } return 'unknown'; } } /// Représente une action de navigation dérivée d'une notification. class NotificationAction { /// Type normalisé de la notification (message, expense, activity, etc.). final String type; /// Identifiant de voyage éventuellement présent dans le payload. final String? tripId; /// Identifiant de groupe éventuellement présent dans le payload. final String? groupId; /// Identifiant d'activité éventuellement présent dans le payload. final String? activityId; /// Identifiant d'invitation de voyage éventuellement présent. final String? invitationId; /// Nom de l'invitant, utilisé pour le texte du popup d'invitation. final String? inviterName; /// Titre du voyage, utilisé pour enrichir le popup d'invitation. final String? tripTitle; /// Crée une action de notification. const NotificationAction({ required this.type, this.tripId, this.groupId, this.activityId, this.invitationId, this.inviterName, this.tripTitle, }); }