//
//  AuxiliarySceneDelegate.swift
//  Tusker
//
//  Created by Shadowfacts on 12/13/20.
//  Copyright © 2020 Shadowfacts. All rights reserved.
//

import UIKit
import Pachyderm
import UserAccounts

class AuxiliarySceneDelegate: UIResponder, UIWindowSceneDelegate, TuskerSceneDelegate {
    
    var window: UIWindow?
    
    var rootViewController: TuskerRootViewController? {
        window?.rootViewController as? TuskerRootViewController
    }
    
    private var launchActivity: NSUserActivity?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else {
            return
        }
        
        guard let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity else {
            // without an account, we don't know what type of auxiliary scene this is and can't do anything
            UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
            return
        }
        launchActivity = activity
        
        let account: UserAccountInfo
        
        if let activityAccount = UserActivityManager.getAccount(from: activity) {
            account = activityAccount
        } else if let mostRecent = UserAccountsManager.shared.getMostRecentAccount() {
            account = mostRecent
        } else {
            // without an account, we can't do anything so we just destroy the scene
            // todo: this isn't really true for instance public timelines, how much do we care about that?
            UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
            return
        }
        
        let controller = MastodonController.getForAccount(account)
        session.mastodonController = controller
        controller.initialize()
        
        guard let rootVC = viewController(for: activity, mastodonController: controller) else {
            UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
            return
        }
        rootVC.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(close))
        let nav = EnhancedNavigationViewController(rootViewController: rootVC)
        
        window = UIWindow(windowScene: windowScene)
        window!.rootViewController = nav
        window!.makeKeyAndVisible()
        
        NotificationCenter.default.addObserver(self, selector: #selector(themePrefChanged), name: .themePreferenceChanged, object: nil)
        themePrefChanged()
    }
    
    func sceneWillResignActive(_ scene: UIScene) {
        scene.userActivity = launchActivity
    }
    
    func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
        return scene.userActivity
    }
    
    private func viewController(for activity: NSUserActivity, mastodonController: MastodonController) -> UIViewController? {
        switch UserActivityType(rawValue: activity.activityType) {
        case .showTimeline:
            guard let (timeline, _) = UserActivityManager.getTimeline(from: activity) else { return nil }
            return timelineViewController(for: timeline, mastodonController: mastodonController)
            
        case .showConversation:
            guard let id = UserActivityManager.getConversationStatus(from: activity) else { return nil }
            return ConversationViewController(for: id, state: .unknown, mastodonController: mastodonController)
            
        case .checkNotifications:
            guard let mode = UserActivityManager.getNotificationsMode(from: activity) else { return nil }
            return NotificationsPageViewController(initialMode: mode, mastodonController: mastodonController)
            
        case .search:
            return InlineTrendsViewController(mastodonController: mastodonController)
            
        case .bookmarks:
            return BookmarksViewController(mastodonController: mastodonController)
            
        case .myProfile:
            return MyProfileViewController(mastodonController: mastodonController)
            
        case .showProfile:
            guard let id = UserActivityManager.getProfile(from: activity) else { return nil }
            return ProfileViewController(accountID: id, mastodonController: mastodonController)
            
        default:
            fatalError("invalid activity type for auxiliary scene: \(activity.activityType)")
        }
    }
    
    private func timelineViewController(for timeline: Timeline, mastodonController: MastodonController) -> UIViewController {
        switch timeline {
        case .tag(hashtag: let name):
            return HashtagTimelineViewController(forNamed: name, mastodonController: mastodonController)
        
        case .list(id: let id):
            let req = ListMO.fetchRequest(id: id)
            if let list = try? mastodonController.persistentContainer.viewContext.fetch(req).first {
                return ListTimelineViewController(for: list.apiList, mastodonController: mastodonController)
            } else {
                return TimelineViewController(for: timeline, mastodonController: mastodonController)
            }
            
        default:
            return TimelineViewController(for: timeline, mastodonController: mastodonController)
        }
    }
    
    @objc private func close() {
        closeWindow()
    }
    
    @objc private func themePrefChanged() {
        applyAppearancePreferences()
    }
}
