//
//  PreferencesHostingController.swift
//  Tusker
//
//  Created by Shadowfacts on 11/17/19.
//  Copyright © 2019 Shadowfacts. All rights reserved.
//

import UIKit
import SwiftUI
import UserAccounts

class PreferencesNavigationController: UINavigationController {
    
    private var isSwitchingAccounts = false

    init(mastodonController: MastodonController) {
        let view = PreferencesView(mastodonController: mastodonController)
        let hostingController = UIHostingController(rootView: view)
        super.init(rootViewController: hostingController)
        hostingController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed))
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        NotificationCenter.default.addObserver(self, selector: #selector(showAddAccount), name: .addAccount, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(activateAccount(_:)), name: .activateAccount, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(userLoggedOut), name: .userLoggedOut, object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        if !isSwitchingAccounts {
            // workaround for onDisappear not being called when a modally presented UIHostingController is dismissed
            NotificationCenter.default.post(name: .preferencesChanged, object: nil)
        }
    }

    @objc func donePressed() {
        dismiss(animated: true)
    }
    
    @objc func showAddAccount() {
        let onboardingController = OnboardingViewController()
        onboardingController.onboardingDelegate = self
        onboardingController.instanceSelector.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelAddAccount))
        show(onboardingController, sender: self)
    }
    
    @objc func cancelAddAccount() {
        dismiss(animated: true) // dismisses instance selector
    }
    
    @objc func activateAccount(_ notification: Notification) {
        // TODO: this is a temporary measure
        // when switching accounts shortly after adding a new one, there is an old instance of PreferncesNavigationController still around
        // which tries to handle the notification but is unable to because it no longer is in a window (and therefore doesn't have a scene delegate)
        // the propper fix would be to figure out what's leaking instances of this class
        guard let windowScene = self.view.window?.windowScene else {
            return
        }
        let account = notification.userInfo!["account"] as! UserAccountInfo
        if let sceneDelegate = windowScene.delegate as? MainSceneDelegate {
            isSwitchingAccounts = true
            dismiss(animated: true) { // dismiss preferences
                sceneDelegate.activateAccount(account, animated: true)
            }
        } else {
            UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.mainSceneActivity(accountID: account.id), options: nil)
        }
    }
    
    @objc func userLoggedOut() {
        guard let windowScene = self.view.window?.windowScene else {
            return
        }
        if let sceneDelegate = windowScene.delegate as? MainSceneDelegate {
            isSwitchingAccounts = true
            dismiss(animated: true) { // dismiss preferences
                sceneDelegate.logoutCurrent()
            }
        } else {
            LogoutService(accountInfo: UserAccountsManager.shared.getMostRecentAccount()!).run()
            let accountID = UserAccountsManager.shared.getMostRecentAccount()?.id
            UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.mainSceneActivity(accountID: accountID), options: nil)
            UIApplication.shared.requestSceneSessionDestruction(windowScene.session, options: nil)
        }
    }

}

extension PreferencesNavigationController: OnboardingViewControllerDelegate {
    func didFinishOnboarding(account: UserAccountInfo) {
        guard let windowScene = self.view.window?.windowScene else {
            return
        }
        self.dismiss(animated: true) { // dismiss instance selector
            self.dismiss(animated: true) { // dismiss preferences
                if let sceneDelegate = windowScene.delegate as? MainSceneDelegate {
                    sceneDelegate.activateAccount(account, animated: false)
                } else {
                    UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.mainSceneActivity(accountID: account.id), options: nil)
                }
            }
        }
    }
}
