//
//  UIApplicationSwitchRoot.swift
//  WOKA
//
//  Created by MacBook Pro on 28/05/24.
//

import UIKit

enum RootViewAnimations{
    case login
    case logout
}

// MARK: - Extension to UIApplication to manage root view controller transitions with animations.

extension UIApplication {
    
    // Static variable defining the animation option for login transition.
    static var loginAnimation: UIView.AnimationOptions = .transitionCrossDissolve
    
    // Static variable defining the animation option for logout transition.
    static var logoutAnimation: UIView.AnimationOptions = .curveLinear
    
    // Static method to set the root view controller of the key window with optional animation.
    public static func setRootView(_ viewController: UIViewController,
                                   // isLogin: Bool,
                                   animated: Bool = true,
                                   duration: TimeInterval = 0.5,
                                   completion: (() -> Void)? = nil) {
        // Safely unwrap the key window of the application.
        guard let keyWindow = UIApplication.shared.keyWindowInConnectedScenes else { return }
        
        // Choose the animation option based on login or logout (here we always use loginAnimation).
        let options: UIView.AnimationOptions = loginAnimation
        
        // If animation is not required, set the root view controller immediately.
        guard animated else {
            keyWindow.rootViewController = viewController
            return
        }
        
        // Perform the transition animation for changing the root view controller.
        UIView.transition(with: keyWindow, duration: duration, options: options, animations: {
            // Temporarily disable animations for setting the root view controller.
            let oldState = UIView.areAnimationsEnabled
            UIView.setAnimationsEnabled(false)
            UIApplication.shared.keyWindowInConnectedScenes?.rootViewController = viewController
            UIView.setAnimationsEnabled(oldState)
        }) { _ in
            // Call the completion handler if provided.
            completion?()
        }
    }
}

// MARK: - The enum AppStoryboard represents different storyboards in the application.

enum AppStoryboard: String {
    
    // These are the cases of the enum, each representing a storyboard name.
    case Login = "Login"
    case Main = "Main"
    case Home = "Home"
    case AuthenticationSB = "AuthenticationSB"
    // Computed property that returns an instance of UIStoryboard for the given case.
    var instance: UIStoryboard {
        // Creates and returns a UIStoryboard instance with the name of the enum case and the main bundle.
        return UIStoryboard(name: self.rawValue, bundle: Bundle.main)
    }
    
    // Generic function to instantiate and return a view controller of the specified type from the storyboard.
    func viewController<T: UIViewController>(viewControllerClass: T.Type, function: String = #function, line: Int = #line, file: String = #file) -> T {
        // Get the storyboard ID from the view controller class.
        let storyboardID = (viewControllerClass as UIViewController.Type).storyboardID
        
        // Attempt to instantiate the view controller with the given identifier from the storyboard instance.
        guard let scene = instance.instantiateViewController(withIdentifier: storyboardID) as? T else {
            // If the view controller cannot be instantiated, a runtime error is thrown with a detailed message.
            fatalError("ViewController with identifier \(storyboardID), not found in \(self.rawValue) Storyboard.\nFile : \(file) \nLine Number : \(line) \nFunction : \(function)")
        }
        
        // Return the instantiated view controller.
        return scene
    }
}

// MARK: - Extension to UIViewController to get the storyboard identifier.

extension UIViewController {
    // Computed property to return the class name as the storyboard ID.
    class var storyboardID: String {
        return "\(self)"
    }
    
    static func instantiate(from: AppStoryboard) -> Self {
        return from.viewController(viewControllerClass: self)
    }
}
