//
//  TestToggleModel.swift
//  JSONCreator
//
//  Created by Matt Bruce on 7/27/22.
//  Copyright © 2022 Verizon Wireless. All rights reserved.
//

import Foundation
import MVMCore
import MVMCoreUI
import VDS

//MARK: - Model
public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDSToggleModel {
    
               
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    
    public static var identifier: String = "testToggle"
    public var moleculeName: String = TestToggleModel.identifier

    public var action: ActionModelProtocol?
    public var alternateAction: ActionModelProtocol?
    public var accessibilityIdentifier: String?
    public var backgroundColor: MVMCoreUI.Color?

    //FormFieldProtocol
    public var fieldKey: String?
    public var groupName: String = FormValidator.defaultGroupName
    public var baseValue: AnyHashable?
    public var readOnly: Bool = false
    public var enabled: Bool = true

    //ToggleModelProtocol
    public var id: String?
    public var showText: Bool = false
    public var on: Bool = false
    public var surface: Surface = .light
    public var inputId: String?
    public var value: AnyHashable?
    public var dataAnalyticsTrack: String?
    public var dataClickStream: String?
    public var dataTrack: String?
    public var disabled: Bool = false
    public var accessibilityHintEnabled: String?
    public var accessibilityHintDisabled: String?
    public var accessibilityValueEnabled: String?
    public var accessibilityValueDisabled: String?
    public var accessibilityLabelEnabled: String?
    public var accessibilityLabelDisabled: String?
    public var fontSize: VDSFontSize = .small
    public var textPosition: VDSTextPosition = .left
    public var fontWeight: VDSFontWeight = .regular
    public var offText: String = "Off"
    public var onText: String = "On"
    //--------------------------------------------------
    // MARK: - Keys
    //--------------------------------------------------

    private enum CodingKeys: String, CodingKey {
        case moleculeName
        case action
        case alternateAction
        case accessibilityIdentifier
        case fieldKey
        case groupName
        case readOnly
        case enabled //which to use
        
        case id
        case showText
        case on
        case surface
        case inputId
        case value
        case dataAnalyticsTrack
        case dataClickStream
        case dataTrack
        case disabled //which to use
        case fontSize
        case textPosition
        case fontWeight
        case offText
        case onText
    }
    
    //--------------------------------------------------
    // MARK: - Form Valdiation
    //--------------------------------------------------

    public func formFieldValue() -> AnyHashable? {
        guard enabled else { return nil }
        if let value = value {
            return value
        } else {
            return on
        }
    }

    //--------------------------------------------------
    // MARK: - Server Value
    //--------------------------------------------------
    open func formFieldServerValue() -> AnyHashable? {
        return formFieldValue()
    }

    //--------------------------------------------------
    // MARK: - Initializer
    //--------------------------------------------------
    required public convenience init(){
        self.init(false)
    }
    
    public init(_ state: Bool) {
        self.on = state
        baseValue = state
    }

    //--------------------------------------------------
    // MARK: - Codec
    //--------------------------------------------------

    required public init(from decoder: Decoder) throws {
        let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
        
        //molecule
        action = try typeContainer.decodeModelIfPresent(codingKey: .action)
        alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
        accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)

        //formField
        fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
        readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
        if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
            self.groupName = groupName
        }
        
        //vds toggle
        id = try typeContainer.decodeIfPresent(String.self, forKey: .id)
        showText = try typeContainer.decodeIfPresent(Bool.self, forKey: .showText) ?? false
        on = try typeContainer.decodeIfPresent(Bool.self, forKey: .on) ?? false
       
        surface = try typeContainer.decodeIfPresent(Surface.self, forKey: .surface)  ?? .light
        dataAnalyticsTrack = try typeContainer.decodeIfPresent(String.self, forKey: .dataAnalyticsTrack)
        dataClickStream = try typeContainer.decodeIfPresent(String.self, forKey: .dataClickStream)
        dataTrack = try typeContainer.decodeIfPresent(String.self, forKey: .dataTrack)
        fontSize = try typeContainer.decodeIfPresent(VDSFontSize.self, forKey: .fontSize) ?? .small
        textPosition = try typeContainer.decodeIfPresent(VDSTextPosition.self, forKey: .textPosition) ?? .left
        fontWeight = try typeContainer.decodeIfPresent(VDSFontWeight.self, forKey: .fontWeight) ?? .regular
        offText = try typeContainer.decodeIfPresent(String.self, forKey: .offText) ?? "Off"
        onText = try typeContainer.decodeIfPresent(String.self, forKey: .onText) ?? "On"
        
        accessibilityHintEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint")
        accessibilityHintDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccDisabled")
        accessibilityValueEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOn")
        accessibilityValueDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
        accessibilityLabelEnabled = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
        accessibilityLabelDisabled = accessibilityLabelEnabled
        
        if let _enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
            enabled = _enabled  && !readOnly
            disabled = !_enabled && readOnly
        } else if let _disabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .disabled) {
            enabled = !_disabled && !readOnly
            disabled = _disabled && readOnly
        }

        baseValue = on
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        //molecule
        try container.encode(moleculeName, forKey: .moleculeName)
        try container.encodeModelIfPresent(action, forKey: .action)
        try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction)
        try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
        //formField
        try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
        try container.encodeIfPresent(groupName, forKey: .groupName)
        try container.encode(readOnly, forKey: .readOnly)
        try container.encode(enabled, forKey: .enabled)
        //vds toggle
        try container.encodeIfPresent(id, forKey: .id)
        try container.encode(showText, forKey: .showText)
        try container.encode(on, forKey: .on)
        try container.encodeIfPresent(surface, forKey: .surface)
        try container.encodeIfPresent(inputId, forKey: .inputId)
        try container.encode(dataAnalyticsTrack, forKey: .dataAnalyticsTrack)
        try container.encode(dataClickStream, forKey: .dataClickStream)
        try container.encode(dataTrack, forKey: .dataTrack)
        try container.encode(disabled, forKey: .disabled)
        try container.encodeIfPresent(fontSize, forKey: .fontSize)
        try container.encodeIfPresent(textPosition, forKey: .textPosition)
        try container.encodeIfPresent(fontWeight, forKey: .fontWeight)
        try container.encodeIfPresent(offText, forKey: .offText)
        try container.encodeIfPresent(onText, forKey: .onText)
    }
}
