//
//  UINavigationController+Extension.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 3/14/22.
//  Copyright © 2022 Verizon Wireless. All rights reserved.
//

import Foundation

public extension UINavigationController {
    
    /// Convenience function for setting the navigation item.
    func setNavigationItem(with model: NavigationItemModelProtocol, for viewController: UIViewController) {
        viewController.navigationItem.title = model.title
        viewController.navigationItem.accessibilityLabel = model.title
        viewController.navigationItem.hidesBackButton = model.hidesSystemBackButton
        viewController.navigationItem.leftItemsSupplementBackButton = !model.hidesSystemBackButton
        setNavigationButtons(with: model, for: viewController)
        setNavigationTitleView(with: model, for: viewController)
    }
    
    /// Convenience function for setting the navigation buttons.
    func setNavigationButtons(with model: NavigationItemModelProtocol, for viewController: UIViewController) {
        let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
        var leftItems: [UIBarButtonItem] = []
        if model.hidesSystemBackButton,
           model.alwaysShowBackButton != false {
            if let backButtonModel = model.backButton,
               MVMCoreNavigationHandler.shared()?.getViewControllers(for: self)?.count ?? 0 > 1 || model.alwaysShowBackButton ?? false {
                leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
            }
            if let leftItemModels = model.additionalLeftButtons {
                for item in leftItemModels {
                    leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
                }
            }
        }
        viewController.navigationItem.leftBarButtonItems = leftItems.count > 0 ? leftItems : nil

        var rightItems: [UIBarButtonItem] = []
        if let rightItemModels = model.additionalRightButtons {
            for item in rightItemModels {
                rightItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil))
            }
        }
        viewController.navigationItem.rightBarButtonItems = rightItems.count > 0 ? rightItems : nil
    }
    
    /// Convenience function for setting the navigation titleView.
    func setNavigationTitleView(with model: NavigationItemModelProtocol, for viewController: UIViewController) {
        let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
        if let titleViewModel = model.titleView,
           let molecule = ModelRegistry.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) {
            viewController.navigationItem.titleView = molecule
        }
    }
    
    /// Returns a ShadowImage based on the line property of NavigationItemModelProtocol
    func getNavigationBarShadowImage(for navigationItemModel: NavigationItemModelProtocol) -> UIImage? {
        guard let thickness = navigationItemModel.line?.thickness,
              let backgroundColor = navigationItemModel.line?.backgroundColor else { return nil }
        return backgroundColor.uiColor.image(CGSize(width: thickness, height: thickness))
    }
    
    /// Convenience function for setting the navigation bar ui
    func setNavigationBarUI(with model: NavigationItemModelProtocol) {
        let navigationBar = navigationBar
        let font = Styler.Font.BoldTitleSmall.getFont(false)
        let backgroundColor = model.backgroundColor?.uiColor
        let tint = model.tintColor.uiColor
        navigationBar.tintColor = tint

        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.titleTextAttributes = [NSAttributedString.Key.font: font,
                                          NSAttributedString.Key.foregroundColor: tint];
        appearance.backgroundColor = backgroundColor
        appearance.titleTextAttributes.updateValue(tint, forKey: .foregroundColor)
        appearance.titlePositionAdjustment = model.titleOffset ?? .zero
        appearance.shadowColor = model.line?.backgroundColor?.uiColor ?? .clear
        appearance.shadowImage = getNavigationBarShadowImage(for: model)?.withRenderingMode(.alwaysTemplate)
        navigationBar.standardAppearance = appearance
        navigationBar.scrollEdgeAppearance = appearance
        
        setNavigationBarHidden(model.hidden, animated: true)
    }
}
