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 int planId; final String customerName; final int userId; final String userPhotoPath; final String chatId; final String chatUrl; @override final DateTime createdAt; PlanSubscriptionStartedToAuthorNotification({ required this.type, required this.planName, required this.planId, required this.customerName, required this.userId, required this.userPhotoPath, required this.chatId, required this.chatUrl, 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'] ?? '', planId: json['plan_id'] ?? 0, customerName: json['user_name'] ?? '', userId: json['user_id'] ?? 0, userPhotoPath: json['user_photo_path'] ?? '', chatId: json['chat_id']?.toString() ?? '', chatUrl: json['chat_url'] ?? '', 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 int planId; final String customerName; final int userId; final String userPhotoPath; final String chatUrl; @override final DateTime createdAt; PlanSubscriptionCanceledToAuthorNotification({ required this.type, required this.planName, required this.planId, required this.customerName, required this.userId, required this.userPhotoPath, required this.chatUrl, 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'] ?? '', planId: json['plan_id'] ?? 0, customerName: json['user_name'] ?? '', userId: json['user_id'] ?? 0, userPhotoPath: json['user_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', 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; final String consultantName; final String peerProfileUrl; @override final DateTime createdAt; ChosenPlanStartedToClientNotification({ required this.type, required this.planName, required this.planId, required this.consultantName, required this.peerProfileUrl, 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'] ?? 0, consultantName: json['consultant_name'] ?? '', peerProfileUrl: json['peer_profile_url'] ?? '', 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; final String consultantName; final int chatId; @override final DateTime createdAt; ChosenPlanTomorrowReminderToClientNotification({ required this.type, required this.planName, required this.consultantName, required this.chatId, 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'] ?? '', consultantName: json['consultant_name'] ?? '', chatId: json['chat_id'] ?? 0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class DiaryReminderNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final int? diaryId; final String? message; @override final DateTime createdAt; DiaryReminderNotification({required this.type, required this.isRead, this.diaryId, this.message, required this.createdAt}); factory DiaryReminderNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return DiaryReminderNotification( type: type, isRead: isRead ?? false, diaryId: json['diary_id'], message: json['message'], createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantLeftCommentNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final int chosenPlanId; final int diaryId; final DateTime date; final String planName; final String userName; final String consultantName; @override final DateTime createdAt; ConsultantLeftCommentNotification({ required this.type, required this.chosenPlanId, required this.diaryId, required this.date, required this.planName, required this.userName, required this.consultantName, required this.isRead, required this.createdAt, }); factory ConsultantLeftCommentNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantLeftCommentNotification( type: type, chosenPlanId: json['chosen_plan_id'] ?? 0, diaryId: json['diary_id'] ?? 0, date: parseDate(json['diary_date'] ?? DateTime.now().toIso8601String()), planName: json['plan_name'] ?? '', userName: json['user_name'] ?? '', consultantName: json['consultant_name'] ?? '', 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; final int chosenPlanId; final String consultantName; final String consultantPhotoPath; final String consultantProfileUrl; final int consultantId; @override final DateTime createdAt; ChosenPlanFinishedToClientNotification({ required this.type, required this.planName, required this.chosenPlanId, required this.consultantName, required this.consultantPhotoPath, required this.consultantProfileUrl, required this.consultantId, 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'] ?? '', chosenPlanId: json['chosen_plan_id'] ?? 0, consultantName: json['consultant_name'] ?? '', consultantPhotoPath: json['consultant_photo_path'] ?? '', consultantProfileUrl: json['consultant_profile_url'] ?? '', consultantId: json['consultant_id'] ?? 0, 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; final int planId; final String authorName; final int authorId; final String authorPhotoPath; final String chatUrl; @override final DateTime createdAt; PlanSubscriptionCanceledToCustomerNotification({ required this.type, required this.planName, required this.planId, required this.authorName, required this.authorId, required this.authorPhotoPath, required this.chatUrl, 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'] ?? '', planId: json['plan_id'] ?? 0, authorName: json['author_name'] ?? '', authorId: json['author_id'] ?? 0, authorPhotoPath: json['author_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', 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; final int planId; final int customerId; final String peerProfileUrl; final String consultationUrl; @override final DateTime createdAt; ChosenPlanStartedToConsultantNotification({ required this.type, required this.isRead, required this.planName, required this.customerName, required this.planId, required this.customerId, required this.peerProfileUrl, required this.consultationUrl, 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'] ?? '', planId: json['plan_id'] ?? 0, customerId: json['client_id'] ?? 0, peerProfileUrl: json['peer_profile_url'] ?? '', consultationUrl: json['consultation_url'] ?? '', 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; final int chatId; @override final DateTime createdAt; ChosenPlanTomorrowReminderToConsultantNotification({ required this.type, required this.planName, required this.customerName, required this.chatId, 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'] ?? '', chatId: json['chat_id'] ?? 0, 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 int planId; final String customerName; final int userId; final String userPhotoPath; final String chatUrl; @override final DateTime createdAt; PlanSubscriptionPaidToAuthorNotification({ required this.type, required this.isRead, required this.planName, required this.planId, required this.customerName, required this.userId, required this.userPhotoPath, required this.chatUrl, 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'] ?? '', planId: json['plan_id'] ?? 0, customerName: json['user_name'] ?? '', userId: json['user_id'] ?? 0, userPhotoPath: json['user_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', 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; final int chosenPlanId; final String clientPhotoPath; final int clientId; @override final DateTime createdAt; ChosenPlanFinishedToConsultantNotification({ required this.type, required this.planName, required this.customerName, required this.planId, required this.chosenPlanId, required this.clientPhotoPath, required this.clientId, 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'] ?? 0, chosenPlanId: json['chosen_plan_id'] ?? 0, clientPhotoPath: json['client_photo_path'] ?? '', clientId: json['client_id'] ?? 0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanLastDayFinishedForUser implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int chosenPlanId; final String complaintUrl; final String chatUrl; @override final DateTime createdAt; ChosenPlanLastDayFinishedForUser({ required this.type, required this.isRead, required this.planName, required this.chosenPlanId, required this.complaintUrl, required this.chatUrl, required this.createdAt, }); factory ChosenPlanLastDayFinishedForUser.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanLastDayFinishedForUser( type: type, isRead: isRead ?? false, planName: json['plan_name'] ?? '', chosenPlanId: json['chosen_plan_id'] ?? 0, complaintUrl: json['complaintUrl'] ?? json['complaint_url'] ?? '', chatUrl: json['chatUrl'] ?? json['chat_url'] ?? '', 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'] ?? 0, chatId: json['chat_id']?.toString() ?? '', 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; final String entityName; @override final DateTime createdAt; ComplaintToModerationForUser({ required this.type, required this.message, required this.entityId, required this.entityType, required this.entityName, 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'] ?? 0, entityType: json['entity_type'] ?? '', entityName: json['entity_name'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } enum CommentedEntityType { diet, blogPost, unknown; factory CommentedEntityType.fromJson(String type) { return switch (type) { 'diet' => CommentedEntityType.diet, 'Modules\\UserGeneratedPublicContent\\Models\\Diet' => CommentedEntityType.diet, 'blog-post' => CommentedEntityType.blogPost, 'Modules\\UserGeneratedPublicContent\\Models\\BlogPost' => CommentedEntityType.blogPost, _ => CommentedEntityType.unknown, }; } } class CommentReplied implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String entityName; final int commentedEntityId; final CommentedEntityType commentedEntityType; final String author; final int authorId; final int parentCommentId; final int? commentId; @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, this.commentId, 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: CommentedEntityType.fromJson(json['commented_entity_type']), author: json['author'], authorId: json['author_id'], parentCommentId: json['parrent_comment_id'], commentId: json['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 CommentedEntityType entityType; final String entityTranslatedType; final String entityUrl; final String authorName; final int authorId; final String authorSlug; final int? commentId; @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, this.commentId, 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: CommentedEntityType.fromJson(json['entity_type']), entityTranslatedType: json['entity_traslated_type'], entityUrl: json['entity_url'], authorName: json['author_name'], authorId: json['author_id'], authorSlug: json['author_slug'], commentId: json['comment_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PlanSubscriptionExpiredNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; @override final DateTime createdAt; PlanSubscriptionExpiredNotification({required this.type, required this.planName, required this.customerName, required this.isRead, required this.createdAt}); factory PlanSubscriptionExpiredNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PlanSubscriptionExpiredNotification( type: type, planName: json['plan_name'], customerName: json['user_name'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PlanSubscriptionRenewedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String customerName; final String renewalDate; @override final DateTime createdAt; PlanSubscriptionRenewedNotification({ required this.type, required this.planName, required this.customerName, required this.renewalDate, required this.isRead, required this.createdAt, }); factory PlanSubscriptionRenewedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PlanSubscriptionRenewedNotification( type: type, planName: json['plan_name'], customerName: json['user_name'], renewalDate: json['renewal_date'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantAssignedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String consultantName; final String planName; final int planId; @override final DateTime createdAt; ConsultantAssignedNotification({ required this.type, required this.consultantName, required this.planName, required this.planId, required this.isRead, required this.createdAt, }); factory ConsultantAssignedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantAssignedNotification( type: type, consultantName: json['consultant_name'], planName: json['plan_name'], planId: json['plan_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantUnassignedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String consultantName; final String planName; final int planId; @override final DateTime createdAt; ConsultantUnassignedNotification({ required this.type, required this.consultantName, required this.planName, required this.planId, required this.isRead, required this.createdAt, }); factory ConsultantUnassignedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantUnassignedNotification( type: type, consultantName: json['consultant_name'], planName: json['plan_name'], planId: json['plan_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PaymentFailedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String errorMessage; final String paymentMethod; @override final DateTime createdAt; PaymentFailedNotification({ required this.type, required this.planName, required this.errorMessage, required this.paymentMethod, required this.isRead, required this.createdAt, }); factory PaymentFailedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PaymentFailedNotification( type: type, planName: json['plan_name'], errorMessage: json['error_message'], paymentMethod: json['payment_method'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PaymentSuccessfulNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final double amount; final String currency; final String transactionId; @override final DateTime createdAt; PaymentSuccessfulNotification({ required this.type, required this.planName, required this.amount, required this.currency, required this.transactionId, required this.isRead, required this.createdAt, }); factory PaymentSuccessfulNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PaymentSuccessfulNotification( type: type, planName: json['plan_name'], amount: (json['amount'] as num).toDouble(), currency: json['currency'], transactionId: json['transaction_id'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class GoalAchievedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String goalName; final String goalType; final double achievedValue; final double targetValue; @override final DateTime createdAt; GoalAchievedNotification({ required this.type, required this.goalName, required this.goalType, required this.achievedValue, required this.targetValue, required this.isRead, required this.createdAt, }); factory GoalAchievedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return GoalAchievedNotification( type: type, goalName: json['goal_name'], goalType: json['goal_type'], achievedValue: (json['achieved_value'] as num).toDouble(), targetValue: (json['target_value'] as num).toDouble(), isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class WorkoutReminderNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String workoutName; final String workoutType; final int duration; @override final DateTime createdAt; WorkoutReminderNotification({ required this.type, required this.workoutName, required this.workoutType, required this.duration, required this.isRead, required this.createdAt, }); factory WorkoutReminderNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return WorkoutReminderNotification( type: type, workoutName: json['workout_name'], workoutType: json['workout_type'], duration: json['duration'], isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class MealReminderNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String mealName; final String mealType; final int calories; @override final DateTime createdAt; MealReminderNotification({ required this.type, required this.mealName, required this.mealType, required this.calories, required this.isRead, required this.createdAt, }); factory MealReminderNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return MealReminderNotification( type: type, mealName: json['meal_name'], mealType: json['meal_type'], calories: json['calories'], 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, required this.createdAt}); factory UnknownNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return UnknownNotification(type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String())); } } class DietCancelledNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String dietName; final int dietId; @override final DateTime createdAt; DietCancelledNotification({required this.type, required this.dietName, required this.dietId, required this.isRead, required this.createdAt}); factory DietCancelledNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return DietCancelledNotification( type: type, dietName: json['diet_name'] ?? '', dietId: json['diet_id'] ?? 0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class DietStartedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String dietName; final int dietId; @override final DateTime createdAt; DietStartedNotification({required this.type, required this.dietName, required this.dietId, required this.isRead, required this.createdAt}); factory DietStartedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return DietStartedNotification( type: type, dietName: json['diet_name'] ?? '', dietId: json['diet_id'] ?? 0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class DietExpiredNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String dietName; final int dietId; @override final DateTime createdAt; DietExpiredNotification({required this.type, required this.dietName, required this.dietId, required this.isRead, required this.createdAt}); factory DietExpiredNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return DietExpiredNotification( type: type, dietName: json['diet_name'] ?? '', dietId: json['diet_id'] ?? 0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class DietWillStartedInNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String dietName; final int dietId; final String startDate; @override final DateTime createdAt; DietWillStartedInNotification({ required this.type, required this.dietName, required this.dietId, required this.startDate, required this.isRead, required this.createdAt, }); factory DietWillStartedInNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return DietWillStartedInNotification( type: type, dietName: json['diet_name'] ?? '', dietId: json['diet_id'] ?? 0, startDate: json['start_date'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class DietCanNotBeStartedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String dietName; final int dietId; final String reason; @override final DateTime createdAt; DietCanNotBeStartedNotification({ required this.type, required this.dietName, required this.dietId, required this.reason, required this.isRead, required this.createdAt, }); factory DietCanNotBeStartedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return DietCanNotBeStartedNotification( type: type, dietName: json['diet_name'] ?? '', dietId: json['diet_id'] ?? 0, reason: json['reason'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PersonalDietCreationNeededNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String userName; final String consultantName; final String myDietsUrl; @override final DateTime createdAt; PersonalDietCreationNeededNotification({ required this.type, required this.userName, required this.consultantName, required this.myDietsUrl, required this.isRead, required this.createdAt, }); factory PersonalDietCreationNeededNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PersonalDietCreationNeededNotification( type: type, userName: json['user_name'] ?? '', consultantName: json['consultant_name'] ?? '', myDietsUrl: json['myDietsUrl'] ?? json['my_diets_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanClientLastDayFinishedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int chosenPlanId; final String complaintUrl; final String chatUrl; @override final DateTime createdAt; ChosenPlanClientLastDayFinishedNotification({ required this.type, required this.planName, required this.chosenPlanId, required this.complaintUrl, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ChosenPlanClientLastDayFinishedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanClientLastDayFinishedNotification( type: type, planName: json['plan_name'] ?? '', chosenPlanId: json['chosen_plan_id'] ?? 0, complaintUrl: json['complaintUrl'] ?? json['complaint_url'] ?? '', chatUrl: json['chatUrl'] ?? json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenPlanClientLastDayStartedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int chosenPlanId; final String lastDayDiaryUrl; @override final DateTime createdAt; ChosenPlanClientLastDayStartedNotification({ required this.type, required this.planName, required this.chosenPlanId, required this.lastDayDiaryUrl, required this.isRead, required this.createdAt, }); factory ChosenPlanClientLastDayStartedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenPlanClientLastDayStartedNotification( type: type, planName: json['plan_name'] ?? '', chosenPlanId: json['chosen_plan_id'] ?? 0, lastDayDiaryUrl: json['last_day_diary_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class StayOnTrackToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String userName; final int dayNum; final int diaryDayId; @override final DateTime createdAt; StayOnTrackToAuthorNotification({ required this.type, required this.planName, required this.userName, required this.dayNum, required this.diaryDayId, required this.isRead, required this.createdAt, }); factory StayOnTrackToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return StayOnTrackToAuthorNotification( type: type, planName: json['plan_name'] ?? '', userName: json['user_name'] ?? '', dayNum: json['day_num'] ?? 0, diaryDayId: json['diary_day_id'] ?? 0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientStartPlanSubscriptionToSubscriberNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String authorName; final int authorId; final String authorPhotoPath; final String chatUrl; final String chatId; final String startDate; @override final DateTime createdAt; ClientStartPlanSubscriptionToSubscriberNotification({ required this.type, required this.planName, required this.planId, required this.authorName, required this.authorId, required this.authorPhotoPath, required this.chatUrl, required this.chatId, required this.startDate, required this.isRead, required this.createdAt, }); factory ClientStartPlanSubscriptionToSubscriberNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientStartPlanSubscriptionToSubscriberNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, authorName: json['author_name'] ?? '', authorId: json['author_id'] ?? 0, authorPhotoPath: json['author_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', chatId: json['chat_id']?.toString() ?? '', startDate: json['start_date']?.toString() ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantConfirmPlanSubscriptionToSubscriberNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String consultantName; final int authorId; final String authorPhotoPath; final String chatUrl; @override final DateTime createdAt; ConsultantConfirmPlanSubscriptionToSubscriberNotification({ required this.type, required this.planName, required this.planId, required this.consultantName, required this.authorId, required this.authorPhotoPath, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ConsultantConfirmPlanSubscriptionToSubscriberNotification.fromJson( Map json, NotificationType type, { bool? isRead, String? createdAt, }) { return ConsultantConfirmPlanSubscriptionToSubscriberNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, consultantName: json['author_name'] ?? json['consultant_name'] ?? '', authorId: json['author_id'] ?? 0, authorPhotoPath: json['author_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientPaidPlanSubscriptionToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String clientName; final int userId; final String userPhotoPath; final String chatUrl; @override final DateTime createdAt; ClientPaidPlanSubscriptionToAuthorNotification({ required this.type, required this.planName, required this.planId, required this.clientName, required this.userId, required this.userPhotoPath, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ClientPaidPlanSubscriptionToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientPaidPlanSubscriptionToAuthorNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, clientName: json['user_name'] ?? '', userId: json['user_id'] ?? 0, userPhotoPath: json['user_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantLeftDiaryCommentNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final int chosenPlanId; final int diaryId; final String planName; final String userName; final String consultantName; final DateTime diaryDate; @override final DateTime createdAt; ConsultantLeftDiaryCommentNotification({ required this.type, required this.chosenPlanId, required this.diaryId, required this.planName, required this.userName, required this.consultantName, required this.diaryDate, required this.isRead, required this.createdAt, }); factory ConsultantLeftDiaryCommentNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantLeftDiaryCommentNotification( type: type, chosenPlanId: json['chosen_plan_id'] ?? 0, diaryId: json['diary_id'] ?? 0, planName: json['plan_name'] ?? '', userName: json['user_name'] ?? '', consultantName: json['consultant_name'] ?? '', diaryDate: parseDate(json['diary_date'] ?? DateTime.now().toIso8601String()), isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantConfirmPlanSubscriptionToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String clientName; final int userId; final String userPhotoPath; final String chatUrl; @override final DateTime createdAt; ConsultantConfirmPlanSubscriptionToAuthorNotification({ required this.type, required this.planName, required this.planId, required this.clientName, required this.userId, required this.userPhotoPath, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ConsultantConfirmPlanSubscriptionToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantConfirmPlanSubscriptionToAuthorNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, clientName: json['user_name'] ?? '', userId: json['user_id'] ?? 0, userPhotoPath: json['user_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientPaidPlanSubscriptionToSubscriberNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String authorName; final int authorId; final String authorPhotoPath; final String chatUrl; @override final DateTime createdAt; ClientPaidPlanSubscriptionToSubscriberNotification({ required this.type, required this.planName, required this.planId, required this.authorName, required this.authorId, required this.authorPhotoPath, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ClientPaidPlanSubscriptionToSubscriberNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientPaidPlanSubscriptionToSubscriberNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, authorName: json['author_name'] ?? '', authorId: json['author_id'] ?? 0, authorPhotoPath: json['author_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientStartPlanSubscriptionToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String clientName; final int userId; final String userPhotoPath; final String chatId; final String chatUrl; @override final DateTime createdAt; ClientStartPlanSubscriptionToAuthorNotification({ required this.type, required this.planName, required this.planId, required this.clientName, required this.userId, required this.userPhotoPath, required this.chatId, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ClientStartPlanSubscriptionToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientStartPlanSubscriptionToAuthorNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, clientName: json['user_name'] ?? '', userId: json['user_id'] ?? 0, userPhotoPath: json['user_photo_path'] ?? '', chatId: json['chat_id']?.toString() ?? '', chatUrl: json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientCancelPlanSubscriptionToAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String clientName; final int userId; final String userPhotoPath; final String chatUrl; @override final DateTime createdAt; ClientCancelPlanSubscriptionToAuthorNotification({ required this.type, required this.planName, required this.planId, required this.clientName, required this.userId, required this.userPhotoPath, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ClientCancelPlanSubscriptionToAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientCancelPlanSubscriptionToAuthorNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, clientName: json['user_name'] ?? '', userId: json['user_id'] ?? 0, userPhotoPath: json['user_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientCancelPlanSubscriptionToSubscriberNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int planId; final String authorName; final int authorId; final String authorPhotoPath; final String chatUrl; @override final DateTime createdAt; ClientCancelPlanSubscriptionToSubscriberNotification({ required this.type, required this.planName, required this.planId, required this.authorName, required this.authorId, required this.authorPhotoPath, required this.chatUrl, required this.isRead, required this.createdAt, }); factory ClientCancelPlanSubscriptionToSubscriberNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientCancelPlanSubscriptionToSubscriberNotification( type: type, planName: json['plan_name'] ?? '', planId: json['plan_id'] ?? 0, authorName: json['author_name'] ?? '', authorId: json['author_id'] ?? 0, authorPhotoPath: json['author_photo_path'] ?? '', chatUrl: json['chat_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class UserDailyReportCompletedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final int chosenPlanId; final int diaryId; final String planName; final String clientName; final String consultantName; @override final DateTime createdAt; UserDailyReportCompletedNotification({ required this.type, required this.chosenPlanId, required this.diaryId, required this.planName, required this.clientName, required this.consultantName, required this.isRead, required this.createdAt, }); factory UserDailyReportCompletedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return UserDailyReportCompletedNotification( type: type, chosenPlanId: json['chosen_plan_id'] ?? 0, diaryId: json['diary_id'] ?? 0, planName: json['plan_name'] ?? '', clientName: json['user_name'] ?? '', consultantName: json['consultant_name'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class StayOnTrackToCustomerNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final int dayNum; final int diaryDayId; @override final DateTime createdAt; StayOnTrackToCustomerNotification({ required this.type, required this.planName, required this.dayNum, required this.diaryDayId, required this.isRead, required this.createdAt, }); factory StayOnTrackToCustomerNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return StayOnTrackToCustomerNotification( type: type, planName: json['plan_name'] ?? '', dayNum: json['day_num'] ?? 0, diaryDayId: json['diary_day_id'] ?? 0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PhoneChangedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String oldPhone; final String newPhone; @override final DateTime createdAt; PhoneChangedNotification({required this.type, required this.oldPhone, required this.newPhone, required this.isRead, required this.createdAt}); factory PhoneChangedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PhoneChangedNotification( type: type, oldPhone: json['old_phone'] ?? '', newPhone: json['new_phone'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class SubscriptionNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String userName; final String userPhotoPath; final String userProfileUrl; @override final DateTime createdAt; SubscriptionNotification({ required this.type, required this.userName, required this.userPhotoPath, required this.userProfileUrl, required this.isRead, required this.createdAt, }); factory SubscriptionNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return SubscriptionNotification( type: type, userName: json['user_name'] ?? '', userPhotoPath: json['user_photo_path'] ?? '', userProfileUrl: json['user_profile_url'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class BadgeAwardedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String badgeTitle; final String badgeType; final String badgeImage; @override final DateTime createdAt; BadgeAwardedNotification({ required this.type, required this.badgeTitle, required this.badgeType, required this.badgeImage, required this.isRead, required this.createdAt, }); factory BadgeAwardedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return BadgeAwardedNotification( type: type, badgeTitle: json['badge_title'] ?? '', badgeType: json['badge_type'] ?? '', badgeImage: json['badge_image'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class BadgeRevokedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String badgeTitle; final String badgeType; final String badgeImage; @override final DateTime createdAt; BadgeRevokedNotification({ required this.type, required this.badgeTitle, required this.badgeType, required this.badgeImage, required this.isRead, required this.createdAt, }); factory BadgeRevokedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return BadgeRevokedNotification( type: type, badgeTitle: json['badge_title'] ?? '', badgeType: json['badge_type'] ?? '', badgeImage: json['badge_image'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantRequestStartedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String consultantName; @override final DateTime createdAt; ConsultantRequestStartedNotification({required this.type, required this.consultantName, required this.isRead, required this.createdAt}); factory ConsultantRequestStartedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantRequestStartedNotification( type: type, consultantName: json['consultant_name'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientCloseComplaintSuccessNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; @override final DateTime createdAt; ClientCloseComplaintSuccessNotification({required this.type, required this.planName, required this.isRead, required this.createdAt}); factory ClientCloseComplaintSuccessNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientCloseComplaintSuccessNotification( type: type, planName: json['plan_name'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientRefundSuccessNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final double amount; final String reason; @override final DateTime createdAt; ClientRefundSuccessNotification({ required this.type, required this.planName, required this.amount, required this.reason, required this.isRead, required this.createdAt, }); factory ClientRefundSuccessNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientRefundSuccessNotification( type: type, planName: json['plan_name'] ?? '', amount: (json['amount'] as num?)?.toDouble() ?? 0.0, reason: json['reason'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantRefundSuccessNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String clientName; final double amount; @override final DateTime createdAt; ConsultantRefundSuccessNotification({ required this.type, required this.planName, required this.clientName, required this.amount, required this.isRead, required this.createdAt, }); factory ConsultantRefundSuccessNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantRefundSuccessNotification( type: type, planName: json['plan_name'] ?? '', clientName: json['client_name'] ?? '', amount: (json['amount'] as num?)?.toDouble() ?? 0.0, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ClientRejectSuccessNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; @override final DateTime createdAt; ClientRejectSuccessNotification({required this.type, required this.planName, required this.isRead, required this.createdAt}); factory ClientRejectSuccessNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ClientRejectSuccessNotification( type: type, planName: json['plan_name'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ConsultantRejectSuccessNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String planName; final String clientName; @override final DateTime createdAt; ConsultantRejectSuccessNotification({required this.type, required this.planName, required this.clientName, required this.isRead, required this.createdAt}); factory ConsultantRejectSuccessNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantRejectSuccessNotification( type: type, planName: json['plan_name'] ?? '', clientName: json['user_name'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ScoreSubstractedNotification 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; ScoreSubstractedNotification({ 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 ScoreSubstractedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ScoreSubstractedNotification( 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 ProductStatusUpdatedForAuthorNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final String productName; final int productId; final String author; final int authorId; final String status; final String subject; final String messageLine; @override final DateTime createdAt; ProductStatusUpdatedForAuthorNotification({ required this.type, required this.productName, required this.productId, required this.author, required this.authorId, required this.status, required this.subject, required this.messageLine, required this.isRead, required this.createdAt, }); factory ProductStatusUpdatedForAuthorNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ProductStatusUpdatedForAuthorNotification( type: type, productName: json['product_name'] ?? '', productId: json['product_id'] ?? 0, author: json['author'] ?? '', authorId: json['author_id'] ?? 0, status: json['status'] ?? '', subject: json['subject'] ?? '', messageLine: json['messageLine'] ?? json['message_line'] ?? '', isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class DiaryReminderForUsersNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; final int? diaryId; final String? message; @override final DateTime createdAt; DiaryReminderForUsersNotification({required this.type, required this.isRead, this.diaryId, this.message, required this.createdAt}); factory DiaryReminderForUsersNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { final data = json['data'] is Map ? json['data'] as Map : json; return DiaryReminderForUsersNotification( type: type, isRead: isRead ?? false, diaryId: data['diary_id'], message: data['message'], createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class PersonalDietIsDefinedToCustomerNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final int chosenPlanId; final int dietId; final String planName; final String userName; final String consultantName; final String dietName; final String role; final String peerSlug; final String peerImagePath; PersonalDietIsDefinedToCustomerNotification({ required this.type, required this.isRead, required this.createdAt, required this.chosenPlanId, required this.dietId, required this.planName, required this.userName, required this.consultantName, required this.dietName, required this.role, required this.peerSlug, required this.peerImagePath, }); factory PersonalDietIsDefinedToCustomerNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return PersonalDietIsDefinedToCustomerNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), chosenPlanId: json['chosen_plan_id'] ?? 0, dietId: json['diet_id'] ?? 0, planName: json['plan_name'] ?? '', userName: json['user_name'] ?? '', consultantName: json['consultant_name'] ?? '', dietName: json['diet_name'] ?? '', role: json['role']?.toString() ?? '', peerSlug: json['peer_slug'] ?? '', peerImagePath: json['peer_image_path'] ?? '', ); } } // New Model Classes for Comprehensive Support class ConsultantEducationUpdatedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String consultantName; ConsultantEducationUpdatedNotification({required this.type, required this.isRead, required this.createdAt, required this.consultantName}); factory ConsultantEducationUpdatedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ConsultantEducationUpdatedNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), consultantName: json['consultant_name'] ?? '', ); } } class ComplaintRegisteredNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String message; final int entityId; final String entityType; final String entityName; ComplaintRegisteredNotification({ required this.type, required this.isRead, required this.createdAt, required this.message, required this.entityId, required this.entityType, required this.entityName, }); factory ComplaintRegisteredNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ComplaintRegisteredNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), message: json['message'] ?? '', entityId: json['entity_id'] ?? 0, entityType: json['entity_type'] ?? '', entityName: json['entity_name'] ?? '', ); } } class ContentUnpublishedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String reason; final String entityName; ContentUnpublishedNotification({required this.type, required this.isRead, required this.createdAt, required this.reason, required this.entityName}); factory ContentUnpublishedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ContentUnpublishedNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), reason: json['reason'] ?? '', entityName: json['entity_name'] ?? '', ); } } class FinanceQuestionCreatedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String questionText; FinanceQuestionCreatedNotification({required this.type, required this.isRead, required this.createdAt, required this.questionText}); factory FinanceQuestionCreatedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return FinanceQuestionCreatedNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), questionText: json['question_text'] ?? '', ); } } class NewChatMessageNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String senderName; final String messagePreview; final int chatId; NewChatMessageNotification({ required this.type, required this.isRead, required this.createdAt, required this.senderName, required this.messagePreview, required this.chatId, }); factory NewChatMessageNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return NewChatMessageNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), senderName: json['sender_name'] ?? '', messagePreview: json['message_preview'] ?? '', chatId: json['chat_id'] ?? 0, ); } } class CompleteRegistrationNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; CompleteRegistrationNotification({required this.type, required this.isRead, required this.createdAt}); factory CompleteRegistrationNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return CompleteRegistrationNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), ); } } class ChosenDietExpiredNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String dietName; final int dietId; ChosenDietExpiredNotification({required this.type, required this.isRead, required this.createdAt, required this.dietName, required this.dietId}); factory ChosenDietExpiredNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return ChosenDietExpiredNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), dietName: json['diet_name'] ?? '', dietId: json['diet_id'] ?? 0, ); } } class MotivateUserNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String message; MotivateUserNotification({required this.type, required this.isRead, required this.createdAt, required this.message}); factory MotivateUserNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return MotivateUserNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), message: json['message'] ?? '', ); } } class CommentComplaintNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String commentPreview; final String reason; CommentComplaintNotification({required this.type, required this.isRead, required this.createdAt, required this.commentPreview, required this.reason}); factory CommentComplaintNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return CommentComplaintNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), commentPreview: json['comment_preview'] ?? '', reason: json['reason'] ?? '', ); } } class CommentDeletedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String commentPreview; CommentDeletedNotification({required this.type, required this.isRead, required this.createdAt, required this.commentPreview}); factory CommentDeletedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return CommentDeletedNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), commentPreview: json['comment_preview'] ?? '', ); } } class UserSubscribedNotification implements BaseNotificationModel { @override final NotificationType type; @override final bool isRead; @override final DateTime createdAt; final String userName; final String userPhotoPath; final String userProfileUrl; UserSubscribedNotification({ required this.type, required this.isRead, required this.createdAt, required this.userName, required this.userPhotoPath, required this.userProfileUrl, }); factory UserSubscribedNotification.fromJson(Map json, NotificationType type, {bool? isRead, String? createdAt}) { return UserSubscribedNotification( type: type, isRead: isRead ?? false, createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()), userName: json['user_name'] ?? '', userPhotoPath: json['user_photo_path'] ?? '', userProfileUrl: json['user_profile_url'] ?? '', ); } } enum NotificationType { // Diet related dietCancelled, dietStarted, dietExpired, dietWillStartedIn, dietCanNotBeStarted, chosenDietExpired, // New // Plan related personalDietCreationNeeded, chosenPlanClientLastDayFinished, chosenPlanConsultantLastDayStarted, chosenPlanClientLastDayStarted, stayOnTrackToAuthor, chosenPlanStartedToClient, clientStartPlanSubscriptionToSubscriber, consultantConfirmPlanSubscriptionToSubscriber, clientPaidPlanSubscriptionToAuthor, chosenPlanTomorrowReminderToClient, chosenPlanTomorrowReminderToConsultant, chosenPlanStartedToConsultant, consultantLeftDiaryComment, chosenPlanFinishedToClient, consultantConfirmPlanSubscriptionToAuthor, clientPaidPlanSubscriptionToSubscriber, clientStartPlanSubscriptionToAuthor, clientCancelPlanSubscriptionToAuthor, clientCancelPlanSubscriptionToSubscriber, userDailyReportCompleted, chosenPlanFinishedToConsultant, stayOnTrackToCustomer, personalDietIsDefinedToCustomer, // Comments entityCommented, commentReplied, commentComplaint, // New commentDeleted, // New // Profile phoneChanged, consultantEducationUpdated, // New completeRegistration, // New // Subscription subscription, userSubscribed, // New // Badges badgeAwarded, badgeRevoked, // Consultant consultantRequestStarted, motivateUser, // New // Complaints clientCloseComplaintSuccess, complaintToModerationForUser, complaintRegistered, // New contentUnpublished, // New contentUnpublishedComplaint, // New // Finance clientRefundSuccess, consultantRefundSuccess, clientRejectSuccess, consultantRejectSuccess, financeQuestionCreated, // New // Score scoreAdded, scoreSubstracted, // Product productStatusUpdatedForAuthor, // Diary diaryReminderForUsers, // Chat newChatMessage, // New // Legacy types (keeping for backward compatibility) planSubscriptionStartedToAuthor, planSubscriptionCanceledToAuthor, chosenPlanStartedToClientNotification, chosenPlanTomorrowReminderToClientNotification, diaryReminderNotification, consultantLeftComment, personalizedDietIsDefined, planSubscriptionCanceledToCustomer, chosenPlanStartedToConsultantNotification, chosenPlanTomorrowReminderToConsultantNotification, planSubscriptionPaidToAuthor, chosenPlanLastDayFinishedForUser, planSubscriptionExpired, planSubscriptionRenewed, consultantAssigned, consultantUnassigned, paymentFailed, paymentSuccessful, goalAchieved, workoutReminder, mealReminder, unknown; static NotificationType getTypeFromString(String type) => switch (type) { // New type-based mapping 'diet-cancelled' => NotificationType.dietCancelled, 'entity-commented' => NotificationType.entityCommented, 'comment-replied' => NotificationType.commentReplied, 'phone-changed' => NotificationType.phoneChanged, 'diet-started' => NotificationType.dietStarted, 'personal-diet-creation-needed-to-author' => NotificationType.personalDietCreationNeeded, 'chosen-plan-client-last-day-finished' => NotificationType.chosenPlanClientLastDayFinished, 'chosen-plan-consultant-last-day-started' => NotificationType.chosenPlanConsultantLastDayStarted, 'chosen-plan-client-last-day-started' => NotificationType.chosenPlanClientLastDayStarted, 'subscription' => NotificationType.subscription, 'badge-awarded' => NotificationType.badgeAwarded, 'badge-revoked' => NotificationType.badgeRevoked, 'diet-expired' => NotificationType.dietExpired, 'consultant-request-started' => NotificationType.consultantRequestStarted, 'diet-will-started-in' => NotificationType.dietWillStartedIn, 'client-close-complaint-success' => NotificationType.clientCloseComplaintSuccess, 'complaint-to-moderation-for-user' => NotificationType.complaintToModerationForUser, 'client-refund-success' => NotificationType.clientRefundSuccess, 'consultant-refund-success' => NotificationType.consultantRefundSuccess, 'client-reject-success' => NotificationType.clientRejectSuccess, 'consultant-reject-success' => NotificationType.consultantRejectSuccess, 'score-added' => NotificationType.scoreAdded, 'score-substracted' => NotificationType.scoreSubstracted, 'product-status-updated-for-author' => NotificationType.productStatusUpdatedForAuthor, 'diet-can-not-started' => NotificationType.dietCanNotBeStarted, 'stay-on-track-to-author' => NotificationType.stayOnTrackToAuthor, 'chosen-plan-started-to-client' => NotificationType.chosenPlanStartedToClient, 'client-start-plan-subscription-to-subscriber' => NotificationType.clientStartPlanSubscriptionToSubscriber, 'consultant-confirm-plan-subscription-to-subscriber' => NotificationType.consultantConfirmPlanSubscriptionToSubscriber, 'client-paid-plan-subscription-to-author' => NotificationType.clientPaidPlanSubscriptionToAuthor, 'chosen-plan-tomorrow-reminder-to-client' => NotificationType.chosenPlanTomorrowReminderToClient, 'chosen-plan-tomorrow-reminder-to-consultant' => NotificationType.chosenPlanTomorrowReminderToConsultant, 'chosen-plan-started-to-consultant' => NotificationType.chosenPlanStartedToConsultant, 'consultant-left-diary-comment' => NotificationType.consultantLeftDiaryComment, 'chosen-plan-finished-to-client' => NotificationType.chosenPlanFinishedToClient, 'consultant-confirm-plan-subscription-to-author' => NotificationType.consultantConfirmPlanSubscriptionToAuthor, 'client-paid-plan-subscription-to-subscriber' => NotificationType.clientPaidPlanSubscriptionToSubscriber, 'client-start-plan-subscription-to-author' => NotificationType.clientStartPlanSubscriptionToAuthor, 'client-cancel-plan-subscription-to-author' => NotificationType.clientCancelPlanSubscriptionToAuthor, 'client-cancel-plan-subscription-to-subscriber' => NotificationType.clientCancelPlanSubscriptionToSubscriber, 'user-daily-report-completed' => NotificationType.userDailyReportCompleted, 'chosen-plan-finished-to-consultant' => NotificationType.chosenPlanFinishedToConsultant, 'stay-on-track-to-customer' => NotificationType.stayOnTrackToCustomer, 'diary-reminder-for-users' => NotificationType.diaryReminderForUsers, 'personal-diet-is-defined-to-customer' => NotificationType.personalDietIsDefinedToCustomer, // New additions 'consultant-education-updated' => NotificationType.consultantEducationUpdated, 'complaint-registered' => NotificationType.complaintRegistered, 'content-unpublished' => NotificationType.contentUnpublished, 'content-unpublished-complaint' => NotificationType.contentUnpublishedComplaint, 'finance-question-created' => NotificationType.financeQuestionCreated, 'new-chat-message' => NotificationType.newChatMessage, 'complete-registration' => NotificationType.completeRegistration, 'chosen-diet-expired' => NotificationType.chosenDietExpired, 'motivate-user' => NotificationType.motivateUser, 'comment-complaint' => NotificationType.commentComplaint, 'comment-deleted' => NotificationType.commentDeleted, 'user-subscribed' => NotificationType.userSubscribed, // 'diary-reminder' => NotificationType.diaryReminder, // Already legacy? Check if it maps to diaryReminderNotification 'meal-reminder' => NotificationType.mealReminder, // Maps to legacy if string matches? No, legacy was App\\... // Legacy mapping 'App\\Notifications\\Plan\\PlanSubscriptionStartedToAuthor' => NotificationType.planSubscriptionStartedToAuthor, 'App\\Notifications\\Plan\\PlanSubscriptionCanceledToAuthor' => NotificationType.planSubscriptionCanceledToAuthor, 'App\\Notifications\\Plan\\ChosenPlanStartedToClientNotification' => NotificationType.chosenPlanStartedToClientNotification, 'App\\Notifications\\Plan\\ChosenPlanTomorrowReminderToClientNotification' => NotificationType.chosenPlanTomorrowReminderToClientNotification, '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, 'App\\Notifications\\Plan\\PlanSubscriptionExpired' => NotificationType.planSubscriptionExpired, 'App\\Notifications\\Plan\\PlanSubscriptionRenewed' => NotificationType.planSubscriptionRenewed, 'App\\Notifications\\Plan\\ConsultantAssigned' => NotificationType.consultantAssigned, 'App\\Notifications\\Plan\\ConsultantUnassigned' => NotificationType.consultantUnassigned, 'App\\Notifications\\Payment\\PaymentFailed' => NotificationType.paymentFailed, 'App\\Notifications\\Payment\\PaymentSuccessful' => NotificationType.paymentSuccessful, 'App\\Notifications\\Goal\\GoalAchieved' => NotificationType.goalAchieved, 'App\\Notifications\\Workout\\WorkoutReminder' => NotificationType.workoutReminder, 'App\\Notifications\\Meal\\MealReminder' => NotificationType.mealReminder, _ => NotificationType.unknown, }; } DateTime parseDate(String date) => DateTime.parse(date).toLocal();