// ignore_for_file: sort_constructors_first import 'package:flutter/foundation.dart'; import 'package:relationship_saver/features/ai_digest/domain/ai_digest_models.dart'; import 'package:relationship_saver/features/dashboard/domain/dashboard_models.dart'; import 'package:relationship_saver/features/ideas/domain/idea_models.dart'; import 'package:relationship_saver/features/moments/domain/moment_models.dart'; import 'package:relationship_saver/features/people/domain/person_models.dart'; import 'package:relationship_saver/features/reminders/domain/reminder_models.dart'; import 'package:relationship_saver/features/share_intake/domain/share_models.dart'; /// Aggregate local snapshot used by the prototype app store. /// /// During this prototyping phase the app still uses one persisted snapshot for /// most product state. The types inside it are now feature-owned, so each slice /// can evolve without hiding its models in a horizontal "local" module. @immutable class LocalDataState { const LocalDataState({ required this.people, required this.moments, required this.ideas, required this.reminders, required this.tasks, this.dismissedSignalIds = const [], this.sourceLinks = const [], this.sharedMessages = const [], this.sharedInbox = const [], this.personFacts = const [], this.importantDates = const [], this.preferenceSignals = const [], this.aiSuggestionDrafts = const [], }); final List people; final List moments; final List ideas; final List reminders; final List tasks; final List dismissedSignalIds; final List sourceLinks; final List sharedMessages; final List sharedInbox; final List personFacts; final List importantDates; final List preferenceSignals; final List aiSuggestionDrafts; LocalDataState copyWith({ List? people, List? moments, List? ideas, List? reminders, List? tasks, List? dismissedSignalIds, List? sourceLinks, List? sharedMessages, List? sharedInbox, List? personFacts, List? importantDates, List? preferenceSignals, List? aiSuggestionDrafts, }) { return LocalDataState( people: people ?? this.people, moments: moments ?? this.moments, ideas: ideas ?? this.ideas, reminders: reminders ?? this.reminders, tasks: tasks ?? this.tasks, dismissedSignalIds: dismissedSignalIds ?? this.dismissedSignalIds, sourceLinks: sourceLinks ?? this.sourceLinks, sharedMessages: sharedMessages ?? this.sharedMessages, sharedInbox: sharedInbox ?? this.sharedInbox, personFacts: personFacts ?? this.personFacts, importantDates: importantDates ?? this.importantDates, preferenceSignals: preferenceSignals ?? this.preferenceSignals, aiSuggestionDrafts: aiSuggestionDrafts ?? this.aiSuggestionDrafts, ); } DashboardSummary summary({DateTime? now}) { final DateTime baseline = now ?? DateTime.now(); return DashboardSummary( activePeople: people.length, upcomingPlans: people .where((PersonProfile p) => p.nextMoment.isAfter(baseline)) .length, pendingIdeas: ideas .where((RelationshipIdea idea) => !idea.isArchived) .length, weeklyConsistency: moments.isEmpty ? 0 : (70 + moments.length * 4).clamp(0, 100), ); } Map toJson() { return { 'people': people .map((PersonProfile person) => person.toJson()) .toList(growable: false), 'moments': moments .map((RelationshipMoment moment) => moment.toJson()) .toList(growable: false), 'ideas': ideas .map((RelationshipIdea idea) => idea.toJson()) .toList(growable: false), 'reminders': reminders .map((ReminderRule reminder) => reminder.toJson()) .toList(growable: false), 'tasks': tasks .map((DashboardTask task) => task.toJson()) .toList(growable: false), 'dismissedSignalIds': dismissedSignalIds, 'sourceLinks': sourceLinks .map((SourceProfileLink link) => link.toJson()) .toList(growable: false), 'sharedMessages': sharedMessages .map((SharedMessageEntry entry) => entry.toJson()) .toList(growable: false), 'sharedInbox': sharedInbox .map((SharedInboxEntry entry) => entry.toJson()) .toList(growable: false), 'personFacts': personFacts .map((PersonFact fact) => fact.toJson()) .toList(growable: false), 'importantDates': importantDates .map((PersonImportantDate value) => value.toJson()) .toList(growable: false), 'preferenceSignals': preferenceSignals .map((PersonPreferenceSignal signal) => signal.toJson()) .toList(growable: false), 'aiSuggestionDrafts': aiSuggestionDrafts .map((AiSuggestionDraft draft) => draft.toJson()) .toList(growable: false), }; } factory LocalDataState.fromJson(Map json) { return LocalDataState( people: (json['people'] as List? ?? []) .map( (dynamic person) => PersonProfile.fromJson(person as Map), ) .toList(growable: false), moments: (json['moments'] as List? ?? []) .map( (dynamic moment) => RelationshipMoment.fromJson(moment as Map), ) .toList(growable: false), ideas: (json['ideas'] as List? ?? []) .map( (dynamic idea) => RelationshipIdea.fromJson(idea as Map), ) .toList(growable: false), reminders: (json['reminders'] as List? ?? []) .map( (dynamic reminder) => ReminderRule.fromJson(reminder as Map), ) .toList(growable: false), tasks: (json['tasks'] as List? ?? []) .map( (dynamic task) => DashboardTask.fromJson(task as Map), ) .toList(growable: false), dismissedSignalIds: (json['dismissedSignalIds'] as List? ?? []) .map((dynamic value) => '$value') .toList(growable: false), sourceLinks: (json['sourceLinks'] as List? ?? []) .map( (dynamic link) => SourceProfileLink.fromJson(link as Map), ) .toList(growable: false), sharedMessages: (json['sharedMessages'] as List? ?? []) .map( (dynamic entry) => SharedMessageEntry.fromJson(entry as Map), ) .toList(growable: false), sharedInbox: (json['sharedInbox'] as List? ?? []) .map( (dynamic entry) => SharedInboxEntry.fromJson(entry as Map), ) .toList(growable: false), personFacts: (json['personFacts'] as List? ?? []) .map( (dynamic fact) => PersonFact.fromJson(fact as Map), ) .toList(growable: false), importantDates: (json['importantDates'] as List? ?? []) .map( (dynamic value) => PersonImportantDate.fromJson(value as Map), ) .toList(growable: false), preferenceSignals: (json['preferenceSignals'] as List? ?? []) .map( (dynamic signal) => PersonPreferenceSignal.fromJson( signal as Map, ), ) .toList(growable: false), aiSuggestionDrafts: (json['aiSuggestionDrafts'] as List? ?? []) .map( (dynamic draft) => AiSuggestionDraft.fromJson(draft as Map), ) .toList(growable: false), ); } static LocalDataState empty() { return const LocalDataState( people: [], moments: [], ideas: [], reminders: [], tasks: [], ); } static LocalDataState seed() => empty(); }