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

import SwiftUI
import SwiftData


/*
         current day 3/5/22

        ..... before time | after time .....

         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

 */
@MainActor
class ShowBasedOnVoteLogics {
    static private func returnCurrentVoteStatus(onboardingData: OnboardingData, now: Date = Date()) -> (passedTimeToVote: Bool, inputDay: DayOptions) {
        let passedTimeToVote = ShowBasedOnVoteLogics.passedTodaysVotingUnlock(voteDate: onboardingData.date, now: now)
        let inputDay: DayOptions = onboardingData.inputDay

        return (passedTimeToVote, inputDay)
    }

    static public func passedTodaysVotingUnlock(voteDate: Date, now: Date = Date()) -> Bool {
        let currentDateComp = Calendar.current.dateComponents([.hour, .minute], from: now)
        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
    }

    static public func isMissingCurrentVote(onboardingData: OnboardingData, now: Date = Date()) -> Bool {
        let startDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: onboardingData, now: now).startOfDay
        #if WIDGET_EXTENSION
        let entry = WidgetDataProvider.shared.getEntry(byDate: startDate)
        #else
        let entry = DataController.shared.getEntry(byDate: startDate)
        #endif
        return entry == nil || entry?.mood == .missing
    }

    static public func getCurrentVotingDate(onboardingData: OnboardingData, now: Date = Date()) -> Date {
        var date: Date?
        let currentVoteStatus = ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData, now: now)
        // note to future self, this should account for midnight until next voting unlock
        // the vote at 12:03 am will not be passed time, and will be for yesterday
        switch (currentVoteStatus.passedTimeToVote, currentVoteStatus.inputDay) {
        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: now)
        case (true, .Today):
            // if we're passed time to vote and the voting type is previous - last vote should be today
            date = now

        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: now)
        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: now)
        }

        return date ?? now
    }

    static public func getVotingTitle(onboardingData: OnboardingData, now: Date = Date()) -> String {
        let currentVoteStatus = ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData, now: now)
        switch (currentVoteStatus.passedTimeToVote, currentVoteStatus.inputDay) {
        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: now) ?? now
            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")
        }
    }
}
