//
//  ShowBasedOnVoteLogics.swift
//  Feels (iOS)
//
//  Created by Trey Tartt on 2/17/22.
//

import CoreData
import SwiftUI


/*
         current day 3/5/22

         day option = .today
         -------
         voting for 3/4     |  voting for 3/5
         ------------------------*-------------------------
         db should contain 3/3   | db should contain 3/4
         
 ----------------------------------------------------------------------------
         
         day option = .yesterday
        --------
         voting for 3/3     |  voting for 3/4
         ------------------------*-------------------------
         db should contain 3/2   | db should contain 3/3
 
 */
class ShowBasedOnVoteLogics {
    static func returnCurrentVoteStatus(onboardingData: OnboardingData) -> (Bool, DayOptions) {
        let passedTimeToVote = ShowBasedOnVoteLogics.ableToVoteBasedOnCurentTime(voteDate: onboardingData.date)
        let inputDay: DayOptions = onboardingData.inputDay
        
        return (passedTimeToVote, inputDay)
    }
    
    static func isMissingCurrentVote(onboardingData: OnboardingData) -> Bool {
        var startDate: Date?

        switch ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData) {
        case (false, .Today):
            // if we're NOT passed time to vote and the voting type is previous - last vote should be -1
            startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
        case (true, .Today):
            // if we're passed time to vote and the voting type is today - last vote should be current date
            startDate = Date()
            
        case (false, .Previous):
            // if we're NOT passed time to vote and the voting type is previous - last vote should be 2 days ago
            startDate = Calendar.current.date(byAdding: .day, value: -2, to: Date())!
        case (true, .Previous):
            // if we're passed time to vote and the voting type is previous - last vote should be -1
            startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
        }
        
        startDate = Calendar.current.startOfDay(for: startDate!)
        let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate!)!

        let fetchRequest = NSFetchRequest<MoodEntry>(entityName: "MoodEntry")
        let fromPredicate = NSPredicate(format: "%@ <= %K", startDate!
                                        as NSDate, #keyPath(MoodEntry.forDate))
        let toPredicate = NSPredicate(format: "%K < %@", #keyPath(MoodEntry.forDate), endDate as NSDate)
        let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])
        fetchRequest.predicate = datePredicate
        let entries = try! PersistenceController.shared.viewContext.count(for: fetchRequest)
        
        return entries < 1
    }
    
    static func getVotingTitle(onboardingData: OnboardingData) -> String {
        switch ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData) {
        case (false, .Today):
            return String(localized: "add_mood_header_view_title_yesterday")
        case (true, .Today):
            return String(localized: "add_mood_header_view_title_today")
            
        case (false, .Previous):
            let date = Calendar.current.date(byAdding: .day, value: -2, to: Date())!
            return String(format: String(localized: "add_mood_header_view_title"), Random.weekdayName(fromDate: date))
        case (true, .Previous):
            return String(localized: "add_mood_header_view_title_yesterday")
        }
    }
    
    static func dateForHeaderVote(onboardingData: OnboardingData) -> Date? {
        var date: Date?
        
        switch ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData) {
        case (false, .Today):
            // if we're passed time to vote and the voting type is previous - last vote should be -1
            date = Calendar.current.date(byAdding: .day, value: -1, to: Date())
        case (true, .Today):
            // if we're passed time to vote and the voting type is previous - last vote should be today
            date = Date()
            
        case (false, .Previous):
            // if we're passed time to vote and the voting type is previous - last vote should be -2
            date = Calendar.current.date(byAdding: .day, value: -2, to: Date())
        case (true, .Previous):
            // if we're passed time to vote and the voting type is previous - last vote should be -1
            date = Calendar.current.date(byAdding: .day, value: -1, to: Date())
        }

        if let date = date {
            return date
        }
        
        return nil
    }
    
    static func getLastDateVoteShouldExist(onboardingData: OnboardingData) -> Date {
        var date: Date?
        
        switch ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData) {
        case (false, .Today):
            // if we're passed time to vote and the voting type is previous - last vote should be -2
            date = Calendar.current.date(byAdding: .day, value: -2, to: Date())!
        case (true, .Today):
            // if we're passed time to vote and the voting type is previous - last vote should be -1
            date = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
            
        case (false, .Previous):
            // if we're passed time to vote and the voting type is previous - last vote should be -3
            date = Calendar.current.date(byAdding: .day, value: -3, to: Date())!
        case (true, .Previous):
            // if we're passed time to vote and the voting type is previous - last vote should -2
            date = Calendar.current.date(byAdding: .day, value: -2, to: Date())!
        }
        
        return date!
    }
    
    static func ableToVoteBasedOnCurentTime(voteDate: Date) -> Bool {
        let currentDateComp = Calendar.current.dateComponents([.hour, .minute], from: Date())
        let savedDateComp = Calendar.current.dateComponents([.hour, .minute], from: voteDate)

        if let currentHour = currentDateComp.hour,
           let currentMin = currentDateComp.minute,
           let savedHour = savedDateComp.hour,
           let savedMin = savedDateComp.minute {
            
            if currentHour > savedHour {
                return true
            }
            
            if currentHour == savedHour {
                return currentMin >= savedMin
            }
        }
        
        return false
    }
}
