//
//  PageBehaviorProtocol.swift
//  MVMCoreUI
//
//  Created by Kyle on 5/8/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//

import MVMCore


public protocol PageBehaviorProtocol: ModelHandlerProtocol {
    
    /// Should the behavior persist regardless of page behavior model updates.
    var transcendsPageUpdates: Bool { get }
    
    /// Initializes the behavior with the model
    init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?)
}

public extension PageBehaviorProtocol {
    var transcendsPageUpdates: Bool { return false }
}

/**
    Behavior conforming protocols. Behaviors will conform to one or more of these protocols to receive page lifecycle events that pertain to them.
 */

public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol {
    func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?)
    func willSetupMolecule(with model: MoleculeModelProtocol, updating view: MoleculeViewProtocol?)
    func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol)
}

public extension PageMoleculeTransformationBehavior {
    // All optional.
    func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) {}
    func willSetupMolecule(with model: MoleculeModelProtocol, updating view: MoleculeViewProtocol?) {}
    func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol) {}
}

public protocol PageVisibilityBehavior: PageBehaviorProtocol {
    
    func willShowPage(_ delegateObject: MVMCoreUIDelegateObject?)
    func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?)
    func willHidePage(_ delegateObject: MVMCoreUIDelegateObject?)
    func onPageHidden(_ delegateObject: MVMCoreUIDelegateObject?)
}

public extension PageVisibilityBehavior {
    // All optional.
    func willShowPage(_ delegateObject: MVMCoreUIDelegateObject?) {}
    func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?) {}
    func willHidePage(_ delegateObject: MVMCoreUIDelegateObject?) {}
    func onPageHidden(_ delegateObject: MVMCoreUIDelegateObject?) {}
}

public protocol PageScrolledBehavior: PageBehaviorProtocol {
    
    func pageScrolled(scrollView: UIScrollView, _ delegateObject: MVMCoreUIDelegateObject?)
}

public protocol PageLocalDataShareBehavior: PageBehaviorProtocol {
    
    func compileLocalPageDataForTransfer(_ delegateObject: MVMCoreUIDelegateObject) -> [AnyHashable: Any]
    func receiveLocalPageData(_ data:[AnyHashable: Any], _ delegateObject: MVMCoreUIDelegateObject)
}

public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol {

    /// Returns if this behavior can handle the action.
    func canHandleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) -> Bool
    
    /// - Parameters:
    ///   - model: The action model.
    ///   - additionalData: Additional information of the
    func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) async throws
}

public extension MVMCoreUIDelegateObject {
    var behaviorModelDelegate: PageBehaviorHandlerModelProtocol? {
        (moleculeDelegate as? PageProtocol)?.pageModel as? PageBehaviorHandlerModelProtocol
    }
    
    weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? {
        moleculeDelegate as? (PageBehaviorHandlerProtocol & NSObjectProtocol)
    }
}
