sealed class BaseNotificationModel { abstract final NotificationType type; abstract final bool isRead; abstract final DateTime createdAt; } class PlanSubscriptionStartedToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; final String chatId; @override final DateTime createdAt; PlanSubscriptionStartedToAuthorNotification({ required this.type, required this.planName, required this.customerName, required this.chatId, required this.isRead, required this.createdAt, }); factory PlanSubscriptionStartedToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PlanSubscriptionStartedToAuthorNotification( type: type, planName: json['plan_name'], customerName: json['user_name'], chatId: json['chat_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PlanSubscriptionCanceledToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; @override final DateTime createdAt; PlanSubscriptionCanceledToAuthorNotification({ required this.type, required this.planName, required this.customerName, required this.isRead, required this.createdAt, }); factory PlanSubscriptionCanceledToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PlanSubscriptionCanceledToAuthorNotification( type: type, planName: json['plan_name'], customerName: json['user_name'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanStartedToClientNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; @override final DateTime createdAt; ChosenPlanStartedToClientNotification({required this.type, required this.planName, required this.planId, required this.isRead, required this.createdAt}); factory ChosenPlanStartedToClientNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanStartedToClientNotification( type: type, planName: json['plan_name'], planId: json['plan_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanTomorrowReminderToClientNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; @override final DateTime createdAt; ChosenPlanTomorrowReminderToClientNotification({required this.type, required this.planName, required this.isRead, required this.createdAt}); factory ChosenPlanTomorrowReminderToClientNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanTomorrowReminderToClientNotification( type: type, planName: json['plan_name'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class DiaryReminderNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; DiaryReminderNotification({required this.type, required this.isRead, required this.createdAt}); factory DiaryReminderNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return DiaryReminderNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantLeftCommentNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final DateTime date; @override final DateTime createdAt; ConsultantLeftCommentNotification({required this.type, required this.date, required this.isRead, required this.createdAt}); factory ConsultantLeftCommentNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantLeftCommentNotification( type: type, date: parseDate(json['diary_date'] ?? DateTime.now().toIso8601String()), isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PersonalizedDietIsDefinedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; PersonalizedDietIsDefinedNotification({required this.type, required this.isRead, required this.createdAt}); factory PersonalizedDietIsDefinedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PersonalizedDietIsDefinedNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanFinishedToClientNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; @override final DateTime createdAt; ChosenPlanFinishedToClientNotification({required this.type, required this.planName, required this.isRead, required this.createdAt}); factory ChosenPlanFinishedToClientNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanFinishedToClientNotification( type: type, planName: json['plan_name'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PlanSubscriptionCanceledToCustomerNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; @override final DateTime createdAt; PlanSubscriptionCanceledToCustomerNotification({required this.type, required this.planName, required this.isRead, required this.createdAt}); factory PlanSubscriptionCanceledToCustomerNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PlanSubscriptionCanceledToCustomerNotification( type: type, planName: json['plan_name'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanStartedToConsultantNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; @override final DateTime createdAt; ChosenPlanStartedToConsultantNotification({ required this.type, required this.isRead, required this.planName, required this.customerName, required this.createdAt, }); factory ChosenPlanStartedToConsultantNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanStartedToConsultantNotification( type: type, isRead: isRead ?? false, planName: json['plan_name'], customerName: json['client_name'], createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanTomorrowReminderToConsultantNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; @override final DateTime createdAt; ChosenPlanTomorrowReminderToConsultantNotification({ required this.type, required this.planName, required this.customerName, required this.isRead, required this.createdAt, }); factory ChosenPlanTomorrowReminderToConsultantNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanTomorrowReminderToConsultantNotification( type: type, planName: json['plan_name'], customerName: json['client_name'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PlanSubscriptionPaidToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; @override final DateTime createdAt; PlanSubscriptionPaidToAuthorNotification({ required this.type, required this.isRead, required this.planName, required this.customerName, required this.createdAt, }); factory PlanSubscriptionPaidToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PlanSubscriptionPaidToAuthorNotification( type: type, isRead: isRead ?? false, planName: json['plan_name'], customerName: json['user_name'], createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanFinishedToConsultantNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; final int planId; @override final DateTime createdAt; ChosenPlanFinishedToConsultantNotification({ required this.type, required this.planName, required this.customerName, required this.planId, required this.isRead, required this.createdAt, }); factory ChosenPlanFinishedToConsultantNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanFinishedToConsultantNotification( type: type, planName: json['plan_name'], customerName: json['client_name'], planId: json['plan_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanLastDayFinishedForUser implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; ChosenPlanLastDayFinishedForUser({required this.type, required this.isRead, required this.createdAt}); factory ChosenPlanLastDayFinishedForUser.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanLastDayFinishedForUser( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanConsultantLastDayStarted implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String chatId; final String chatUrl; @override final DateTime createdAt; ChosenPlanConsultantLastDayStarted({ required this.type, required this.planName, required this.planId, required this.chatId, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ChosenPlanConsultantLastDayStarted.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanConsultantLastDayStarted( type: type, planName: json['plan_name'], planId: json['plan_id'], chatId: json['chat_id'], chatUrl: json['chat_url'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ComplaintToModerationForUser implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String message; final int entityId; final String entityType; @override final DateTime createdAt; ComplaintToModerationForUser({ required this.type, required this.message, required this.entityId, required this.entityType, required this.isRead, required this.createdAt, }); factory ComplaintToModerationForUser.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ComplaintToModerationForUser( type: type, message: json['message'], entityId: json['entity_id'], entityType: json['entity_type'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class CommentReplied implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String entityName; final int commentedEntityId; final String commentedEntityType; final String author; final int authorId; final int parentCommentId; @override final DateTime createdAt; CommentReplied({ required this.type, required this.entityName, required this.commentedEntityId, required this.commentedEntityType, required this.author, required this.authorId, required this.parentCommentId, required this.isRead, required this.createdAt, }); factory CommentReplied.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return CommentReplied( type: type, entityName: json['entity_name'], commentedEntityId: json['commented_entity_id'], commentedEntityType: json['commented_entity_type'], author: json['author'], authorId: json['author_id'], parentCommentId: json['parrent_comment_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ScoreAdded implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String scoreKey; final int scorableId; final String scorableType; final String scorableName; final String scorableSlug; final int scoreValue; @override final DateTime createdAt; ScoreAdded({ required this.type, required this.scoreKey, required this.scorableId, required this.scorableType, required this.scorableName, required this.scorableSlug, required this.scoreValue, required this.isRead, required this.createdAt, }); factory ScoreAdded.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ScoreAdded( type: type, scoreKey: json['score_key'], scorableId: json['scorable_id'], scorableType: json['scorable_type'], scorableName: json['scorable_name'] ?? '', scorableSlug: json['scorable_slug'] ?? '', scoreValue: json['score_value'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class EntityCommented implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String entityName; final int entityId; final String entityType; final String entityTranslatedType; final String entityUrl; final String authorName; final int authorId; final String authorSlug; @override final DateTime createdAt; EntityCommented({ required this.type, required this.entityName, required this.entityId, required this.entityType, required this.entityTranslatedType, required this.entityUrl, required this.authorName, required this.authorId, required this.authorSlug, required this.isRead, required this.createdAt, }); factory EntityCommented.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return EntityCommented( type: type, entityName: json['entity_name'], entityId: json['entity_id'], entityType: json['entity_type'], entityTranslatedType: json['entity_traslated_type'], entityUrl: json['entity_url'], authorName: json['author_name'], authorId: json['author_id'], authorSlug: json['author_slug'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class UnknownNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; UnknownNotification({required this.type, this.isRead = true, DateTime? createdAt}) : createdAt = createdAt ?? DateTime.fromMillisecondsSinceEpoch(0); } enum NotificationType { planSubscriptionStartedToAuthor, planSubscriptionCanceledToAuthor, chosenPlanStartedToClientNotification, chosenPlanTomorrowReminderToClientNotification, diaryReminderNotification, consultantLeftComment, personalizedDietIsDefined, chosenPlanFinishedToClient, planSubscriptionCanceledToCustomer, chosenPlanStartedToConsultantNotification, chosenPlanTomorrowReminderToConsultantNotification, planSubscriptionPaidToAuthor, chosenPlanFinishedToConsultant, chosenPlanLastDayFinishedForUser, // Новые типы chosenPlanConsultantLastDayStarted, complaintToModerationForUser, commentReplied, scoreAdded, entityCommented, unknown; static NotificationType getTypeFromString(String type) => switch (type) { 'App\\Notifications\\Plan\\PlanSubscriptionStartedToAuthor' => NotificationType.planSubscriptionStartedToAuthor, 'App\\Notifications\\Plan\\PlanSubscriptionCanceledToAuthor' => NotificationType.planSubscriptionCanceledToAuthor, 'App\\Notifications\\Plan\\ChosenPlanStartedToClientNotification' => NotificationType.chosenPlanStartedToClientNotification, 'App\\Notifications\\Plan\\ChosenPlanTomorrowReminderToClientNotification' => NotificationType.chosenPlanStartedToClientNotification, 'App\\Notifications\\DiaryReminderNotification' => NotificationType.diaryReminderNotification, 'App\\Notifications\\Plan\\ConsultantLeftComment' => NotificationType.consultantLeftComment, 'App\\Notifications\\Plan\\PersonalizedDietIsDefined' => NotificationType.personalizedDietIsDefined, 'App\\Notifications\\Plan\\ChosenPlanFinishedToClient' => NotificationType.chosenPlanFinishedToClient, 'App\\Notifications\\Plan\\PlanSubscriptionCanceledToCustomer' => NotificationType.planSubscriptionCanceledToCustomer, 'App\\Notifications\\Plan\\ChosenPlanStartedToConsultantNotification' => NotificationType.chosenPlanStartedToConsultantNotification, 'App\\Notifications\\Plan\\ChosenPlanTomorrowReminderToConsultantNotification' => NotificationType.chosenPlanTomorrowReminderToConsultantNotification, 'App\\Notifications\\Plan\\PlanSubscriptionPaidToAuthor' => NotificationType.planSubscriptionPaidToAuthor, 'App\\Notifications\\Plan\\ChosenPlanFinishedToConsultant' => NotificationType.chosenPlanFinishedToConsultant, 'App\\Notifications\\ChosenPlan\\LastDayFinishedForUser' => NotificationType.chosenPlanLastDayFinishedForUser, // Новые маппинги 'App\\Notifications\\ChosenPlan\\LastDayStartedForConsultant' => NotificationType.chosenPlanConsultantLastDayStarted, 'App\\Notifications\\ComplaintToModerationNotify' => NotificationType.complaintToModerationForUser, 'App\\Notifications\\Comment\\Replied' => NotificationType.commentReplied, 'App\\Notifications\\Score\\ScoreAdded' => NotificationType.scoreAdded, 'App\\Notifications\\Comment\\EntityCommented' => NotificationType.entityCommented, _ => NotificationType.unknown, }; } DateTime parseDate(String date) => DateTime.parse(date).toLocal();