//
//  OasisPlayerView.swift
//  OasisPlayerPlugin
//
//  Created by Roman Karpievich on 12/3/20.
//

import UIKit
import React
import OasisPlayer

public class OasisPlayerView: UIView {
    
    // MARK: - React Native
    
    // playablaItem
    @objc var entry: NSDictionary? {
        didSet {
            self.pluginConfiguration = entry?["pluginConfiguration"] as? NSDictionary
            
            guard let entry = entry else { return }
            let playable = Playable(from: entry)
            
            guard let oasisEnvironment = setOasisEnvironment(playble: playable) else {
                return
            }
            
            let somConfig = SOMConfig(from: playable.sourceDictionary,
                                      configuration: pluginConfiguration ?? [:])
            let playerViewController = OasisPlayerViewController(playable: playable,
                                                                 oasisEnvironment: oasisEnvironment,
                                                                 somConfig: somConfig)
            playerViewController.modalPresentationStyle = .fullScreen

            let rootVC = UIApplication.topViewController()
            rootVC?.present(playerViewController, animated: true, completion: nil)
            
            self.playerViewController = playerViewController
        }
    }
    
    @objc var pluginConfiguration: NSDictionary? {
        didSet {
            let PLAYER_ID_FROM_CONFIG = "oasis_player_config_id"
            
            if let playerConfigId = pluginConfiguration?[PLAYER_ID_FROM_CONFIG] as? String {
                let playerConfiguration = PlayerConfiguration(configId: playerConfigId)
                let oasisEnvironment = OasisEnvironment(playerConfiguration: playerConfiguration)
                OasisPlayerView.oasisEnvironments[playerConfigId] = oasisEnvironment
            }
            
            let testID = "de.prosiebensat17sports.applicaster-prod"
            let oasisEnvironment = OasisEnvironment(playerConfiguration: PlayerConfiguration(configId: testID))
            OasisPlayerView.oasisEnvironments[testID] = oasisEnvironment
        }
    }
    
    @objc public var onVideoEnd: RCTBubblingEventBlock? {
        didSet {
            playerViewController?.onVideoEnd = { [weak self] in
                self?.onVideoEnd?(["target": self?.reactTag ?? NSNull()])
            }
        }
    }
        
    public init(eventDispatcher: RCTEventDispatcher) {
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Native
    
    private static var oasisEnvironments: [String: OasisEnvironment] = [:]
    private var playerViewController: OasisPlayerViewController?
    
    private func setOasisEnvironment(playble: Playable) -> OasisEnvironment? {
        let PLAYER_CONFIG_KEY = "playerConfig"
        let ID_KEY = "id"
        
        var environments = OasisPlayerView.oasisEnvironments
        
        guard let streams = playble.extensions?["streams"] as? [String: [[String: Any]]],
              let key = streams.keys.first,
              let stream = streams[key]?.first,
              let config = stream[PLAYER_CONFIG_KEY] as? [String: Any],
              let configId = config[ID_KEY] as? String else {
            return environments.first?.value
        }
        
        if environments.keys.contains(configId) {
            return environments[configId]
        } else {
            let playerConfiguration = PlayerConfiguration(configId: configId)
            let oasisEnv = OasisEnvironment(playerConfiguration: playerConfiguration)
            environments[configId] = oasisEnv
            
            return oasisEnv
        }
    }
    
    // TOOD: This method shoud be called on presenting player in fullscreen mode
    
    private func generateFullScreenEvent() {
//        guard let playable = playerViewController?.currentPlayableItem else {
//            return
//        }
//        var eventName = ""
//        //"Video or Livestream Title" "Domain" "Video Type (VOD or Live)"
//        //"Domain" and "Video Type" are both important because they determine which IVW code is fired
//        let name = playable.playableName() ?? ""
//        let domain = playable.getDomain() ?? "default" //take the default domain
//
//        if playable.isLive() {
//            eventName = name + " - " + domain + " - " + "LIVE"
//        } else {
//            eventName = name + " - " + domain + " - " + "VOD"
//        }
//
//        ZAAppConnector.sharedInstance().analyticsDelegate.trackScreenView(screenTitle: eventName, parameters: [:])
    }
    
    // As an example from old code. Just to see how inline playet was layouted previosly
    
//    public func pluggablePlayerAddInline(_ rootViewController: UIViewController, container: UIView) {
//        playerViewController?.isFullScreen = false
//        if let playerVC = self.pluggablePlayerViewController() {
//            rootViewController.addChildViewController(playerVC, to:container)
//            playerVC.view.matchParent();
//        }
//    }
}

extension UIApplication {
    class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let nav = base as? UINavigationController {
            return topViewController(base: nav.visibleViewController)
        }
        if let presented = base?.presentedViewController {
            return topViewController(base: presented)
        }
        return base
    }
}
