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

import UIKit
import CocoaLumberjack

class OutputSinksViewController: MusicLibraryBaseViewController {
    private var collectionViewHelper: MusicListDisplayHelper!
    private var outputSinksDelegate: OutputSinksDataSourceDelegate?
    private var observers = [ObserverToken] ()

    deinit {
        observers.forEach { NotificationCenter.default.removeObserver($0) }
        observers.removeAll()
    }
}

// MARK: - Overridden Methods
extension OutputSinksViewController {
    override func viewDidLoad() {
        assert(playerGroup != nil)
        hasSearchButton = false
        super.viewDidLoad()

        title = NSLocalizedString("OUTPUT OPTIONS", comment: "Output Sinks text")

        outputSinksDelegate = OutputSinksDataSourceDelegate(playerGroup: playerGroup!, playerController: playerController)
        let dataSource = MusicListDataSource(playerGroup: playerGroup!,
                                             playerController: playerController,
                                             delegate: outputSinksDelegate!)

        collectionViewHelper = MusicListDisplayHelper(dataSources: [dataSource],
                                                      viewController: self,
                                                      collectionView: collectionView!,
                                                      dragAllowed: false,
                                                      countUpdater: nil,
                                                      onItemSelected: { [weak self] indexPath, item in
                                                        guard let self = self else {
                                                            return
                                                        }
                                                        self.didSelect(row: indexPath.row, item: item)

            },
                                                      useNarrowRows: true)

        setupObservers()
    }
}

// MARK: - Private Methods
extension OutputSinksViewController {
    private func setupObservers() {
        let playerHandler: (PlayerNotification) -> () = { [weak self] notification in
            guard let self = self else { return }

            if notification.reason == .outputSelectorsChanged {
                self.outputSinksDelegate?.forceReload()
            }
        }

        let playerObserver = NotificationCenter.default.addObserver(forType: PlayerNotification.self,
                                                                    object: playerController,
                                                                    queue: OperationQueue.main,
                                                                    using: playerHandler)

        observers.append(playerObserver)
    }
    
    private func didSelect(row: Int, item: MusicListDisplayHelperItem) {
        guard let inputItem = item as? InputSourcesOutputSinksMusicListDisplayHelperItem else {
            return
        }
        
        let player = inputItem.player
        let selector = inputItem.source
        DDLogVerbose("Attempting to set output selector: \(selector) on player: \(player.displayName)")
        
        
        var currentActives = player.activeOutputSelectors
        if let index = currentActives.firstIndex(of: selector) {
            currentActives.remove(at: index)
        } else {
            currentActives.append(selector)
        }

        if currentActives.count > 0 {
            player.setOutputSelectors(currentActives,
                                      completion: { (success, e) in
                                        if !success, let error = e {
                                            DDLogError("Error setting output selector: \(error)")
                                        }
            }, completionQueue: DispatchQueue.main)
        } else {
            let alert = UIAlertController(title: NSLocalizedString("No Output Destination", comment: "Output Sink Alert"),
                                          message: NSLocalizedString("At least one output destination must be chosen per speaker.", comment: "Output Sink Alert MEssage"),
                                          preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK"),
                                          style: .default,
                                          handler: nil))

            present(alert, animated: true, completion: nil)
        }
    }
}
