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

import CoreData

extension PersistenceController {
    public func fixWrongWeekdays() {
        let data = PersistenceController.shared.getData(startDate: Date(timeIntervalSince1970: 0),
                                                        endDate: Date(),
                                                        includedDays: []).sorted(by: {
            $0.forDate! < $1.forDate!
        })
        
        data.forEach({
            $0.weekDay = Int16(Calendar.current.component(.weekday, from: $0.forDate!))
        })
        try? viewContext.save()
    }
    
    public func add(mood: Mood, forDate date: Date, entryType: EntryType) {
        if let existingEntry = getEntry(byDate: date) {
            viewContext.delete(existingEntry)
            try? viewContext.save()
        }
        
        let newItem = MoodEntry(context: viewContext)
        newItem.timestamp = Date()
        newItem.moodValue = Int16(mood.rawValue)
        newItem.forDate = date
        newItem.weekDay = Int16(Calendar.current.component(.weekday, from: date))
        newItem.canEdit = true
        newItem.canDelete = true
        newItem.entryType = Int16(entryType.rawValue)
        
        EventLogger.log(event: "add_entry", withData: ["entry_type": entryType.rawValue])
        
        saveAndRunDataListerners()
    }
    
    func fillInMissingDates() {
        let currentOnboarding = UserDefaultsStore.getOnboarding()
        var endDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: currentOnboarding)
        // since its for views take away the last date so vote is enabled
        endDate = Calendar.current.date(byAdding: .day, value: -1, to: endDate)!
        
        let fetchRequest = NSFetchRequest<MoodEntry>(entityName: "MoodEntry")
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "forDate", ascending: false)]
        let entries = try! viewContext.fetch(fetchRequest)
        
        if let firstEntry = entries.last?.forDate {
            let allDates: [Date] = Date.dates(from: firstEntry, toDate: endDate, includingToDate: true).map({
                let zeroDate = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: $0)!
                return zeroDate
            })
                    
            let existingEntries: [Date] = entries.compactMap({
                if let date = $0.forDate {
                    let zeroDate = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: date)!
                    return zeroDate
                }
                return nil
            })
            
            let allDatesSet = Set(allDates)
            let existingEntriesSet = Set(existingEntries)
            let missing = Array(allDatesSet.subtracting(existingEntriesSet)).sorted(by: >)
            for date in missing {
                // add 12 hours, if you enter a things right at 12:00.00 it wont show .... mabye
                // due to utc offset?
                let adjustedDate = Calendar.current.date(byAdding: .hour, value: 12, to: date)!
                add(mood: .missing, forDate: adjustedDate, entryType: .filledInMissing)
            }
            
            if !missing.isEmpty {
                EventLogger.log(event: "filled_in_missing_entries", withData: ["count": missing.count])
            }
        }
    }
    
    func removeNoForDates() {
        let fetchRequest = NSFetchRequest<MoodEntry>(entityName: "MoodEntry")
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "forDate", ascending: false)]
        let entries = try! viewContext.fetch(fetchRequest)
        
        for entry in entries {
            guard let _ = entry.forDate else {
                viewContext.delete(entry)
                try? viewContext.save()
                return
            }
        }
        EventLogger.log(event: "removed_entry_no_for_date", withData: ["count": entries.count])
    }
}
