//
//  MVMCoreUIActionHandler.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 7/18/22.
//  Copyright © 2022 Verizon Wireless. All rights reserved.
//

import Foundation
import MVMCore
import SafariServices

@objc open class MVMCoreUIActionHandler: MVMCoreActionHandler {
    
    /// Adds the source model to the additionalData
    public static func add(sourceModel: MoleculeModelProtocol?, to additionalData: [AnyHashable: Any]?) -> [AnyHashable: Any]? {
        guard let sourceModel = sourceModel else { return additionalData }
        return additionalData.dictionaryAdding(key: KeySourceModel, value: sourceModel)
    }
    
    /// Gets the source model from the additionalData
    public static func getSourceModel(from additionalData: [AnyHashable: Any]?) -> MoleculeModelProtocol? {
        return additionalData?[KeySourceModel] as? MoleculeModelProtocol
    }
    
    /// Removes the source model to the additionalData
    public static func removeSourceModel(from additionalData: [AnyHashable: Any]?) -> [AnyHashable: Any]? {
        guard var additionalData = additionalData else { return nil }
        additionalData.removeValue(forKey: KeySourceModel)
        return additionalData
    }
    
    /// Starts the action in a task, adding the source model.
    public static func performActionUnstructured(with model: ActionModelProtocol, sourceModel: MoleculeModelProtocol? = nil, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
        Task(priority: .userInitiated) {
            try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: model, additionalData: MVMCoreUIActionHandler.add(sourceModel: sourceModel, to: additionalData), delegateObject: delegateObject)
        }
    }
    
    /// Logs the error and shows a popup if the error is not silent.
    open override func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable : Any]?) {
        super.defaultHandleActionError(error, additionalData: additionalData)
        guard !error.silentError else { return }
        Task(priority: .userInitiated) { @MainActor in
            let alertObject = MVMCoreAlertObject.init(popupAlertWithError: error, isGreedy: false)!
            MVMCoreAlertHandler.shared()?.showAlert(with: alertObject)
        }
    }
    
    open override func logAction(with JSON: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
        // Legacy logging.
        delegateObject?.actionDelegate?.logAction?(withActionInformation: JSON, additionalData: additionalData) ?? MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: nil, actionInformation: JSON, additionalData: additionalData)
    }
    
    @objc(openURLInSafariWebView:)
    @MainActor
    open func openURL(inSafariWebView url: URL) {
        let safariViewController = SFSafariViewController(url: url)
        MVMCoreNavigationHandler.shared()?.present(safariViewController, animated: true)
    }
}
