//
//  MoodEntryFunctions.swift
//  Reflect (iOS)
//
//  Created by Trey Tartt on 2/19/22.
//

import Foundation

@MainActor
class MoodEntryFunctions {
    static func padMoodEntriesForCalendar(entries grouped: [Int: [Int: [MoodEntryModel]]]) -> [Int: [Int: [MoodEntryModel]]] {
        var newGrouped = [Int: [Int: [MoodEntryModel]]]()

        let allYears = grouped.keys.sorted(by: > )
        for year in allYears {
            var newMonth = [Int: [MoodEntryModel]]()

            let oldMonths = grouped[year]!
            let monthKeys = oldMonths.keys.sorted(by: > )
            for key in monthKeys {
                if let entries = oldMonths[key] {
                    newMonth[key] = MoodEntryFunctions.padMoodEntriesMonth(monthEntries: entries)
                }
                newGrouped[year] = newMonth
            }
        }
        return newGrouped
    }

    static func padMoodEntriesMonth(monthEntries entries: [MoodEntryModel]) -> [MoodEntryModel] {
        let sortedEntries = entries.sorted(by: { $0.forDate < $1.forDate })
        var mutableEntries = sortedEntries

        if let firstDate = sortedEntries.first {
            let date = firstDate.forDate

            // if the first entry for a month is in the middle of the month we
            // need to add in the missing entries, as placeholders, to the beignning to get
            // the entries on the right day. think user downloads in the middle of the month
            // and entry is on the 13th ... this needs to show on the 13th entry spot
            var startOfMonth = date.startOfMonth
            startOfMonth = Calendar.current.date(byAdding: .hour, value: 9, to: startOfMonth)!
            let lastMissingDate = mutableEntries.first?.forDate ?? date.endOfMonth
            var missingDates = Date.dates(from: startOfMonth, toDate: lastMissingDate, includingToDate: true)
            missingDates = missingDates.dropLast()

            for date in missingDates {
                mutableEntries.insert(DataController.shared.generateObjectNotInArray(forDate: date, withMood: .placeholder), at: 0)
            }

            mutableEntries = mutableEntries.sorted(by: {
                $0.forDate < $1.forDate
            })

            // fill in calendar day offset .. if month starts on wed we need to
            // pad the beginning sun, mon, tues
            if let firstDate = mutableEntries.first?.forDate {
                let weekday = Int16(Calendar.current.component(.weekday, from: firstDate))
                for _ in 1..<weekday {
                    mutableEntries.insert(DataController.shared.generateObjectNotInArray(withMood: .placeholder), at: 0)
                }
            }
        }
        return mutableEntries
    }
}
