//
//  MoodTintable.swift
//  Feels (iOS)
//
//  Created by Trey Tartt on 2/19/22.
//

import SwiftUI

struct DefaultTextColor {
    static var textColor: Color {
        Color(UIColor.label)
    }
}

protocol MoodTintable {
    static func color(forMood mood: Mood) -> Color
    static func secondary(forMood mood: Mood) -> Color
}

enum MoodTints: Int, CaseIterable {
    case Default
    case Neon
    case Pastel
    case Custom
    
    static var defaultOptions: [MoodTints] {
        return [Default, Neon, Pastel]
    }
    
    func color(forMood mood: Mood) -> Color {
        switch self {
        case .Default:
            return DefaultMoodTint.color(forMood: mood)
        case .Custom:
            return CustomMoodTint.color(forMood: mood)
        case .Neon:
            return NeonMoodTint.color(forMood: mood)
        case .Pastel:
            return PastelTint.color(forMood: mood)
        }
    }
    
    func secondary(forMood mood: Mood) -> Color {
        switch self {
        case .Default:
            return DefaultMoodTint.secondary(forMood: mood)
        case .Custom:
            return CustomMoodTint.secondary(forMood: mood)
        case .Neon:
            return NeonMoodTint.secondary(forMood: mood)
        case .Pastel:
            return PastelTint.secondary(forMood: mood)
        }
    }
    
    var moodTints: MoodTintable.Type {
        switch self {
        case .Default:
            return DefaultMoodTint.self
        case .Custom:
            return CustomMoodTint.self
        case .Neon:
            return NeonMoodTint.self
        case .Pastel:
            return PastelTint.self
        }
    }
}

final class SavedMoodTint: NSObject, ObservableObject, Codable {
    @Published var colorOne: Color
    @Published var colorTwo: Color
    @Published var colorThree: Color
    @Published var colorFour: Color
    @Published var colorFive: Color
    
    override init() {
        colorOne = Color(hex: "a92b26")
        colorTwo = Color(hex: "a92b26")
        colorThree = Color(hex: "a92b26")
        colorFour = Color(hex: "a92b26")
        colorFive = Color(hex: "a92b26")
    }
    
    enum CodingKeys: CodingKey {
        case colorOne, colorTwo, colorThree, colorFour, colorFive
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        colorOne = try container.decode(Color.self, forKey: .colorOne)
        colorTwo = try container.decode(Color.self, forKey: .colorTwo)
        colorThree = try container.decode(Color.self, forKey: .colorThree)
        colorFour = try container.decode(Color.self, forKey: .colorFour)
        colorFive = try container.decode(Color.self, forKey: .colorFive)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(colorOne, forKey: .colorOne)
        try container.encode(colorTwo, forKey: .colorTwo)
        try container.encode(colorThree, forKey: .colorThree)
        try container.encode(colorFour, forKey: .colorFour)
        try container.encode(colorFive, forKey: .colorFive)
    }
}

final class CustomMoodTint: MoodTintable  {
    static func color(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return UserDefaultsStore.getCustomMoodTint().colorFive
        case .bad:
            return UserDefaultsStore.getCustomMoodTint().colorFour
        case .average:
            return  UserDefaultsStore.getCustomMoodTint().colorThree
        case .good:
            return UserDefaultsStore.getCustomMoodTint().colorTwo
        case .great:
            return UserDefaultsStore.getCustomMoodTint().colorOne
        case .missing:
            return Color(uiColor: UIColor.lightGray)
        case .placeholder:
            return Color(uiColor: UIColor.lightGray)
        }
    }
    
    static func secondary(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return UserDefaultsStore.getCustomMoodTint().colorFive.darker(by: 40)
        case .bad:
            return UserDefaultsStore.getCustomMoodTint().colorFour.darker(by: 40)
        case .average:
            return  UserDefaultsStore.getCustomMoodTint().colorThree.darker(by: 40)
        case .good:
            return UserDefaultsStore.getCustomMoodTint().colorTwo.darker(by: 40)
        case .great:
            return UserDefaultsStore.getCustomMoodTint().colorOne.darker(by: 40)
        case .missing:
            return Color(uiColor: UIColor.lightGray).darker(by: 40)
        case .placeholder:
            return Color(uiColor: UIColor.lightGray).darker(by: 40)
        }
    }
}

final class DefaultMoodTint: MoodTintable {
    static func color(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return Color(hex: "ff453a")
        case .bad:
            return Color(hex: "ff9e0b")
        case .average:
            return  Color(hex: "0b84ff")
        case .good:
            return Color(hex: "ffd709")
        case .great:
            return Color(hex: "31d158")
        case .missing:
            return Color(uiColor: UIColor.lightGray)
        case .placeholder:
            return Color(uiColor: UIColor.lightGray)
        }
    }
    
    static func secondary(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return Color(hex: "a92b26")
        case .bad:
            return Color(hex: "a06407")
        case .average:
            return Color(hex: "074f9a")
        case .good:
            return Color(hex: "9d8405")
        case .great:
            return Color(hex: "208939")
        case .missing:
            return Color(uiColor: UIColor.lightGray)
        case .placeholder:
            return Color(uiColor: UIColor.lightGray)
        }
    }
}

final class AllRedMoodTint: MoodTintable {
    static func color(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return .red
        case .bad:
            return .red
        case .average:
            return .red
        case .good:
            return .red
        case .great:
            return .red
        case .missing:
            return Color(uiColor: UIColor.systemGray2)
        case .placeholder:
            return Color(uiColor: UIColor.systemGray2)
        }
    }
    
    static func secondary(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return .red
        case .bad:
            return .red
        case .average:
            return .red
        case .good:
            return .red
        case .great:
            return .red
        case .missing:
            return Color(uiColor: UIColor.label)
        case .placeholder:
            return Color(uiColor: UIColor.label)
        }
    }
}

final class NeonMoodTint: MoodTintable {
    static func color(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return Color(hex: "#ff1818")
        case .bad:
            return Color(hex: "#FF5F1F")
        case .average:
            return Color(hex: "#1F51FF")
        case .good:
            return Color(hex: "#FFF01F")
        case .great:
            return Color(hex: "#39FF14")
        case .missing:
            return Color(uiColor: UIColor.systemGray2)
        case .placeholder:
            return Color(uiColor: UIColor.systemGray2)
        }
    }
    
    static func secondary(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return Color(hex: "#8b1113")
        case .bad:
            return Color(hex: "#893315")
        case .average:
            return Color(hex: "#0f2a85")
        case .good:
            return Color(hex: "#807a18")
        case .great:
            return Color(hex: "#218116")
        case .missing:
            return Color(uiColor: UIColor.label)
        case .placeholder:
            return Color(uiColor: UIColor.label)
        }
    }
}

final class MonoChromeTint: MoodTintable {
    static func color(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return Color(hex: "#000000")
        case .bad:
            return Color(hex: "#47474a")
        case .average:
            return Color(hex: "#7b7b81")
        case .good:
            return Color(hex: "#a3a3ab")
        case .great:
            return Color(hex: "#c2c1cb")
        case .missing:
            return Color(hex: "#ff0000")
        case .placeholder:
            return Color(hex: "#efeffb")
        }
    }
    
    static func secondary(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return .black
        case .bad:
            return Color(uiColor: UIColor.systemGray)
        case .average:
            return Color(uiColor: UIColor.systemGray)
        case .good:
            return Color(uiColor: UIColor.systemGray2)
        case .great:
            return Color(uiColor: UIColor.systemGray3)
        case .missing:
            return Color(uiColor: UIColor.systemGray2)
        case .placeholder:
            return Color(uiColor: UIColor.systemGray4)
        }
    }
}

final class PastelTint: MoodTintable {
    static func color(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return Color(hex: "#FF6961")
        case .bad:
            return Color(hex: "#ffb347")
        case .average:
            return Color(hex: "#A7C7E7")
        case .good:
            return Color(hex: "#fdfd96")
        case .great:
            return Color(hex: "#C1E1C1")
        case .missing:
            return Color(uiColor: UIColor.systemGray2)
        case .placeholder:
            return Color(uiColor: UIColor.systemGray4)
        }
    }
    
    static func secondary(forMood mood: Mood) -> Color {
        switch mood {
        case .horrible:
            return Color(hex: "#893734")
        case .bad:
            return Color(hex: "#855d28")
        case .average:
            return Color(hex: "#5d6e83")
        case .good:
            return Color(hex: "#7f804f")
        case .great:
            return Color(hex: "#6b7e6d")
        case .missing:
            return Color(uiColor: UIColor.systemGray2)
        case .placeholder:
            return Color(uiColor: UIColor.systemGray4)
        }
    }
}
