//
//  ToggleModel.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 1/14/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//


public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    
    public static var identifier: String = "toggle"
    public var accessibilityIdentifier: String?
    public var backgroundColor: Color?
    public var selected: Bool = false
    public var animated: Bool = true
    public var enabled: Bool = true
    public var readOnly: Bool = false
    public var action: ActionModelProtocol?
    public var alternateAction: ActionModelProtocol?
    public var accessibilityText: String?
    public var onTintColor: Color = Color(uiColor: .mvmGreen)
    public var offTintColor: Color = Color(uiColor: .mvmBlack)
    public var onKnobTintColor: Color = Color(uiColor: .mvmWhite)
    public var offKnobTintColor: Color = Color(uiColor: .mvmWhite)
    
    public var fieldKey: String?
    public var groupName: String = FormValidator.defaultGroupName
    public var baseValue: AnyHashable?

    //--------------------------------------------------
    // MARK: - Keys
    //--------------------------------------------------

    private enum CodingKeys: String, CodingKey {
        case moleculeName
        case state
        case animated
        case enabled
        case readOnly
        case action
        case backgroundColor
        case accessibilityIdentifier
        case alternateAction
        case accessibilityText
        case onTintColor
        case offTintColor
        case onKnobTintColor
        case offKnobTintColor
        case fieldKey
        case groupName
    }
    
    //--------------------------------------------------
    // MARK: - Form Valdiation
    //--------------------------------------------------
    
    public func formFieldValue() -> AnyHashable? {
        guard enabled else { return nil }
        return selected
    }
    
    //--------------------------------------------------
    // MARK: - Initializer
    //--------------------------------------------------
    
    public init(_ state: Bool) {
        self.selected = state
        baseValue = state
    }
    
    //--------------------------------------------------
    // MARK: - Codec
    //--------------------------------------------------
    
    required public init(from decoder: Decoder) throws {
        let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
        
        if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
            self.selected = state
        }
        
        if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
            self.animated = animated
        }
        
        action = try typeContainer.decodeModelIfPresent(codingKey: .action)
        alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
        backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
        accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
        
        if let onTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onTintColor) {
            self.onTintColor = onTintColor
        }
        
        if let offTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offTintColor) {
            self.offTintColor = offTintColor
        }
        
        if let onKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onKnobTintColor) {
            self.onKnobTintColor = onKnobTintColor
        }
        
        if let offKnobTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .offKnobTintColor) {
            self.offKnobTintColor = offKnobTintColor
        }
        
        accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)

        baseValue = selected
        fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
        if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
            self.groupName = groupName
        }
        enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
        readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
        try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
        try container.encodeModelIfPresent(action, forKey: .action)
        try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction)
        try container.encode(moleculeName, forKey: .moleculeName)
        try container.encode(selected, forKey: .state)
        try container.encode(animated, forKey: .animated)
        try container.encode(enabled, forKey: .enabled)
        try container.encode(onTintColor, forKey: .onTintColor)
        try container.encode(onKnobTintColor, forKey: .onKnobTintColor)
        try container.encode(onKnobTintColor, forKey: .onKnobTintColor)
        try container.encode(offKnobTintColor, forKey: .offKnobTintColor)
        try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
        try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
        try container.encodeIfPresent(groupName, forKey: .groupName)
        try container.encode(readOnly, forKey: .readOnly)
    }
}
