//
//  CustomIcon.swift
//  Reflect (iOS)
//
//  Created by Trey Tartt on 2/13/22.
//

import SwiftUI

class CustomWidgetModel: ObservableObject, Codable, NSCopying {
    static let numberOfBGItems = 109

    static var randomWidget: CustomWidgetModel {
        return CustomWidgetModel(leftEye: CustomWidgeImageOptions.defaultOption,
                                 rightEye: CustomWidgeImageOptions.defaultOption,
                                 mouth: CustomWidgeImageOptions.defaultOption,
                                 background: CustomWidgetBackGroundOptions.defaultOption,
                                 bgColor: Color.random(),
                                 innerColor: Color.random(),
                                 bgOverlayColor: Color.random(),
                                 rightEyeColor: Color.random(),
                                 leftEyeColor: Color.random(),
                                 mouthColor: Color.random(),
                                 circleStrokeColor: Color.random(),
                                 inUse: true,
                                 uuid: UUID().uuidString,
                                 isSaved: false,
                                 createdDate: Date())
    }
    
    init(leftEye: CustomWidgeImageOptions,
         rightEye: CustomWidgeImageOptions,
         mouth: CustomWidgeImageOptions,
         background: CustomWidgetBackGroundOptions,
         bgColor: Color,
         innerColor: Color,
         bgOverlayColor: Color,
         rightEyeColor: Color,
         leftEyeColor: Color,
         mouthColor: Color,
         circleStrokeColor: Color,
         inUse: Bool,
         uuid: String,
         isSaved: Bool,
         createdDate: Date) {
        self.leftEye = leftEye
        self.rightEye = rightEye
        self.mouth = mouth
        self.background = background
        self.bgColor = bgColor
        self.innerColor = innerColor
        self.bgOverlayColor = bgOverlayColor
        self.rightEyeColor = rightEyeColor
        self.leftEyeColor = leftEyeColor
        self.mouthColor = mouthColor
        self.circleStrokeColor = circleStrokeColor
        self.inUse = inUse
        self.uuid = uuid
        self.isSaved = isSaved
        self.createdDate = createdDate
    }
    
    @Published var leftEye: CustomWidgeImageOptions
    @Published var rightEye: CustomWidgeImageOptions
    @Published var mouth: CustomWidgeImageOptions
    
    @Published var background: CustomWidgetBackGroundOptions
    @Published var bgColor: Color
    @Published var innerColor: Color
    @Published var bgOverlayColor: Color
    
    @Published var leftEyeColor: Color
    @Published var rightEyeColor: Color
    @Published var mouthColor: Color
    
    @Published var circleStrokeColor: Color
    @Published var inUse: Bool
    @Published var uuid: String
    @Published var isSaved: Bool
    @Published var createdDate: Date
    
    private var oldBackground: CustomWidgetBackGroundOptions?
    private var oldBackgroundImages: [(Image, String)]?
    
    public var backgroundImages : [(Image, String)] {
        if let oldBackgroundImages = oldBackgroundImages,
           oldBackground == background  {
            return oldBackgroundImages
        }
        
        oldBackground = background
        
        if background == .random {
            var blah = [(Image, String)]()
            for _ in 0...CustomWidgetModel.numberOfBGItems {
                let image = CustomWidgetBackGroundOptions.selectable.randomElement()?.image ?? CustomWidgetBackGroundOptions.defaultOption.image
                blah.append((image, UUID().uuidString))
            }
            oldBackgroundImages = blah
        } else {
            var blah = [(Image, String)]()
            for _ in 0...CustomWidgetModel.numberOfBGItems {
                blah.append((background.image, UUID().uuidString))
            }
            oldBackgroundImages = blah
        }
        return oldBackgroundImages!
    }
    
    enum CodingKeys: CodingKey {
        case leftEye, rightEye, mouth, background, bgColor, innerColor, bgOverlayColor, leftEyeColor, rightEyeColor, mouthColor, circleStrokeColor, inUse, uuid, isSaved, createdDate
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        leftEye = try container.decode(CustomWidgeImageOptions.self, forKey: .leftEye)
        rightEye = try container.decode(CustomWidgeImageOptions.self, forKey: .rightEye)
        mouth = try container.decode(CustomWidgeImageOptions.self, forKey: .mouth)
        
        background = try container.decode(CustomWidgetBackGroundOptions.self, forKey: .background)
        bgColor = try container.decode(Color.self, forKey: .bgColor)
        innerColor = try container.decode(Color.self, forKey: .innerColor)
        bgOverlayColor = try container.decode(Color.self, forKey: .bgOverlayColor)
        leftEyeColor = try container.decode(Color.self, forKey: .leftEyeColor)
        rightEyeColor = try container.decode(Color.self, forKey: .rightEyeColor)
        mouthColor = try container.decode(Color.self, forKey: .mouthColor)
        circleStrokeColor = try container.decode(Color.self, forKey: .circleStrokeColor)
        inUse = try container.decode(Bool.self, forKey: .inUse)
        uuid = try container.decode(String.self, forKey: .uuid)
        isSaved = try container.decode(Bool.self, forKey: .isSaved)
        createdDate = try container.decode(Date.self, forKey: .createdDate)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(leftEye, forKey: .leftEye)
        try container.encode(rightEye, forKey: .rightEye)
        try container.encode(mouth, forKey: .mouth)
        
        try container.encode(background, forKey: .background)
        try container.encode(bgColor, forKey: .bgColor)
        try container.encode(innerColor, forKey: .innerColor)
        try container.encode(bgOverlayColor, forKey: .bgOverlayColor)
        try container.encode(leftEyeColor, forKey: .leftEyeColor)
        try container.encode(rightEyeColor, forKey: .rightEyeColor)
        try container.encode(mouthColor, forKey: .mouthColor)
        try container.encode(circleStrokeColor, forKey: .circleStrokeColor)
        try container.encode(inUse, forKey: .inUse)
        try container.encode(uuid, forKey: .uuid)
        try container.encode(isSaved, forKey: .isSaved)
        try container.encode(createdDate, forKey: .createdDate)
    }
    
    func copy(with zone: NSZone? = nil) -> Any {
        let copy = CustomWidgetModel(leftEye: self.leftEye,
                                     rightEye: self.rightEye,
                                     mouth: self.mouth,
                                     background: self.background,
                                     bgColor: self.bgColor,
                                     innerColor: self.innerColor,
                                     bgOverlayColor: self.bgOverlayColor,
                                     rightEyeColor: self.rightEyeColor,
                                     leftEyeColor: self.leftEyeColor,
                                     mouthColor: self.mouthColor,
                                     circleStrokeColor: self.circleStrokeColor,
                                     inUse: self.inUse,
                                     uuid: self.uuid,
                                     isSaved: self.isSaved,
                                     createdDate: self.createdDate)
        return copy
    }
}

enum CustomWidgetBackGroundOptions: String, CaseIterable, Codable {
    case horrible
    case bad
    case average
    case good
    case great
    case random
    
    static var selectable: [CustomWidgetBackGroundOptions] {
        return [.great, .good, .average, .bad, .horrible]
    }
    
    static public var defaultOption: CustomWidgetBackGroundOptions {
        CustomWidgetBackGroundOptions.random
    }
    
    public var image: Image {
        return Image(self.rawValue, bundle: .main)
    }
}

enum CustomWidgetEyes: String, Codable {
    case left
    case right
}

enum CustomWidgeImageOptions: String, CaseIterable, Codable {
    case star_solid = "custom_icon/star-solid"
    case jet_fighter_solid = "custom_icon/jet-fighter-solid"
    case circle_xmark_solid = "custom_icon/circle-xmark-solid"
    case frown_regular = "custom_icon/frown-regular"
    case virus_covid_solid = "custom_icon/virus-covid-solid"
    case bullhorn_solid = "custom_icon/bullhorn-solid"
    case caret_down_solid = "custom_icon/caret-down-solid"
    case meteor_solid = "custom_icon/meteor-solid"
    case eye_solid = "custom_icon/eye-solid"
    case battery_half_solid = "custom_icon/battery-half-solid"
    case heart_crack_solid = "custom_icon/heart-crack-solid"
    case heart_solid = "custom_icon/heart-solid"
    case divide_solid = "custom_icon/divide-solid"
    case location_crosshairs_solid = "custom_icon/location-crosshairs-solid"
    case bitcoin_brands = "custom_icon/bitcoin-brands"
    case baby_solid = "custom_icon/baby-solid"
    case grin_regular = "custom_icon/grin-regular"
    case poo_storm_solid = "custom_icon/poo-storm-solid"
    case btc_brands = "custom_icon/btc-brands"
    case shuttle_space_solid = "custom_icon/shuttle-space-solid"
    case chess_king_solid = "custom_icon/chess-king-solid"
    case chess_queen_solid = "custom_icon/chess-queen-solid"
    case lightbulb_solid = "custom_icon/lightbulb-solid"
    case skull_solid = "custom_icon/skull-solid"
    case dice_one_solid = "custom_icon/dice-one-solid"
    case fan_solid = "custom_icon/fan-solid"
    case bolt_solid = "custom_icon/bolt-solid"
    case dharmachakra_solid = "custom_icon/dharmachakra-solid"
    case ban_solid = "custom_icon/ban-solid"
    case skull_crossbones_solid = "custom_icon/skull-crossbones-solid"
    case sad_tear_regular = "custom_icon/sad-tear-regular"
    case floppy_disk_solid = "custom_icon/floppy-disk-solid"
    case crosshairs_solid = "custom_icon/crosshairs-solid"
    case exclamation_solid = "custom_icon/exclamation-solid"
    case lemon_solid = "custom_icon/lemon-solid"
    case caret_right_solid = "custom_icon/caret-right-solid"
    case poo_solid = "custom_icon/poo-solid"
    case rainbow_solid = "custom_icon/rainbow-solid"
    case apple_brands = "custom_icon/apple-brands"
    case x_solid = "custom_icon/x-solid"
    case pizza_slice_solid = "custom_icon/pizza-slice-solid"
    case empire_brands = "custom_icon/empire-brands"
    case caret_up_solid = "custom_icon/caret-up-solid"
    case life_ring_solid = "custom_icon/life-ring-solid"
    case dragon_solid = "custom_icon/dragon-solid"
    case cannabis_solid = "custom_icon/cannabis-solid"
    case bullseye_solid = "custom_icon/bullseye-solid"
    case code_compare_solid = "custom_icon/code-compare-solid"
    case battery_empty_solid = "custom_icon/battery-empty-solid"
    case moon_solid = "custom_icon/moon-solid"
    case android_brands = "custom_icon/android-brands"
    case smile_beam_regular = "custom_icon/smile-beam-regular"
    case futbol_solid = "custom_icon/futbol-solid"
    case dollar_sign_solid = "custom_icon/dollar-sign-solid"
    case cross_solid = "custom_icon/cross-solid"
    case bomb_solid = "custom_icon/bomb-solid"
    case battery_full_solid = "custom_icon/battery-full-solid"
    case arrow_up_solid = "custom_icon/arrow-up-solid"
    case gem_solid = "custom_icon/gem-solid"
    case code_solid = "custom_icon/code-solid"
    case bolt_lightning_solid = "custom_icon/bolt-lightning-solid"
    case caret_left_solid = "custom_icon/caret-left-solid"
    case fort_awesome_brands = "custom_icon/fort-awesome-brands"
    case fire_solid = "custom_icon/fire-solid"
    case hotjar_brands = "custom_icon/hotjar-brands"
    case burger_solid = "custom_icon/burger-solid"
    case egg_solid = "custom_icon/egg-solid"
    case meh_regular = "custom_icon/meh-regular"
    case battery_three_quarters_solid = "custom_icon/battery-three-quarters-solid"
    case crown_solid = "custom_icon/crown-solid"
    case clock_solid = "custom_icon/clock-solid"
    case battery_quarter_solid = "custom_icon/battery-quarter-solid"
    case fly_brands = "custom_icon/fly-brands"
    case baseball_solid = "custom_icon/baseball-solid"
    case dice_d20_solid = "custom_icon/dice-d20-solid"
    case microphone_solid = "custom_icon/microphone-solid"
    case peace_solid = "custom_icon/peace-solid"

    static public var defaultOption: CustomWidgeImageOptions {
        CustomWidgeImageOptions.bomb_solid
    }
    
    public var image: Image {
        return Image(self.rawValue, bundle: .main)
    }
}

enum CustomWidgetMouthOptions: String, CaseIterable, Codable {
    case star_solid = "custom_icon/star-solid"
    case jet_fighter_solid = "custom_icon/jet-fighter-solid"
    case circle_xmark_solid = "custom_icon/circle-xmark-solid"
    case frown_regular = "custom_icon/frown-regular"
    case virus_covid_solid = "custom_icon/virus-covid-solid"
    case bullhorn_solid = "custom_icon/bullhorn-solid"
    case caret_down_solid = "custom_icon/caret-down-solid"
    case meteor_solid = "custom_icon/meteor-solid"
    case eye_solid = "custom_icon/eye-solid"
    case battery_half_solid = "custom_icon/battery-half-solid"
    case heart_crack_solid = "custom_icon/heart-crack-solid"
    case heart_solid = "custom_icon/heart-solid"
    case divide_solid = "custom_icon/divide-solid"
    case location_crosshairs_solid = "custom_icon/location-crosshairs-solid"
    case bitcoin_brands = "custom_icon/bitcoin-brands"
    case baby_solid = "custom_icon/baby-solid"
    case grin_regular = "custom_icon/grin-regular"
    case poo_storm_solid = "custom_icon/poo-storm-solid"
    case btc_brands = "custom_icon/btc-brands"
    case shuttle_space_solid = "custom_icon/shuttle-space-solid"
    case chess_king_solid = "custom_icon/chess-king-solid"
    case chess_queen_solid = "custom_icon/chess-queen-solid"
    case lightbulb_solid = "custom_icon/lightbulb-solid"
    case skull_solid = "custom_icon/skull-solid"
    case dice_one_solid = "custom_icon/dice-one-solid"
    case fan_solid = "custom_icon/fan-solid"
    case bolt_solid = "custom_icon/bolt-solid"
    case dharmachakra_solid = "custom_icon/dharmachakra-solid"
    case ban_solid = "custom_icon/ban-solid"
    case skull_crossbones_solid = "custom_icon/skull-crossbones-solid"
    case sad_tear_regular = "custom_icon/sad-tear-regular"
    case floppy_disk_solid = "custom_icon/floppy-disk-solid"
    case crosshairs_solid = "custom_icon/crosshairs-solid"
    case exclamation_solid = "custom_icon/exclamation-solid"
    case lemon_solid = "custom_icon/lemon-solid"
    case caret_right_solid = "custom_icon/caret-right-solid"
    case poo_solid = "custom_icon/poo-solid"
    case rainbow_solid = "custom_icon/rainbow-solid"
    case apple_brands = "custom_icon/apple-brands"
    case x_solid = "custom_icon/x-solid"
    case pizza_slice_solid = "custom_icon/pizza-slice-solid"
    case empire_brands = "custom_icon/empire-brands"
    case caret_up_solid = "custom_icon/caret-up-solid"
    case life_ring_solid = "custom_icon/life-ring-solid"
    case dragon_solid = "custom_icon/dragon-solid"
    case cannabis_solid = "custom_icon/cannabis-solid"
    case bullseye_solid = "custom_icon/bullseye-solid"
    case code_compare_solid = "custom_icon/code-compare-solid"
    case battery_empty_solid = "custom_icon/battery-empty-solid"
    case moon_solid = "custom_icon/moon-solid"
    case android_brands = "custom_icon/android-brands"
    case smile_beam_regular = "custom_icon/smile-beam-regular"
    case futbol_solid = "custom_icon/futbol-solid"
    case dollar_sign_solid = "custom_icon/dollar-sign-solid"
    case cross_solid = "custom_icon/cross-solid"
    case bomb_solid = "custom_icon/bomb-solid"
    case battery_full_solid = "custom_icon/battery-full-solid"
    case arrow_up_solid = "custom_icon/arrow-up-solid"
    case gem_solid = "custom_icon/gem-solid"
    case code_solid = "custom_icon/code-solid"
    case bolt_lightning_solid = "custom_icon/bolt-lightning-solid"
    case caret_left_solid = "custom_icon/caret-left-solid"
    case fort_awesome_brands = "custom_icon/fort-awesome-brands"
    case fire_solid = "custom_icon/fire-solid"
    case hotjar_brands = "custom_icon/hotjar-brands"
    case burger_solid = "custom_icon/burger-solid"
    case egg_solid = "custom_icon/egg-solid"
    case meh_regular = "custom_icon/meh-regular"
    case battery_three_quarters_solid = "custom_icon/battery-three-quarters-solid"
    case crown_solid = "custom_icon/crown-solid"
    case clock_solid = "custom_icon/clock-solid"
    case battery_quarter_solid = "custom_icon/battery-quarter-solid"
    case fly_brands = "custom_icon/fly-brands"
    case baseball_solid = "custom_icon/baseball-solid"
    case dice_d20_solid = "custom_icon/dice-d20-solid"
    case microphone_solid = "custom_icon/microphone-solid"
    case peace_solid = "custom_icon/peace-solid"
    
    static public var defaultOption: CustomWidgetMouthOptions {
        CustomWidgetMouthOptions.bomb_solid
    }
    
    public var image: Image {
        return Image(self.rawValue, bundle: .main)
    }
}
