import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; import 'notification.dart'; part 'preferences_notification.g.dart'; /// Énumération des canaux de notification enum CanalNotification { @JsonValue('URGENT_CHANNEL') urgent('urgent', 'Notifications urgentes', 5, true, true, '#F44336'), @JsonValue('ERROR_CHANNEL') error('error', 'Erreurs système', 4, true, true, '#F44336'), @JsonValue('WARNING_CHANNEL') warning('warning', 'Avertissements', 4, true, true, '#FF9800'), @JsonValue('IMPORTANT_CHANNEL') important('important', 'Notifications importantes', 4, true, true, '#FF5722'), @JsonValue('REMINDER_CHANNEL') reminder('reminder', 'Rappels', 3, true, true, '#2196F3'), @JsonValue('SUCCESS_CHANNEL') success('success', 'Confirmations', 2, false, false, '#4CAF50'), @JsonValue('DEFAULT_CHANNEL') defaultChannel('default', 'Notifications générales', 2, false, false, '#2196F3'), @JsonValue('EVENTS_CHANNEL') events('events', 'Événements', 3, true, false, '#2196F3'), @JsonValue('PAYMENTS_CHANNEL') payments('payments', 'Paiements', 4, true, true, '#4CAF50'), @JsonValue('SOLIDARITY_CHANNEL') solidarity('solidarity', 'Solidarité', 3, true, false, '#E91E63'), @JsonValue('MEMBERS_CHANNEL') members('members', 'Membres', 2, false, false, '#2196F3'), @JsonValue('ORGANIZATION_CHANNEL') organization('organization', 'Organisation', 3, true, false, '#2196F3'), @JsonValue('SYSTEM_CHANNEL') system('system', 'Système', 2, false, false, '#607D8B'), @JsonValue('MESSAGES_CHANNEL') messages('messages', 'Messages', 3, true, false, '#2196F3'); const CanalNotification(this.id, this.nom, this.importance, this.sonActive, this.vibrationActive, this.couleur); final String id; final String nom; final int importance; final bool sonActive; final bool vibrationActive; final String couleur; bool get isCritique => importance >= 4; bool get isSilencieux => !sonActive && !vibrationActive; } /// Préférences spécifiques à un type de notification @JsonSerializable() class PreferenceTypeNotification extends Equatable { const PreferenceTypeNotification({ this.active = true, this.priorite, this.sonPersonnalise, this.patternVibration, this.couleurLED, this.dureeAffichageSecondes, this.doitVibrer, this.doitEmettreSon, this.doitAllumerLED, this.ignoreModesilencieux = false, }); final bool active; final int? priorite; final String? sonPersonnalise; final List? patternVibration; final String? couleurLED; final int? dureeAffichageSecondes; final bool? doitVibrer; final bool? doitEmettreSon; final bool? doitAllumerLED; final bool ignoreModesilencieux; factory PreferenceTypeNotification.fromJson(Map json) => _$PreferenceTypeNotificationFromJson(json); Map toJson() => _$PreferenceTypeNotificationToJson(this); @override List get props => [ active, priorite, sonPersonnalise, patternVibration, couleurLED, dureeAffichageSecondes, doitVibrer, doitEmettreSon, doitAllumerLED, ignoreModesilencieux, ]; PreferenceTypeNotification copyWith({ bool? active, int? priorite, String? sonPersonnalise, List? patternVibration, String? couleurLED, int? dureeAffichageSecondes, bool? doitVibrer, bool? doitEmettreSon, bool? doitAllumerLED, bool? ignoreModesilencieux, }) { return PreferenceTypeNotification( active: active ?? this.active, priorite: priorite ?? this.priorite, sonPersonnalise: sonPersonnalise ?? this.sonPersonnalise, patternVibration: patternVibration ?? this.patternVibration, couleurLED: couleurLED ?? this.couleurLED, dureeAffichageSecondes: dureeAffichageSecondes ?? this.dureeAffichageSecondes, doitVibrer: doitVibrer ?? this.doitVibrer, doitEmettreSon: doitEmettreSon ?? this.doitEmettreSon, doitAllumerLED: doitAllumerLED ?? this.doitAllumerLED, ignoreModesilencieux: ignoreModesilencieux ?? this.ignoreModesilencieux, ); } } /// Préférences spécifiques à un canal de notification @JsonSerializable() class PreferenceCanalNotification extends Equatable { const PreferenceCanalNotification({ this.active = true, this.importance, this.sonPersonnalise, this.patternVibration, this.couleurLED, this.sonActive, this.vibrationActive, this.ledActive, this.peutEtreDesactive = true, }); final bool active; final int? importance; final String? sonPersonnalise; final List? patternVibration; final String? couleurLED; final bool? sonActive; final bool? vibrationActive; final bool? ledActive; final bool peutEtreDesactive; factory PreferenceCanalNotification.fromJson(Map json) => _$PreferenceCanalNotificationFromJson(json); Map toJson() => _$PreferenceCanalNotificationToJson(this); @override List get props => [ active, importance, sonPersonnalise, patternVibration, couleurLED, sonActive, vibrationActive, ledActive, peutEtreDesactive, ]; PreferenceCanalNotification copyWith({ bool? active, int? importance, String? sonPersonnalise, List? patternVibration, String? couleurLED, bool? sonActive, bool? vibrationActive, bool? ledActive, bool? peutEtreDesactive, }) { return PreferenceCanalNotification( active: active ?? this.active, importance: importance ?? this.importance, sonPersonnalise: sonPersonnalise ?? this.sonPersonnalise, patternVibration: patternVibration ?? this.patternVibration, couleurLED: couleurLED ?? this.couleurLED, sonActive: sonActive ?? this.sonActive, vibrationActive: vibrationActive ?? this.vibrationActive, ledActive: ledActive ?? this.ledActive, peutEtreDesactive: peutEtreDesactive ?? this.peutEtreDesactive, ); } } /// Entité principale des préférences de notification @JsonSerializable() class PreferencesNotificationEntity extends Equatable { const PreferencesNotificationEntity({ required this.id, required this.utilisateurId, this.organisationId, this.notificationsActivees = true, this.pushActivees = true, this.emailActivees = true, this.smsActivees = false, this.inAppActivees = true, this.typesActives, this.typesDesactivees, this.canauxActifs, this.canauxDesactives, this.modeSilencieux = false, this.heureDebutSilencieux, this.heureFinSilencieux, this.joursSilencieux, this.urgentesIgnorentSilencieux = true, this.frequenceRegroupementMinutes = 5, this.maxNotificationsSimultanees = 10, this.dureeAffichageSecondes = 10, this.vibrationActivee = true, this.sonActive = true, this.ledActivee = true, this.sonPersonnalise, this.patternVibrationPersonnalise, this.couleurLEDPersonnalisee, this.apercuEcranVerrouillage = true, this.affichageHistorique = true, this.dureeConservationJours = 30, this.marquageLectureAutomatique = false, this.delaiMarquageLectureSecondes, this.archivageAutomatique = true, this.delaiArchivageHeures = 168, this.preferencesParType, this.preferencesParCanal, this.motsClesFiltre, this.expediteursBloques, this.expediteursPrioritaires, this.notificationsTestActivees = false, this.niveauLog = 'INFO', this.tokenFCM, this.plateforme, this.versionApp, this.langue = 'fr', this.fuseauHoraire, this.metadonnees, }); final String id; final String utilisateurId; final String? organisationId; final bool notificationsActivees; final bool pushActivees; final bool emailActivees; final bool smsActivees; final bool inAppActivees; final Set? typesActives; final Set? typesDesactivees; final Set? canauxActifs; final Set? canauxDesactives; final bool modeSilencieux; final String? heureDebutSilencieux; // Format HH:mm final String? heureFinSilencieux; // Format HH:mm final Set? joursSilencieux; // 1=Lundi, 7=Dimanche final bool urgentesIgnorentSilencieux; final int frequenceRegroupementMinutes; final int maxNotificationsSimultanees; final int dureeAffichageSecondes; final bool vibrationActivee; final bool sonActive; final bool ledActivee; final String? sonPersonnalise; final List? patternVibrationPersonnalise; final String? couleurLEDPersonnalisee; final bool apercuEcranVerrouillage; final bool affichageHistorique; final int dureeConservationJours; final bool marquageLectureAutomatique; final int? delaiMarquageLectureSecondes; final bool archivageAutomatique; final int delaiArchivageHeures; final Map? preferencesParType; final Map? preferencesParCanal; final Set? motsClesFiltre; final Set? expediteursBloques; final Set? expediteursPrioritaires; final bool notificationsTestActivees; final String niveauLog; final String? tokenFCM; final String? plateforme; final String? versionApp; final String langue; final String? fuseauHoraire; final Map? metadonnees; factory PreferencesNotificationEntity.fromJson(Map json) => _$PreferencesNotificationEntityFromJson(json); Map toJson() => _$PreferencesNotificationEntityToJson(this); @override List get props => [ id, utilisateurId, organisationId, notificationsActivees, pushActivees, emailActivees, smsActivees, inAppActivees, typesActives, typesDesactivees, canauxActifs, canauxDesactives, modeSilencieux, heureDebutSilencieux, heureFinSilencieux, joursSilencieux, urgentesIgnorentSilencieux, frequenceRegroupementMinutes, maxNotificationsSimultanees, dureeAffichageSecondes, vibrationActivee, sonActive, ledActivee, sonPersonnalise, patternVibrationPersonnalise, couleurLEDPersonnalisee, apercuEcranVerrouillage, affichageHistorique, dureeConservationJours, marquageLectureAutomatique, delaiMarquageLectureSecondes, archivageAutomatique, delaiArchivageHeures, preferencesParType, preferencesParCanal, motsClesFiltre, expediteursBloques, expediteursPrioritaires, notificationsTestActivees, niveauLog, tokenFCM, plateforme, versionApp, langue, fuseauHoraire, metadonnees, ]; PreferencesNotificationEntity copyWith({ String? id, String? utilisateurId, String? organisationId, bool? notificationsActivees, bool? pushActivees, bool? emailActivees, bool? smsActivees, bool? inAppActivees, Set? typesActives, Set? typesDesactivees, Set? canauxActifs, Set? canauxDesactives, bool? modeSilencieux, String? heureDebutSilencieux, String? heureFinSilencieux, Set? joursSilencieux, bool? urgentesIgnorentSilencieux, int? frequenceRegroupementMinutes, int? maxNotificationsSimultanees, int? dureeAffichageSecondes, bool? vibrationActivee, bool? sonActive, bool? ledActivee, String? sonPersonnalise, List? patternVibrationPersonnalise, String? couleurLEDPersonnalisee, bool? apercuEcranVerrouillage, bool? affichageHistorique, int? dureeConservationJours, bool? marquageLectureAutomatique, int? delaiMarquageLectureSecondes, bool? archivageAutomatique, int? delaiArchivageHeures, Map? preferencesParType, Map? preferencesParCanal, Set? motsClesFiltre, Set? expediteursBloques, Set? expediteursPrioritaires, bool? notificationsTestActivees, String? niveauLog, String? tokenFCM, String? plateforme, String? versionApp, String? langue, String? fuseauHoraire, Map? metadonnees, }) { return PreferencesNotificationEntity( id: id ?? this.id, utilisateurId: utilisateurId ?? this.utilisateurId, organisationId: organisationId ?? this.organisationId, notificationsActivees: notificationsActivees ?? this.notificationsActivees, pushActivees: pushActivees ?? this.pushActivees, emailActivees: emailActivees ?? this.emailActivees, smsActivees: smsActivees ?? this.smsActivees, inAppActivees: inAppActivees ?? this.inAppActivees, typesActives: typesActives ?? this.typesActives, typesDesactivees: typesDesactivees ?? this.typesDesactivees, canauxActifs: canauxActifs ?? this.canauxActifs, canauxDesactives: canauxDesactives ?? this.canauxDesactives, modeSilencieux: modeSilencieux ?? this.modeSilencieux, heureDebutSilencieux: heureDebutSilencieux ?? this.heureDebutSilencieux, heureFinSilencieux: heureFinSilencieux ?? this.heureFinSilencieux, joursSilencieux: joursSilencieux ?? this.joursSilencieux, urgentesIgnorentSilencieux: urgentesIgnorentSilencieux ?? this.urgentesIgnorentSilencieux, frequenceRegroupementMinutes: frequenceRegroupementMinutes ?? this.frequenceRegroupementMinutes, maxNotificationsSimultanees: maxNotificationsSimultanees ?? this.maxNotificationsSimultanees, dureeAffichageSecondes: dureeAffichageSecondes ?? this.dureeAffichageSecondes, vibrationActivee: vibrationActivee ?? this.vibrationActivee, sonActive: sonActive ?? this.sonActive, ledActivee: ledActivee ?? this.ledActivee, sonPersonnalise: sonPersonnalise ?? this.sonPersonnalise, patternVibrationPersonnalise: patternVibrationPersonnalise ?? this.patternVibrationPersonnalise, couleurLEDPersonnalisee: couleurLEDPersonnalisee ?? this.couleurLEDPersonnalisee, apercuEcranVerrouillage: apercuEcranVerrouillage ?? this.apercuEcranVerrouillage, affichageHistorique: affichageHistorique ?? this.affichageHistorique, dureeConservationJours: dureeConservationJours ?? this.dureeConservationJours, marquageLectureAutomatique: marquageLectureAutomatique ?? this.marquageLectureAutomatique, delaiMarquageLectureSecondes: delaiMarquageLectureSecondes ?? this.delaiMarquageLectureSecondes, archivageAutomatique: archivageAutomatique ?? this.archivageAutomatique, delaiArchivageHeures: delaiArchivageHeures ?? this.delaiArchivageHeures, preferencesParType: preferencesParType ?? this.preferencesParType, preferencesParCanal: preferencesParCanal ?? this.preferencesParCanal, motsClesFiltre: motsClesFiltre ?? this.motsClesFiltre, expediteursBloques: expediteursBloques ?? this.expediteursBloques, expediteursPrioritaires: expediteursPrioritaires ?? this.expediteursPrioritaires, notificationsTestActivees: notificationsTestActivees ?? this.notificationsTestActivees, niveauLog: niveauLog ?? this.niveauLog, tokenFCM: tokenFCM ?? this.tokenFCM, plateforme: plateforme ?? this.plateforme, versionApp: versionApp ?? this.versionApp, langue: langue ?? this.langue, fuseauHoraire: fuseauHoraire ?? this.fuseauHoraire, metadonnees: metadonnees ?? this.metadonnees, ); } /// Vérifie si un type de notification est activé bool isTypeActive(TypeNotification type) { if (!notificationsActivees) return false; if (typesDesactivees?.contains(type) == true) return false; if (typesActives != null) return typesActives!.contains(type); return true; // Activé par défaut } /// Vérifie si un canal de notification est activé bool isCanalActif(CanalNotification canal) { if (!notificationsActivees) return false; if (canauxDesactives?.contains(canal) == true) return false; if (canauxActifs != null) return canauxActifs!.contains(canal); return true; // Activé par défaut } /// Vérifie si on est en mode silencieux actuellement bool get isEnModeSilencieux { if (!modeSilencieux) return false; if (heureDebutSilencieux == null || heureFinSilencieux == null) return false; final maintenant = DateTime.now(); final heureActuelle = '${maintenant.hour.toString().padLeft(2, '0')}:${maintenant.minute.toString().padLeft(2, '0')}'; // Gestion du cas où la période traverse minuit if (heureDebutSilencieux!.compareTo(heureFinSilencieux!) > 0) { return heureActuelle.compareTo(heureDebutSilencieux!) >= 0 || heureActuelle.compareTo(heureFinSilencieux!) <= 0; } else { return heureActuelle.compareTo(heureDebutSilencieux!) >= 0 && heureActuelle.compareTo(heureFinSilencieux!) <= 0; } } /// Vérifie si un expéditeur est bloqué bool isExpediteurBloque(String? expediteurId) { if (expediteurId == null) return false; return expediteursBloques?.contains(expediteurId) == true; } /// Vérifie si un expéditeur est prioritaire bool isExpediteurPrioritaire(String? expediteurId) { if (expediteurId == null) return false; return expediteursPrioritaires?.contains(expediteurId) == true; } /// Crée des préférences par défaut pour un utilisateur static PreferencesNotificationEntity creerDefaut(String utilisateurId) { return PreferencesNotificationEntity( id: 'pref_$utilisateurId', utilisateurId: utilisateurId, ); } }