import Foundation
import UIKit
import WortiseSDK

@objc
public class WortiseAppOpen: NSObject {

    @objc
    public static let shared = WortiseAppOpen()


    fileprivate var delegates = [Int: WortiseAppOpenDelegate]()

    fileprivate var instances = [Int: WAAppOpenAd]()


    @objc
    public func create(_ id: Int, adUnitId: String) {
        if instances.keys.contains(id) {
            return
        }

        let ad = WAAppOpenAd(adUnitId: adUnitId)

        let delegate = WortiseAppOpenDelegate(id)

        ad.delegate = delegate

        delegates[id] = delegate
        instances[id] = ad
    }

    @objc
    public func destroy(_ id: Int) {
        delegates.removeValue(forKey: id)

        guard let instance = instances.removeValue(forKey: id) else {
            return
        }

        DispatchQueue.main.async {
            instance.destroy()
        }
    }

    @objc
    public func getAutoReload(_ id: Int) -> Bool {
        return instances[id]?.autoReload ?? false
    }

    @objc
    public func getCooldownRemainingMs(_ id: Int) -> Int64 {
        return Int64((instances[id]?.cooldownRemaining ?? 0) * 1000)
    }

    @objc
    public func isAvailable(_ id: Int) -> Bool {
        return instances[id]?.isAvailable ?? false
    }

    @objc
    public func isDestroyed(_ id: Int) -> Bool {
        return instances[id]?.isDestroyed ?? false
    }

    @objc
    public func isInCooldown(_ id: Int) -> Bool {
        return instances[id]?.isInCooldown ?? false
    }

    @objc
    public func isShowing(_ id: Int) -> Bool {
        return instances[id]?.isShowing ?? false
    }

    @objc
    public func loadAd(_ id: Int, requestParameters: String?) {
        DispatchQueue.main.async {

            let parameters = WortiseRequestParametersFactory.create(requestParameters)

            self.instances[id]?.loadAd(parameters: parameters)
        }
    }

    @objc
    public func setAutoReload(_ id: Int, value: Bool) {
        instances[id]?.autoReload = value
    }

    @objc
    public func showAd(_ id: Int) {
        guard let controller = WortiseUtils.rootViewController else {
            return
        }

        DispatchQueue.main.async {
            self.instances[id]?.showAd(from: controller)
        }
    }

    @objc
    public func tryToShowAd(_ id: Int) {
        guard let controller = WortiseUtils.rootViewController else {
            return
        }

        DispatchQueue.main.async {
            self.instances[id]?.tryToShowAd(from: controller)
        }
    }
}

class WortiseAppOpenDelegate: WAAppOpenDelegate {

    fileprivate let id: Int


    init(_ id: Int) {
        self.id = id
    }

    func didClick(appOpenAd: WAAppOpenAd) {
        WortiseUtils.send(event: "OnAppOpenClicked", message: String(id))
    }
    
    func didDismiss(appOpenAd: WAAppOpenAd) {
        WortiseUtils.send(event: "OnAppOpenDismissed", message: String(id))
    }
    
    func didFailToLoad(appOpenAd: WAAppOpenAd, error: WAAdError) {
        WortiseUtils.send(event: "OnAppOpenFailedToLoad", message: String(id))
    }
    
    func didFailToShow(appOpenAd: WAAppOpenAd, error: WAAdError) {
        WortiseUtils.send(event: "OnAppOpenFailedToShow", message: String(id))
    }

    func didImpress(appOpenAd: WAAppOpenAd) {
        WortiseUtils.send(event: "OnAppOpenImpression", message: String(id))
    }

    func didLoad(appOpenAd: WAAppOpenAd) {
        WortiseUtils.send(event: "OnAppOpenLoaded", message: String(id))
    }

    func didPayRevenue(appOpenAd: WAAppOpenAd, data: WARevenueData) {
        var dictionary = data.toDictionary()

        dictionary["id"] = id

        WortiseUtils.send(event: "OnAppOpenRevenuePaid", data: dictionary)
    }
    
    func didShow(appOpenAd: WAAppOpenAd) {
        WortiseUtils.send(event: "OnAppOpenShown", message: String(id))
    }
}
