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<AnyCancellable>()

    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?
}
