//
//  ModuleMolecule.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 6/25/19.
//  Copyright © 2019 Verizon Wireless. All rights reserved.
//

import UIKit

open class ModuleMolecule: Container {

    open var moduleMolecule: MoleculeViewProtocol?
    var moduleMoleculeModel: ModuleMoleculeModel? {
        get { model as? ModuleMoleculeModel }
    }
    
    public override func setupView() {
        super.setupView()
    }
    
    public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        super.set(with: model, delegateObject, additionalData)

        guard let moduleMoleculeModel = model as? ModuleMoleculeModel,
            let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMoleculeModel.moduleName) else {
        // Critical error
                return
        }

        if moduleMolecule == nil {
            if let moleculeView = ModelRegistry.createMolecule(moduleModel, delegateObject: delegateObject, additionalData: additionalData) {
                addSubview(moleculeView)
                NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: false).values))
                moduleMolecule = moleculeView

                isAccessibilityElement = false
                if moleculeView.accessibilityElements != nil {
                    accessibilityElements = moleculeView.accessibilityElements
                } else {
                    accessibilityElements = [moleculeView]
                }
            }
        } else {
            moduleMolecule?.set(with: model, delegateObject, additionalData)
        }
    }

    public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {

        guard let moduleMolecule = model as? ModuleMoleculeModel,
            let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName),
            let classType = ModelRegistry.getMoleculeClass(moduleModel),
            let height = classType.estimatedHeight(with: moduleModel, delegateObject) else {
                // Critical error
                return 0
        }
        return height
    }

    public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
        guard let moduleMolecule = model as? ModuleMoleculeModel,
            let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName),
            let classType = ModelRegistry.getMoleculeClass(moduleModel),
               let name = classType.nameForReuse(with: moduleModel, delegateObject) else {
                // Critical error
            return "moduleMolecule<>"
        }
        return name
    }

    public override class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {

        guard let moduleName = (model as? ModuleMoleculeModel)?.moduleName,
            let _ = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
            if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) {
                error?.pointee = errorObject
                MVMCoreUILoggingHandler.shared()?.addError(toLog: errorObject)
            }
            return nil
        }
        return [moduleName]
    }
}
