import 'package:json_annotation/json_annotation.dart'; import '../../domain/entities/notification.dart'; part 'notification_model.g.dart'; /// Modèle de données pour les actions de notification @JsonSerializable() class ActionNotificationModel extends ActionNotification { const ActionNotificationModel({ required super.id, required super.libelle, required super.typeAction, super.description, super.icone, super.couleur, super.url, super.route, super.parametres, super.fermeNotification = true, super.necessiteConfirmation = false, super.estDestructive = false, super.ordre = 0, super.estActivee = true, }); factory ActionNotificationModel.fromJson(Map json) => _$ActionNotificationModelFromJson(json); @override Map toJson() => _$ActionNotificationModelToJson(this); factory ActionNotificationModel.fromEntity(ActionNotification entity) { return ActionNotificationModel( id: entity.id, libelle: entity.libelle, typeAction: entity.typeAction, description: entity.description, icone: entity.icone, couleur: entity.couleur, url: entity.url, route: entity.route, parametres: entity.parametres, fermeNotification: entity.fermeNotification, necessiteConfirmation: entity.necessiteConfirmation, estDestructive: entity.estDestructive, ordre: entity.ordre, estActivee: entity.estActivee, ); } ActionNotification toEntity() { return ActionNotification( id: id, libelle: libelle, typeAction: typeAction, description: description, icone: icone, couleur: couleur, url: url, route: route, parametres: parametres, fermeNotification: fermeNotification, necessiteConfirmation: necessiteConfirmation, estDestructive: estDestructive, ordre: ordre, estActivee: estActivee, ); } } /// Modèle de données pour les notifications @JsonSerializable() class NotificationModel extends NotificationEntity { const NotificationModel({ required super.id, required super.typeNotification, required super.statut, required super.titre, required super.message, super.messageCourt, super.expediteurId, super.expediteurNom, required super.destinatairesIds, super.organisationId, super.donneesPersonnalisees, super.imageUrl, super.iconeUrl, super.actionClic, super.parametresAction, super.actionsRapides, required super.dateCreation, super.dateEnvoiProgramme, super.dateEnvoi, super.dateExpiration, super.dateDerniereLecture, super.priorite = 3, super.estLue = false, super.estImportante = false, super.estArchivee = false, super.nombreAffichages = 0, super.nombreClics = 0, super.tags, super.campagneId, super.plateforme, super.tokenFCM, }); factory NotificationModel.fromJson(Map json) => _$NotificationModelFromJson(json); @override Map toJson() => _$NotificationModelToJson(this); factory NotificationModel.fromEntity(NotificationEntity entity) { return NotificationModel( id: entity.id, typeNotification: entity.typeNotification, statut: entity.statut, titre: entity.titre, message: entity.message, messageCourt: entity.messageCourt, expediteurId: entity.expediteurId, expediteurNom: entity.expediteurNom, destinatairesIds: entity.destinatairesIds, organisationId: entity.organisationId, donneesPersonnalisees: entity.donneesPersonnalisees, imageUrl: entity.imageUrl, iconeUrl: entity.iconeUrl, actionClic: entity.actionClic, parametresAction: entity.parametresAction, actionsRapides: entity.actionsRapides?.map((action) => ActionNotificationModel.fromEntity(action)).toList(), dateCreation: entity.dateCreation, dateEnvoiProgramme: entity.dateEnvoiProgramme, dateEnvoi: entity.dateEnvoi, dateExpiration: entity.dateExpiration, dateDerniereLecture: entity.dateDerniereLecture, priorite: entity.priorite, estLue: entity.estLue, estImportante: entity.estImportante, estArchivee: entity.estArchivee, nombreAffichages: entity.nombreAffichages, nombreClics: entity.nombreClics, tags: entity.tags, campagneId: entity.campagneId, plateforme: entity.plateforme, tokenFCM: entity.tokenFCM, ); } NotificationEntity toEntity() { return NotificationEntity( id: id, typeNotification: typeNotification, statut: statut, titre: titre, message: message, messageCourt: messageCourt, expediteurId: expediteurId, expediteurNom: expediteurNom, destinatairesIds: destinatairesIds, organisationId: organisationId, donneesPersonnalisees: donneesPersonnalisees, imageUrl: imageUrl, iconeUrl: iconeUrl, actionClic: actionClic, parametresAction: parametresAction, actionsRapides: actionsRapides?.map((action) => (action as ActionNotificationModel).toEntity()).toList(), dateCreation: dateCreation, dateEnvoiProgramme: dateEnvoiProgramme, dateEnvoi: dateEnvoi, dateExpiration: dateExpiration, dateDerniereLecture: dateDerniereLecture, priorite: priorite, estLue: estLue, estImportante: estImportante, estArchivee: estArchivee, nombreAffichages: nombreAffichages, nombreClics: nombreClics, tags: tags, campagneId: campagneId, plateforme: plateforme, tokenFCM: tokenFCM, ); } /// Crée un modèle depuis une notification Firebase factory NotificationModel.fromFirebaseMessage(Map data) { // Extraction des données de base final id = data['id'] ?? data['notification_id'] ?? ''; final titre = data['title'] ?? data['titre'] ?? ''; final message = data['body'] ?? data['message'] ?? ''; final messageCourt = data['short_message'] ?? data['message_court']; // Parsing du type de notification TypeNotification typeNotification = TypeNotification.annonceGenerale; if (data['type'] != null) { try { typeNotification = TypeNotification.values.firstWhere( (type) => type.name == data['type'] || type.toString().split('.').last == data['type'], orElse: () => TypeNotification.annonceGenerale, ); } catch (e) { // Utilise le type par défaut en cas d'erreur } } // Parsing du statut StatutNotification statut = StatutNotification.recue; if (data['status'] != null) { try { statut = StatutNotification.values.firstWhere( (s) => s.name == data['status'] || s.toString().split('.').last == data['status'], orElse: () => StatutNotification.recue, ); } catch (e) { // Utilise le statut par défaut } } // Parsing des actions rapides List? actionsRapides; if (data['actions'] != null && data['actions'] is List) { try { actionsRapides = (data['actions'] as List) .map((actionData) => ActionNotificationModel.fromJson( actionData is Map ? actionData : {})) .toList(); } catch (e) { // Ignore les erreurs de parsing des actions } } // Parsing des destinataires List destinatairesIds = []; if (data['recipients'] != null) { if (data['recipients'] is List) { destinatairesIds = List.from(data['recipients']); } else if (data['recipients'] is String) { destinatairesIds = [data['recipients']]; } } // Parsing des tags List? tags; if (data['tags'] != null && data['tags'] is List) { tags = List.from(data['tags']); } // Parsing des dates DateTime dateCreation = DateTime.now(); if (data['created_at'] != null) { try { if (data['created_at'] is int) { dateCreation = DateTime.fromMillisecondsSinceEpoch(data['created_at']); } else if (data['created_at'] is String) { dateCreation = DateTime.parse(data['created_at']); } } catch (e) { // Utilise la date actuelle en cas d'erreur } } DateTime? dateExpiration; if (data['expires_at'] != null) { try { if (data['expires_at'] is int) { dateExpiration = DateTime.fromMillisecondsSinceEpoch(data['expires_at']); } else if (data['expires_at'] is String) { dateExpiration = DateTime.parse(data['expires_at']); } } catch (e) { // Ignore les erreurs de parsing de date } } // Parsing des données personnalisées Map? donneesPersonnalisees; if (data['custom_data'] != null && data['custom_data'] is Map) { donneesPersonnalisees = Map.from(data['custom_data']); } return NotificationModel( id: id, typeNotification: typeNotification, statut: statut, titre: titre, message: message, messageCourt: messageCourt, expediteurId: data['sender_id'], expediteurNom: data['sender_name'], destinatairesIds: destinatairesIds, organisationId: data['organization_id'], donneesPersonnalisees: donneesPersonnalisees, imageUrl: data['image_url'], iconeUrl: data['icon_url'], actionClic: data['click_action'], parametresAction: data['action_params'] != null ? Map.from(data['action_params']) : null, actionsRapides: actionsRapides, dateCreation: dateCreation, dateExpiration: dateExpiration, priorite: data['priority'] ?? 3, tags: tags, campagneId: data['campaign_id'], plateforme: data['platform'], tokenFCM: data['fcm_token'], ); } /// Convertit vers le format Firebase Map toFirebaseData() { final data = { 'id': id, 'type': typeNotification.name, 'status': statut.name, 'title': titre, 'body': message, 'recipients': destinatairesIds, 'created_at': dateCreation.millisecondsSinceEpoch, 'priority': priorite, }; if (messageCourt != null) data['short_message'] = messageCourt; if (expediteurId != null) data['sender_id'] = expediteurId; if (expediteurNom != null) data['sender_name'] = expediteurNom; if (organisationId != null) data['organization_id'] = organisationId; if (donneesPersonnalisees != null) data['custom_data'] = donneesPersonnalisees; if (imageUrl != null) data['image_url'] = imageUrl; if (iconeUrl != null) data['icon_url'] = iconeUrl; if (actionClic != null) data['click_action'] = actionClic; if (parametresAction != null) data['action_params'] = parametresAction; if (dateExpiration != null) data['expires_at'] = dateExpiration!.millisecondsSinceEpoch; if (tags != null) data['tags'] = tags; if (campagneId != null) data['campaign_id'] = campagneId; if (plateforme != null) data['platform'] = plateforme; if (tokenFCM != null) data['fcm_token'] = tokenFCM; if (actionsRapides != null && actionsRapides!.isNotEmpty) { data['actions'] = actionsRapides! .map((action) => (action as ActionNotificationModel).toJson()) .toList(); } return data; } /// Crée une copie avec des modifications NotificationModel copyWithModel({ String? id, TypeNotification? typeNotification, StatutNotification? statut, String? titre, String? message, String? messageCourt, String? expediteurId, String? expediteurNom, List? destinatairesIds, String? organisationId, Map? donneesPersonnalisees, String? imageUrl, String? iconeUrl, String? actionClic, Map? parametresAction, List? actionsRapides, DateTime? dateCreation, DateTime? dateEnvoiProgramme, DateTime? dateEnvoi, DateTime? dateExpiration, DateTime? dateDerniereLecture, int? priorite, bool? estLue, bool? estImportante, bool? estArchivee, int? nombreAffichages, int? nombreClics, List? tags, String? campagneId, String? plateforme, String? tokenFCM, }) { return NotificationModel( id: id ?? this.id, typeNotification: typeNotification ?? this.typeNotification, statut: statut ?? this.statut, titre: titre ?? this.titre, message: message ?? this.message, messageCourt: messageCourt ?? this.messageCourt, expediteurId: expediteurId ?? this.expediteurId, expediteurNom: expediteurNom ?? this.expediteurNom, destinatairesIds: destinatairesIds ?? this.destinatairesIds, organisationId: organisationId ?? this.organisationId, donneesPersonnalisees: donneesPersonnalisees ?? this.donneesPersonnalisees, imageUrl: imageUrl ?? this.imageUrl, iconeUrl: iconeUrl ?? this.iconeUrl, actionClic: actionClic ?? this.actionClic, parametresAction: parametresAction ?? this.parametresAction, actionsRapides: actionsRapides ?? this.actionsRapides, dateCreation: dateCreation ?? this.dateCreation, dateEnvoiProgramme: dateEnvoiProgramme ?? this.dateEnvoiProgramme, dateEnvoi: dateEnvoi ?? this.dateEnvoi, dateExpiration: dateExpiration ?? this.dateExpiration, dateDerniereLecture: dateDerniereLecture ?? this.dateDerniereLecture, priorite: priorite ?? this.priorite, estLue: estLue ?? this.estLue, estImportante: estImportante ?? this.estImportante, estArchivee: estArchivee ?? this.estArchivee, nombreAffichages: nombreAffichages ?? this.nombreAffichages, nombreClics: nombreClics ?? this.nombreClics, tags: tags ?? this.tags, campagneId: campagneId ?? this.campagneId, plateforme: plateforme ?? this.plateforme, tokenFCM: tokenFCM ?? this.tokenFCM, ); } }