//
//  AnagogSDK.swift
//
//  Copyright © 2022 Anagog Ltd. All rights reserved.
//

import Foundation
import JedAIAppKit
import JedAIKit
import os

@objc
public class AnagogSDK: NSObject {
    @objc public let campaignHandlers = AnagogCampaignHandlers()
    @objc public var isStartupAllowed: Bool { stateManager.isStartupAllowed }
    @objc public internal(set) var callCompletionHandlerForRemoteNotifications: Bool = true
    @objc public internal(set) var overwriteUNUserNotificationCenterDelegate: Bool = true
    
    internal private(set) var startupConfigurator: AnagogStartupConfiguratorProtocol
    internal let stateManager: AnagogStateManager
    internal private(set) var unUserNotificationCenterDelegate: UNUserNotificationCenterDelegate? = nil
    
    /// Persistent storage
    internal let persistantStorage: PersistentStorageProtocol
    
    /// Cross-Platfrom calls to Native API
    internal let bridgeAPI: AnagogBridgeAPI
    
    /// Native calls to CrossPlatform API
    public let eventEmitterManager: AnagogEventEmitterManager

    @objc public var configurationFileURL: URL? {
        get { startupConfigurator.url }
        set { startupConfigurator.url = newValue }
    }
    
    
    // MARK: - Initialization
        
    internal init(configurator: AnagogStartupConfiguratorProtocol, storage: PersistentStorageProtocol) {
        _ = JedAIApp.shared
        self.persistantStorage = storage
        let eventEmitterManager = AnagogEventEmitterManager()
        
        self.stateManager = AnagogStateManager(persistantStorage: storage, eventEmitterManager: eventEmitterManager)
        self.startupConfigurator = configurator
        self.bridgeAPI = AnagogBridgeAPI()
        self.eventEmitterManager = eventEmitterManager
        
        super.init()
        
        self.bridgeAPI.sdkWrapper = self
    }
    
    
    // MARK: - New startup
    
    @objc
    public func startup() {
        self.startup(withOptions: nil)
    }
    @objc
    public func startup(withOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
        guard !self.stateManager.sdkIsInitialized else {
            assertionFailure("Anagog SDK is already initialized. You can't' call startup again.")
            return
        }
        self.startupConfigurator.configure() // Load JSON file
        self.handleUNUserNotificationCenter(force: false) // Handle UNUserNotificationCenter calls
        
        // Startup
        self.stateManager.startup(withOptions: launchOptions)
    }
    
    
    // MARK: - Configurations
    
    @objc
    public func isLaunchedInBackground(launchOptions: [UIApplication.LaunchOptionsKey: Any]) -> Bool {
        return launchOptions.contains(where: {$0.key == .location || $0.key == .remoteNotification})
    }
    
    @objc
    public func isLaunchedInForeground(launchOptions: [UIApplication.LaunchOptionsKey: Any]) -> Bool {
        return !isLaunchedInBackground(launchOptions: launchOptions)
    }
    
    @objc
    public func handleUNUserNotificationCenter(force: Bool = true) {
        guard force || self.overwriteUNUserNotificationCenterDelegate else {
            return
        }
        
        if let oldDelegate = UNUserNotificationCenter.current().delegate, oldDelegate !== self {
            unUserNotificationCenterDelegate = oldDelegate
        }
        UNUserNotificationCenter.current().delegate = self
    }
    
    
    // MARK: - AppDelegate methods
    
    @objc
    public func refresh() {
        JedAIApp.shared.refresh()
    }
    
    @objc
    public func didReceiveNotification(_ notification: UNNotification) {
        guard self.overwriteUNUserNotificationCenterDelegate == false else {
            assertionFailure("Do not call `didReceiveNotification` manually, when `overwriteUNUserNotificationCenterDelegate` option is set to `true`")
            return
        }
        JedAIApp.shared.didReceiveNotification(notification)
    }
    
    @objc
    @discardableResult
    public func didReceiveRemoteNotification(_ userInfo: [AnyHashable: Any]) -> Bool {
        return JedAIApp.shared.didReceiveRemoteNotification(userInfo)
    }
    
    @objc
    public func updateDeviceToken(_ deviceToken: Data) {
        JedAIApp.shared.updateDeviceToken(deviceToken)
    }
    
}
