//
//  NavigationRouter.swift
//  Core
//
//  Created by Javier Cicchelli on 11/04/2023.
//  Copyright © 2023 Röck+Cöde. All rights reserved.
//

import UIKit

/// This class is responsible for presenting view controllers, as it is a concrete implementation of the `Router` protocol, but it won't know what view controller or which view controller is next.
public class NavigationRouter: NSObject {
    
    // MARK: Properties
    
    /// A navigation controller to use within this concrete router.
    private let navigationController: UINavigationController

    /// A root view controller coming in from the navigation controller, if any.
    private let rootViewController: UIViewController?
    
    /// Dictionary that persist `onDismiss` closure for its respective view controllers until one of the later is dismissed.
    private var onDismissForViewController: [UIViewController: Router.OnDismissedClosure] = [:]

    // MARK: Initialisers
    
    /// Initialise this router.
    /// - Parameter navigationController: A `UINavigationController` navigation controller instance to use in this router.
    public init(navigationController: UINavigationController) {
        self.navigationController = navigationController
        self.rootViewController = navigationController.viewControllers.first
        
        super.init()
        
        self.navigationController.delegate = self
    }

}

// MARK: - Router

extension NavigationRouter: Router {
    
    // MARK: Functions
    
    public func present(
        _ viewController: UIViewController,
        animated: Bool,
        onDismiss: OnDismissedClosure?
    ) {
        onDismissForViewController[viewController] = onDismiss
        
        navigationController.pushViewController(viewController, animated: animated)
    }
    
    public func dismiss(animated: Bool) {
        guard let rootViewController else {
            navigationController.popViewController(animated: animated)
            return
        }
        
        performOnDismissed(for: rootViewController)
        
        navigationController.popToViewController(rootViewController, animated: animated)
    }
    
}

// MARK: - UINavigationControllerDelegate

extension NavigationRouter: UINavigationControllerDelegate {
    
    // MARK: Functions
    
    public func navigationController(
        _ navigationController: UINavigationController,
        didShow viewController: UIViewController,
        animated: Bool
    ) {
        guard let dismissedViewController = navigationController.transitionCoordinator?.viewController(forKey: .from) else {
            return
        }
        
        performOnDismissed(for: dismissedViewController)
    }

}

// MARK: - Helpers

private extension NavigationRouter {
    
    // MARK: Functions
    
    func performOnDismissed(for viewController: UIViewController) {
        guard let onDismiss = onDismissForViewController[viewController] else {
            return
        }
        
        onDismiss()
        
        onDismissForViewController[viewController] = nil
    }

}
