import Foundation import Combine import CoreData @MainActor class JournalViewModel: ObservableObject { @Published var snapshotNotes: [Snapshot] = [] @Published var monthlyNotes: [MonthlyNoteItem] = [] private let snapshotRepository: SnapshotRepository private var cancellables = Set() init(snapshotRepository: SnapshotRepository? = nil) { self.snapshotRepository = snapshotRepository ?? SnapshotRepository() setupObservers() refresh() } private func setupObservers() { NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange) .debounce(for: .milliseconds(300), scheduler: DispatchQueue.main) .sink { [weak self] _ in self?.refresh() } .store(in: &cancellables) } func refresh() { snapshotNotes = snapshotRepository.fetchAllSnapshots() .sorted { $0.date > $1.date } let snapshotMonths = Set(snapshotNotes.map { $0.date.startOfMonth }) let noteMonths = Set(MonthlyCheckInStore.allNotes().map { $0.date.startOfMonth }) let allMonths = snapshotMonths.union(noteMonths) monthlyNotes = allMonths .sorted(by: >) .map { date -> MonthlyNoteItem in let entry = MonthlyCheckInStore.entry(for: date) return MonthlyNoteItem( date: date, note: entry?.note ?? "", rating: entry?.rating, mood: entry?.mood ) } } } struct MonthlyNoteItem: Identifiable, Equatable { var id: Date { date } let date: Date let note: String let rating: Int? let mood: MonthlyCheckInMood? }