//
//  PersistenceGET.swift
//  Feels
//
//  Created by Trey Tartt on 2/17/22.
//

import CoreData

extension PersistenceController {
    public func getEntry(byDate date: Date) -> MoodEntry? {
        let startDate = Calendar.current.startOfDay(for: date)
        let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate)!
        
        let predicate = NSPredicate(format: "forDate >= %@ && forDate <= %@ ",
                                    startDate as NSDate,
                                    endDate as NSDate)
        
        let fetchRequest = NSFetchRequest<MoodEntry>(entityName: "MoodEntry")
        fetchRequest.predicate = predicate
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "forDate", ascending: true)]
        let data = try! viewContext.fetch(fetchRequest)
        return data.first
    }
    
    public func getData(startDate: Date, endDate: Date, includedDays: [Int]) -> [MoodEntry] {
        try! viewContext.setQueryGenerationFrom(.current)
        viewContext.refreshAllObjects()
        
        var includedDays16 = [Int16]()
        
        if includedDays.isEmpty {
            includedDays16 = [Int16(1), Int16(2), Int16(3), Int16(4), Int16(5), Int16(6), Int16(7)]
        } else {
            includedDays16 = includedDays.map({
                Int16($0)
            })
        }
        let predicate = NSPredicate(format: "forDate >= %@ && forDate <= %@ && weekDay IN %@",
                                    startDate as NSDate,
                                    endDate as NSDate,
                                    includedDays16)
        
        let fetchRequest = NSFetchRequest<MoodEntry>(entityName: "MoodEntry")
        fetchRequest.predicate = predicate
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "forDate", ascending: true)]
        let data = try! viewContext.fetch(fetchRequest)
        return data
    }
    
    public func splitIntoYearMonth() ->  [Int: [Int: [MoodEntry]]] {
        let data = PersistenceController.shared.getData(startDate: Date(timeIntervalSince1970: 0),
                                                        endDate: Date(),
                                                        includedDays: [1,2,3,4,5,6,7]).sorted(by: {
            $0.forDate! < $1.forDate!
        })
        var returnData = [Int: [Int: [MoodEntry]]]()
        
        if let earliestEntry = data.first,
           let lastEntry = data.last {
            
            let calendar = Calendar.current
            let components = calendar.dateComponents([.year], from: earliestEntry.forDate!)
            let earliestYear = components.year!
            
            let latestComponents = calendar.dateComponents([.year], from: lastEntry.forDate!)
            let latestYear = latestComponents.year!
            
            for year in earliestYear...latestYear {
                var allMonths = [Int: [MoodEntry]]()
                
                for month in (1...12) {
                    var components = DateComponents()
                    components.month = month
                    components.year = year
                    let startDateOfMonth = Calendar.current.date(from: components)!
                    
                    let items = data.filter({ entry in
                        let components = calendar.dateComponents([.month, .year], from: startDateOfMonth)
                        let entryComponents = calendar.dateComponents([.month, .year], from: entry.forDate!)
                        return (components.month == entryComponents.month && components.year == entryComponents.year)
                    })
                    if !items.isEmpty {
                        allMonths[month] = items
                    }
                }
                returnData[year] = allMonths
            }
        }
        return returnData
    }
}
