//
//  WifiWidgetMolecule.swift
//  MVMFrameworksSample
//
//  Created by Matt Bruce on 6/17/22.
//

import Foundation
import UIKit
import MVMCore
import MVMCoreUI

@objcMembers open class TestLabelToggle: View {
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------

    public let label = Label(fontStyle: .BoldBodySmall)
    public let toggle = TestToggle()
    
    //--------------------------------------------------
    // MARK: - MVMCoreViewProtocol
    //--------------------------------------------------
    
    open override func updateView(_ size: CGFloat) {
        super.updateView(size)
        label.updateView(size)
        toggle.updateView(size)
    }
    
    open override func setupView() {
        super.setupView()
        
        addSubview(label)
        addSubview(toggle)
        label.setContentHuggingPriority(.required, for: .vertical)
        NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false)
    }
    
    open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
        guard let model = model as? TestLabelToggleModel,
            let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject),
            let labelHeight = Label.estimatedHeight(with: model.label, delegateObject)
            else { return nil }
        
        return max(toggleHeight, labelHeight)
    }
    
    open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        
        guard let labelToggleModel = model as? TestLabelToggleModel else { return }
        
        label.set(with: labelToggleModel.label, delegateObject, additionalData)
        toggle.set(with: labelToggleModel.toggle, delegateObject, additionalData)
    }
    
    // MARK: - MoleculeViewProtocol
    open override func reset() {
        super.reset()
        label.reset()
        toggle.reset()
        label.setFontStyle(.BoldBodySmall)
    }
}

public class TestLabelToggleModel: MoleculeModelProtocol {
    public static var identifier: String = "testLabelToggle"
    public var moleculeName: String = TestLabelToggleModel.identifier
    public var backgroundColor: Color?
    public var label: LabelModel
    public var toggle: TestToggleModel

    public init(_ label: LabelModel, _ toggle: TestToggleModel) {
        self.label = label
        self.toggle = toggle
    }
    
    private enum CodingKeys: String, CodingKey {
        case moleculeName
        case backgroundColor
        case label
        case toggle
    }
    
    required public init(from decoder: Decoder) throws {
        let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
        backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey:.backgroundColor)
        label = try typeContainer.decode(LabelModel.self, forKey:.label)
        toggle = try typeContainer.decode(TestToggleModel.self, forKey:.toggle)
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(moleculeName, forKey: .moleculeName)
        try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
        try container.encode(label, forKey: .label)
        try container.encode(toggle, forKey: .toggle)
    }
}


public class WifiWidget: View {
    //--------------------------------------------------
    // MARK: - Outlets
    //--------------------------------------------------
    public private(set) var titleLabelToggle: TestLabelToggle = {
        let tlt = TestLabelToggle()
        tlt.label.setFontStyle(.BoldBodyLarge)
        return tlt
    }()
    public let descriptionLabel = Label(fontStyle: .RegularMicro)
    public let passwordTextField = TextEntryField()
    public let editTitleLink = Link()
    public let shareTitleLink = Link()

    private lazy var stack1:  Stack<StackModel> = {
        return Stack<StackModel>.createStack(with: [titleLabelToggle, descriptionLabel],
                                             axis: .vertical, spacing: Padding.Two)
    }()
    
    private lazy var stack2: Stack<StackModel> = {
        return Stack<StackModel>.createStack(with: [
                                            (view: editTitleLink, model: StackItemModel()),
                                            (view: shareTitleLink, model: StackItemModel(horizontalAlignment: .trailing))
                                             ],
                                             axis: .horizontal,
                                             spacing: Padding.Two)
    }()
    
    private var row2 = StackItemModel()
    private var row3 = StackItemModel()

    private lazy var stack: Stack<StackModel> = {
        let model = StackModel(molecules: [StackItemModel(), row2, row3],
                               axis: .vertical,
                               spacing: Padding.Four)
        let stackItems = [StackItem(andContain:stack1), StackItem(andContain: passwordTextField),  StackItem(andContain:stack2)]
        return Stack<StackModel>(with: model, stackItems: stackItems)
    }()

    //--------------------------------------------------
    // MARK: - Lifecycle
    //--------------------------------------------------
    
    /// Initial configuration of class and view.
    @objc final public override func setupView() {
        super.setupView()
        
        isAccessibilityElement = false
        setContentCompressionResistancePriority(.required, for: .vertical)
        accessibilityElements = [titleLabelToggle.label, descriptionLabel, editTitleLink, shareTitleLink]
        
        stack1.restack()
        stack2.restack()
        stack.restack()
        
        stack.backgroundColor = .clear
        addSubview(stack)
        
        NSLayoutConstraint.constraintPinSubview(stack,
                                                pinTop: true, topConstant: 16,
                                                pinBottom: true, bottomConstant: 16,
                                                pinLeft: true, leftConstant: 16,
                                                pinRight: true, rightConstant: 16)
    }
        
    open override func reset() {
        super.reset()
        stack.reset()
    }
    
    open func restack(){
        stack1.restack()
        stack2.restack()
        stack.restack()
    }
    
    open override func updateView(_ size: CGFloat) {
        super.updateView(size)
        stack.updateView(size)
    }

    //------------------------------------------------------
    // MARK: - Atomization
    //------------------------------------------------------
    
    open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        super.set(with: model, delegateObject, additionalData)
        
        guard let model = model as? WifiWidgetModel else { return }
        backgroundColor = model.backgroundColor?.uiColor ?? .mvmCoolGray1
                
        //Password Text Field Model
        passwordTextField.set(with: model.passwordModel, delegateObject, additionalData)

        //Update the Stacks with the models
        stack1.updateContainedMolecules(with: [model.titleModel, model.descriptionModel], delegateObject, additionalData)
        stack2.updateContainedMolecules(with: [model.editModel, model.shareModel], delegateObject, additionalData)
        
        //show/hide 2 and 3 rows
        row2.gone = !model.enabled
        row3.gone = !model.enabled
        stack.restack()
    }
}


