//
//  ContentModeViewModel.swift
//  Feels (iOS)
//
//  Created by Trey Tartt on 1/20/22.
//

import SwiftUI
import CoreData

class DayViewViewModel: ObservableObject {
    @Published var grouped = [Int: [Int: [MoodEntry]]]()
    @Published var numberOfItems = 0
    
    let addMonthStartWeekdayPadding: Bool
    
    var hasNoData: Bool {
        grouped.isEmpty
    }
    
    private var numberOfEntries: Int {
        var num = 0
        grouped.keys.forEach({
            let year = grouped[$0]
            let monthKeys = year?.keys
            monthKeys?.forEach({
                num += year![$0]!.count
            })
        })
        return num
        
//        grouped.keys.map{
//            grouped[$0]!.values.reduce(0) { sum, array in
//                sum + array.count
//            }
//        }.reduce(0, +)
    }
    
    init(addMonthStartWeekdayPadding: Bool) {
        self.addMonthStartWeekdayPadding = addMonthStartWeekdayPadding
        
        PersistenceController.shared.switchContainerListeners.append {
            self.getGroupedData(addMonthStartWeekdayPadding: self.addMonthStartWeekdayPadding)
        }

        PersistenceController.shared.addNewDataListener {
            withAnimation{
                self.updateData()
            }
        }
        updateData()
    }
    
    private func getGroupedData(addMonthStartWeekdayPadding: Bool) {
        var newStuff = PersistenceController.shared.splitIntoYearMonth(includedDays: [1,2,3,4,5,6,7])
        if addMonthStartWeekdayPadding {
            newStuff = MoodEntryFunctions.padMoodEntriesForCalendar(entries: newStuff)
        }
        grouped = newStuff
        numberOfItems = numberOfEntries
    }

    public func updateData() {
        getGroupedData(addMonthStartWeekdayPadding: self.addMonthStartWeekdayPadding)
    }
    
    public func add(mood: Mood, forDate date: Date, entryType: EntryType) {
        PersistenceController.shared.add(mood: mood, forDate: date, entryType: entryType)
    }
    
    public func update(entry: MoodEntry, toMood mood: Mood) {
        if !PersistenceController.shared.update(entryDate: entry.forDate!, withModd: mood) {
            #warning("show error")
        }
    }
    
    public func delete(offsets: IndexSet, inMonth month: Int, inYear year: Int) {
        if let monthEntries = grouped[year],
           let entries = monthEntries[month] {
            var mutableEntries = entries.sorted(by: {
                $0.forDate! > $1.forDate!
            })
            var entriesToDelete = [MoodEntry]()
            for idx in offsets {
                let obj = mutableEntries.remove(at: idx)
                entriesToDelete.append(obj)
            }
            entriesToDelete.forEach({ entry in
                let entryDate = entry.forDate!
                PersistenceController.shared.viewContext.delete(entry)
                self.add(mood: .missing, forDate: entryDate, entryType: .listView)
            })
        }
        
        do {
            try PersistenceController.shared.viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
    }
    
    static func updateTitleHeader(forEntry entry: MoodEntry?) -> String {
        guard let entry = entry else {
            return ""
        }
        
        guard let forDate = entry.forDate else {
            return ""
        }
        
        let components = Calendar.current.dateComponents([.day, .month, .year], from: forDate)
        //        let day = components.day!
        let month = components.month!
        let year = components.year!
        
        let monthName = Random.monthName(fromMonthInt: month)
        let weekday = Random.weekdayName(fromDate:entry.forDate!)
        let dayz = Random.dayFormat(fromDate:entry.forDate!)
        
        let string = weekday + " " + monthName + " " + dayz + " " + String(year)
        
        return String(format: String(localized: "content_view_fill_in_missing_entry"), string)
    }
}
