//
//  TextEntryFieldModel.swift
//  MVMCoreUI
//
//  Created by Kevin Christiano on 1/22/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//


@objcMembers open class TextEntryFieldModel: EntryFieldModel {
    //--------------------------------------------------
    // MARK: - Types
    //--------------------------------------------------
    
    public enum EntryType: String, Codable {
        case password
        case secure
        case number
        case numberSecure
        case email
        case text
        case phone
    }
    
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    
    open override class var identifier: String { "textField" }
    
    public var placeholder: String?
    public var enabledTextColor: Color = Color(uiColor: .mvmBlack)
    public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3)
    public var textAlignment: NSTextAlignment = .left
    public var keyboardOverride: String?
    public var type: EntryType?
    public var clearTextOnTap: Bool = false
    public var displayFormat: String?
    public var displayMask: String?
    
    //--------------------------------------------------
    // MARK: - Methods
    //--------------------------------------------------
    
    /// Reads the keyboardOverride set by server and returns the keyboard type associated with it.
    func assignKeyboardType() -> UIKeyboardType? {
        
        guard let keyboardType = keyboardOverride else { return nil }
        
        var typeInt = 0
        
        switch keyboardType {
        case "asciiCapable":
            typeInt = 1 // Displays a keyboard which can enter ASCII characters
        
        case "numbersAndPunctuation":
            typeInt = 2 // Numbers and assorted punctuation.
        
        case "URL":
            typeInt = 3 // A type optimized for URL entry (shows . / .com prominently).
        
        case "numberPad":
            typeInt = 4 // A number pad with locale-appropriate digits (0-9, ۰-۹, ०-९, etc.). Suitable for PIN entry.
        
        case "phonePad":
            typeInt = 5 // A phone pad (1-9, *, 0, #, with letters under the numbers).
        
        case "namePhonePad":
            typeInt = 6 // A type optimized for entering a person's name or phone number.
        
        case "emailAddress":
            typeInt = 7 // A type optimized for multiple email address entry (shows space @ . prominently).
        
        case "decimalPad":
            typeInt = 8 // A number pad with a decimal point.
        
        case "twitter":
            typeInt = 9 // A type optimized for twitter text entry (easy access to @ #)
        
        case "webSearch":
            typeInt = 10 // A default keyboard type with URL-oriented addition (shows space . prominently).
        
        case "asciiCapableNumberPad":
            typeInt = 11 // A number pad (0-9) that will always be ASCII digits.
        
        default:
            typeInt = 0 // Default type for the current input method.
        }
        
        return UIKeyboardType(rawValue: typeInt)
    }
    
    //--------------------------------------------------
    // MARK: - Keys
    //--------------------------------------------------
    
    private enum CodingKeys: String, CodingKey {
        case placeholder
        case textAlignment
        case enabledTextColor
        case disabledTextColor
        case keyboardOverride
        case type
        case clearTextOnTap
        case displayFormat
        case displayMask
    }
    
    //--------------------------------------------------
    // MARK: - Codec
    //--------------------------------------------------
    
    required public init(from decoder: Decoder) throws {
        try super.init(from: decoder)
        let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
        
        placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
        displayFormat = try typeContainer.decodeIfPresent(String.self, forKey: .displayFormat)
        keyboardOverride = try typeContainer.decodeIfPresent(String.self, forKey: .keyboardOverride)
        displayMask = try typeContainer.decodeIfPresent(String.self, forKey: .displayMask)
        type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
        
        if let clearTextOnTap = try typeContainer.decodeIfPresent(Bool.self, forKey: .clearTextOnTap) {
            self.clearTextOnTap = clearTextOnTap
        }
        
        if let enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) {
            self.enabledTextColor = enabledTextColor
        }
        
        if let disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) {
            self.disabledTextColor = disabledTextColor
        }
        
        if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) {
            self.textAlignment = textAlignment
        }
    }
    
    open override func encode(to encoder: Encoder) throws {
        try super.encode(to: encoder)
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encodeIfPresent(placeholder, forKey: .placeholder)
        try container.encodeIfPresent(textAlignment, forKey: .textAlignment)
        try container.encodeIfPresent(type, forKey: .type)
        try container.encodeIfPresent(displayFormat, forKey: .displayFormat)
        try container.encodeIfPresent(keyboardOverride, forKey: .keyboardOverride)
        try container.encodeIfPresent(displayMask, forKey: .displayMask)
        try container.encode(enabledTextColor, forKey: .enabledTextColor)
        try container.encode(disabledTextColor, forKey: .disabledTextColor)
        try container.encode(clearTextOnTap, forKey: .clearTextOnTap)
    }
}
