//
//  NavigationItemModelProtocol.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 3/12/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//


open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol {
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    
    open class var identifier: String { "navigationBar" }
    
    open var title: String?
    open var hidden: Bool
    open var backgroundColor: Color?
    open var tintColor: Color
    open var line: LineModel?
    open var hidesSystemBackButton = true
    
    /// If true, we add the button in the backButton property. If false we do not add the button. If nil, we add the button if the controller is not the bottom of the stack
    open var alwaysShowBackButton: Bool?
    open var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)?
    
    open var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
    open var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
    open var titleView: MoleculeModelProtocol?
    
    //--------------------------------------------------
    // MARK: - Initializer
    //--------------------------------------------------
    
    public init() {
        hidden = false
        backgroundColor = Color(uiColor: .mvmWhite)
        tintColor = Color(uiColor: .mvmBlack)
        line = LineModel(type: .standard)
    }
    
    //--------------------------------------------------
    // MARK: - Keys
    //--------------------------------------------------
    
    private enum CodingKeys: String, CodingKey {
        case moleculeName
        case title
        case hidden
        case backgroundColor
        case tintColor
        case line
        case hidesSystemBackButton
        case alwaysShowBackButton
        case backButton
        case additionalLeftButtons
        case additionalRightButtons
        case titleView
    }
    
    //--------------------------------------------------
    // MARK: - Codec
    //--------------------------------------------------
    
    required public init(from decoder: Decoder) throws {
        let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
        title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
        hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false
        backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .mvmWhite)
        tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .mvmBlack)
        line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) ?? LineModel(type: .standard)
        hidesSystemBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidesSystemBackButton) ?? true
        alwaysShowBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysShowBackButton)
        backButton = try typeContainer.decodeModelIfPresent(codingKey: .backButton)
        additionalLeftButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalLeftButtons)
        additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons)
        titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView)
    }
              
    open func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(moleculeName, forKey: .moleculeName)
        try container.encodeIfPresent(title, forKey: .title)
        try container.encode(hidden, forKey: .hidden)
        try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
        try container.encode(tintColor, forKey: .tintColor)
        try container.encodeIfPresent(line, forKey: .line)
        try container.encode(hidesSystemBackButton, forKey: .hidesSystemBackButton)
        try container.encodeIfPresent(alwaysShowBackButton, forKey: .alwaysShowBackButton)
        try container.encodeModelIfPresent(backButton, forKey: .backButton)
        try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
        try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
        try container.encodeModelIfPresent(titleView, forKey: .titleView)
    }
}

extension NavigationItemModel: ParentMoleculeModelProtocol {
    public var children: [MoleculeModelProtocol] {
        var children: [MoleculeModelProtocol] = [line, titleView, backButton].compactMap { $0 }
        if let leftButtons = additionalLeftButtons {
            children.append(contentsOf: leftButtons)
        }
        if let rightButtons = additionalRightButtons {
            children.append(contentsOf: rightButtons)
        }
        return children
    }
}
