//
//  HelperBarViewController.swift
//  RetroArchiOS
//
//  Created by Yoshi Sugawara on 2/27/22.
//  Copyright © 2022 RetroArch. All rights reserved.
//

@available(iOS 13, *)
class HelperBarViewController: UIViewController {
   var viewModel = HelperBarViewModel()
   
   private let indicatorImageView: UIImageView = {
      let imageView = UIImageView(frame: .zero)
      imageView.image = UIImage(systemName: "arrow.down.circle")
      imageView.tintColor = .white
      imageView.translatesAutoresizingMaskIntoConstraints = false
      imageView.alpha = 0
      imageView.isUserInteractionEnabled = true
      return imageView
   }()
   
   private let navigationBar: UINavigationBar = {
      let navBar = UINavigationBar()
      navBar.barTintColor = .black
      navBar.isTranslucent = true
      navBar.alpha = 0.7
      navBar.tintColor = .white
      navBar.isHidden = true
      return navBar
   }()
   
   override func viewDidLoad() {
      viewModel.delegate = self
      setupViews()
      setupBarItems()
   }
   
   override func viewDidAppear(_ animated: Bool) {
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
         self?.showIndicatorAndFadeAway()
      }
   }
   
   override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
         self?.showIndicatorAndFadeAway()
      }
   }
   
   private func setupViews() {
      indicatorImageView.translatesAutoresizingMaskIntoConstraints = false
      view.addSubview(indicatorImageView)
      indicatorImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 4).isActive = true
      indicatorImageView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40).isActive = true
      indicatorImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true
      indicatorImageView.widthAnchor.constraint(equalTo: indicatorImageView.heightAnchor).isActive = true
      view.addSubview(navigationBar)
      navigationBar.translatesAutoresizingMaskIntoConstraints = false
      navigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
      navigationBar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
      navigationBar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
      let tap = UITapGestureRecognizer(target: self, action: #selector(didTap(_:)))
      tap.delegate = self
      view.addGestureRecognizer(tap)
      view.isUserInteractionEnabled = true
      let indicatorTap = UITapGestureRecognizer(target: self, action: #selector(didTapIndicator(_:)))
      indicatorImageView.addGestureRecognizer(indicatorTap)
      navigationBar.delegate = self
   }
   
   private func setupBarItems() {
      let barButtonItems = viewModel.createBarButtonItems()
      let navItem = UINavigationItem()
      navItem.leftBarButtonItems = barButtonItems
      navigationBar.items = [navItem]
      updateBarItems()
   }
   
   private func updateBarItems() {
      guard let navItem = navigationBar.items?[0],
            let barButtonItems = navItem.leftBarButtonItems else {
         return
      }
      for barButtonItem in barButtonItems {
         guard let helperBarItem = viewModel.barItemMapping[barButtonItem] else {
            continue
         }
         if helperBarItem.isSelected {
            barButtonItem.image = helperBarItem.selectedImage
            if let tintColor = helperBarItem.tintColorOnSelection {
               barButtonItem.tintColor = tintColor
            } else {
               barButtonItem.tintColor = nil
            }
         } else {
            barButtonItem.image = helperBarItem.image
            barButtonItem.tintColor = nil
         }
      }
   }
   
   private func showIndicatorAndFadeAway() {
      UIView.animateKeyframes(withDuration: 4.0, delay: 0) {
         UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1/7) { [weak self] in
            self?.indicatorImageView.alpha = 1.0
         }
         
         UIView.addKeyframe(withRelativeStartTime: 1/3, relativeDuration: 6/7) { [weak self] in
            self?.indicatorImageView.alpha = 0.0
         }
      }
   }

   var tappedIndicator = false
   
   @objc func didTap(_ sender: UITapGestureRecognizer) {
      let point = sender.location(in: view)
      guard point.y <= 60 else { return }   // detect top portion of view only
      if point.x <= 60 {
         indicatorImageView.layer.removeAllAnimations()
         indicatorImageView.alpha = 1.0
         tappedIndicator = false
         DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { [weak self] in
            if !(self?.tappedIndicator ?? false) {
               self?.showIndicatorAndFadeAway()
            }
         }
      }
   }
   
   @objc func didTapIndicator(_ sender: UITapGestureRecognizer) {
      viewModel.didInteractWithBar = true
      indicatorImageView.layer.removeAllAnimations()
      indicatorImageView.alpha = 0
      tappedIndicator = true
   }
}

@available(iOS 13, *)
extension HelperBarViewController: UIGestureRecognizerDelegate {
   func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
      true
   }
}

@available(iOS 13, *)
extension HelperBarViewController: HelperBarViewModelDelegate {
   func setNavigationBarHidden(_ isHidden: Bool) {
      navigationBar.isHidden = isHidden
   }
   func updateNavigationBarItems() {
      updateBarItems()
   }
}

@available(iOS 13, *)
extension HelperBarViewController: UINavigationBarDelegate {
   func position(for bar: UIBarPositioning) -> UIBarPosition {
      return .topAttached
   }
}
