//
// © 2018-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

import UIKit
import CocoaLumberjack

protocol MiniPlayerHosting {
    var playerGroup: IoTPlayerGroup? { get set }
}

class MiniPlayerHostingNavigationController: UINavigationController, MiniPlayerHosting {
	private var miniPlayer: MiniPlayerViewController?
	var playerGroup: IoTPlayerGroup? {
		didSet {
			if playerGroup != nil {
				if let miniVC = miniPlayer {
					miniVC.playerGroup = playerGroup
				}
				
				for vc in viewControllers {
					if let embedder = vc as? MiniPlayerEmbeddingViewController {
						embedder.playerGroup = playerGroup
					}
				}
			}
		}
	}
}

// MARK: - Overridden Methods
extension MiniPlayerHostingNavigationController {
	override func viewDidLoad() {
		super.viewDidLoad()
		self.delegate = self
		miniPlayer = MiniPlayerViewController.instantiateFromStoryboard(name: "Music")
		miniPlayer?.playerGroup = playerGroup
		miniPlayer?.injectDependencies(preferences: preferences, playerController: playerController)
		miniPlayer?.tapDelegate = self
		
		for vc in viewControllers {
			vc.injectDependencies(preferences: preferences, playerController: playerController)
		}
	}
	
	override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
		if let navController = segue.destination as? UINavigationController,
			let nowPlayingVC = navController.topViewController as? NowPlayingViewController {
			navController.transitioningDelegate = self
			nowPlayingVC.injectDependencies(preferences: preferences, playerController: playerController)
			nowPlayingVC.playerGroup = playerGroup
		}
	}
}

// MARK: - MiniPlayerGestureDelegate Conformance
extension MiniPlayerHostingNavigationController: MiniPlayerTapDelegate {
	func miniPlayerDidTapToExpand(_ miniPlayer: MiniPlayerViewController) {
		performSegue(withIdentifier: "showNowPlaying", sender: self)
	}
}

// MARK: - UIViewControllerTransitioningDelegate Conformance
extension MiniPlayerHostingNavigationController: UIViewControllerTransitioningDelegate {
	func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
		return NowPlayingSlideUpAnimator()
	}
	
	func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
		return NowPlayingSlideDownAnimator()
	}
}

// MARK: - UINavigationControllerDelegate Conformance
extension MiniPlayerHostingNavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController,
                              animationControllerFor operation: UINavigationController.Operation,
                              from fromVC: UIViewController,
                              to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return nil;
    }

	func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
		
		// No title for back button to centre next title
		let bbi = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
		if presentingViewController != nil {
            bbi.makeAccessible(Accessibility.Navigation.modalCloseButton)
		} else {
            bbi.makeAccessible(Accessibility.Navigation.backButton)
		}
		viewController.navigationItem.backBarButtonItem = bbi
		
		// Remove from current

		if let currentEmbedder = miniPlayer?.containerViewController as? MiniPlayerEmbeddingViewController {
			currentEmbedder.removeMiniPlayer()
		}
		
		viewController.injectDependencies(preferences: preferences, playerController: playerController)
		
		guard let nextEmbedder = viewController as? MiniPlayerEmbeddingViewController else {
			return
		}
		
		nextEmbedder.playerGroup = playerGroup

		guard let miniPlayerView = miniPlayer?.view else {
			return
		}

		// Do we need to show it on top during the transition?
		guard let item = playerGroup?.playlist?.currentItem,
			!item.isEmpty else {
				return
		}

		// We use frame rects here as using autolayout screws up the back animations.

		var miniPlayerFrame = miniPlayerView.frame
        let viewFrame = view.frame
        var bottomInset: CGFloat = 0.0
        if #available(iOS 11.0, *) {
        	bottomInset = view.safeAreaInsets.bottom
        }
		miniPlayerFrame.origin.x = 0
        miniPlayerFrame.origin.y = viewFrame.size.height - (miniPlayerFrame.size.height + bottomInset)
        miniPlayerView.frame = miniPlayerFrame

        view.addSubview(miniPlayerView)
	}
	
	func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
		guard let miniPlayerView = miniPlayer?.view else {
			return
		}
		
		if miniPlayerView.superview == view {
			miniPlayerView.removeFromSuperview()
		}
		
		guard let embedder = viewController as? MiniPlayerEmbeddingViewController else {
			return
		}
		
		embedder.embedMiniPlayer(miniPlayer!)
	}
}
