//
//  TabBarAccessoryModifier.swift
//  vibes
//
//  Created by Claude Code
//

import SwiftUI
import UIKit

/// A view modifier that sets a custom bottom accessory on the tab bar
/// using UITabBarController's public setBottomAccessory(_:animated:) API
struct TabBarAccessoryModifier<AccessoryContent: View>: ViewModifier {
    let isEnabled: Bool
    let accessoryContent: () -> AccessoryContent

    func body(content: Content) -> some View {
        content
            .background(
                TabBarAccessoryController(
                    isEnabled: isEnabled,
                    accessoryContent: accessoryContent
                )
            )
    }
}

/// UIViewControllerRepresentable that manages the tab bar accessory
private struct TabBarAccessoryController<Content: View>: UIViewControllerRepresentable {
    let isEnabled: Bool
    let accessoryContent: () -> Content

    func makeUIViewController(context: Context) -> AccessoryViewController<Content> {
        AccessoryViewController(
            isEnabled: isEnabled,
            accessoryContent: accessoryContent
        )
    }

    func updateUIViewController(_ uiViewController: AccessoryViewController<Content>, context: Context) {
        uiViewController.updateAccessory(
            isEnabled: isEnabled,
            accessoryContent: accessoryContent
        )
    }
}

/// Controller that manages the UIKit tab bar accessory with SwiftUI content
private class AccessoryViewController<Content: View>: UIViewController {
    private var isEnabled: Bool
    private var accessoryContent: () -> Content
    private var hostingController: UIHostingController<Content>?
    private var currentAccessory: UITabAccessory?

    init(isEnabled: Bool, accessoryContent: @escaping () -> Content) {
        self.isEnabled = isEnabled
        self.accessoryContent = accessoryContent
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        updateAccessory(isEnabled: isEnabled, accessoryContent: accessoryContent)
    }

    func updateAccessory(isEnabled: Bool, accessoryContent: @escaping () -> Content) {
        self.isEnabled = isEnabled
        self.accessoryContent = accessoryContent

        guard let tabBarController = findTabBarController() else {
            return
        }

        setAccessory(on: tabBarController)
    }

    /// Traverses the view controller hierarchy to find UITabBarController
    private func findTabBarController() -> UITabBarController? {
        // Start from this view controller and traverse up
        var current: UIViewController? = self

        while let vc = current {
            if let tabBarController = vc as? UITabBarController {
                return tabBarController
            }
            if let tabBarController = vc.tabBarController {
                return tabBarController
            }
            current = vc.parent
        }

        // If not found in hierarchy, try through the window
        guard let windowScene = view.window?.windowScene else {
            return nil
        }

        for window in windowScene.windows {
            if let tabBarController = findTabBarControllerInView(window.rootViewController) {
                return tabBarController
            }
        }

        return nil
    }

    /// Recursively searches for UITabBarController in view controller hierarchy
    private func findTabBarControllerInView(_ viewController: UIViewController?) -> UITabBarController? {
        guard let viewController = viewController else { return nil }

        if let tabBarController = viewController as? UITabBarController {
            return tabBarController
        }

        // Check children
        for child in viewController.children {
            if let found = findTabBarControllerInView(child) {
                return found
            }
        }

        // Check presented view controller
        if let presented = viewController.presentedViewController {
            if let found = findTabBarControllerInView(presented) {
                return found
            }
        }

        return nil
    }

    /// Sets or removes the tab bar accessory using public API
    private func setAccessory(on tabBarController: UITabBarController) {
        if #available(iOS 18.0, *) {
            if isEnabled {
                // Create or update the hosting controller
                if hostingController == nil {
                    hostingController = UIHostingController(rootView: accessoryContent())
                    hostingController?.view.backgroundColor = .clear
                } else {
                    hostingController?.rootView = accessoryContent()
                }

                // Create the accessory with the hosting controller's view
                if let accessoryView = hostingController?.view {
                    // Configure the accessory
                    let accessory = UITabAccessory(contentView: accessoryView)

                    print("[tab bar] setting accessory: \(accessory)")
                    currentAccessory = accessory
                    tabBarController.setBottomAccessory(accessory, animated: true)
                }
            } else {
                print("[tab bar] removing accessory")
                currentAccessory = nil
                tabBarController.setBottomAccessory(nil, animated: true)
            }
        }
    }

    deinit {
        // Clean up hosting controller
        hostingController?.willMove(toParent: nil)
        hostingController?.view.removeFromSuperview()
        hostingController?.removeFromParent()
    }
}

// MARK: - View Extension

extension View {
    /// Sets a custom bottom accessory on the tab bar with conditional visibility
    ///
    /// Usage:
    /// ```swift
    /// TabView {
    ///     // ... tabs
    /// }
    /// .tabBarAccessory(isEnabled: audioManager.isPlaying) {
    ///     HStack {
    ///         Text("Now Playing")
    ///         Spacer()
    ///         Button("Pause") { }
    ///     }
    ///     .padding()
    ///     .background(.ultraThinMaterial)
    /// }
    /// ```
    ///
    /// - Parameters:
    ///   - isEnabled: Whether the accessory should be visible
    ///   - content: A view builder that creates the accessory content
    /// - Returns: A view with the modifier applied
    func tabBarAccessory<AccessoryContent: View>(
        isEnabled: Bool,
        @ViewBuilder content: @escaping () -> AccessoryContent
    ) -> some View {
        self.modifier(TabBarAccessoryModifier(isEnabled: isEnabled, accessoryContent: content))
    }
}
