import Foundation
import React


/**
 * Central registry for all Brick modules
 * Manages module lifecycle and provides simple module storage
 */
@objc public class BrickModuleRegistry: NSObject {
    
    private var modules: [String: BrickModuleBase] = [:]
    private var isRegistered: Bool = false
    public weak var brickTurboModule: NSObject?
    private weak var bridgeProxy: RCTBridgeProxy?;
    // Event map injected from BrickModuleImpl (already converted to Swift types)
    // Nested structure: [ModuleName: [EventName: Handler]]
    private var eventMap: [String: [String: ([String: Any]) -> Void]] = [:]
    
    public override init() {
        super.init()
    }
    
    // MARK: - Module Registration
    
    /**
     * Registers an array of Brick modules (Swift API)
     * Each module must implement BrickModuleBase and its respective Spec protocol
     * This should be called once during app initialization
     */
    public func register(_ modules: [BrickModuleBase]) {
        if isRegistered {
            print("♻️ BrickModuleRegistry: Re-registering modules. Existing modules may be overwritten.")
        }
        
        for module in modules {
            registerSingleModule(module)
        }
        
        isRegistered = true
        print("✅ BrickModuleRegistry: Successfully registered \(self.modules.count) modules")
    }
    
    /**
     * Registers an array of Brick modules (Objective-C API)
     * Each module must implement BrickModuleBase protocol
     * This should be called once during app initialization
     */
    @objc(registerModules:)
    public func registerModules(_ modules: NSArray) {
        let brickModules = modules.compactMap { $0 as? BrickModuleBase }
        register(brickModules)
    }
    
    private func registerSingleModule(_ module: BrickModuleBase) {
        let moduleName = module.moduleName
        
        // Validate module name
        guard !moduleName.isEmpty else {
            print("❌ BrickModuleRegistry: Module has empty moduleName")
            return
        }
        
        // Register the module
        modules[moduleName] = module
        modules[moduleName]?.bridgeProxy = self.bridgeProxy;
        modules[moduleName]?.registry = self
        print("📦 BrickModuleRegistry: Registered module '\(moduleName)'")
    }
    
    // MARK: - Module Information
    
    /**
     * Returns the actual module instance for reflection-based method calls
     * Used by BrickModuleImpl for direct protocol casting
     */
    public func getModuleInstance(_ moduleName: String) -> Any? {
        return modules[moduleName]
    }
    
    
    public func setBridge(_ bridge: Any) {
        self.bridgeProxy = bridge as? RCTBridgeProxy;
        for module in modules {
            module.value.bridgeProxy = self.bridgeProxy;
        }
    }
    
    // Receives event map from BrickModuleImpl (already converted to Swift types)
    public func setEventMap(_ map: [String: [String: ([String: Any]) -> Void]]) {
        self.eventMap = map
    }

    // Emit event by module+event via typed block
    @objc public func emitEvent(module: String, event: String, payload: [String: Any]) {
        // Direct lookup without string manipulation
        if let moduleEvents = eventMap[module],
           let handler = moduleEvents[event] {
            handler(payload)
        } else {
            print("⚠️ BrickModuleRegistry: No handler for module '\(module)' event '\(event)'")
        }
    }
    
    /**
     * Returns list of registered module names
     */
    @objc public func getRegisteredModules() -> [String] {
        return Array(modules.keys).sorted()
    }
    
    // MARK: - Event Emitter Management removed (CodegenTypes.EventEmitter is used)
        
    /**
     * Unregisters all modules and clears their registry references
     */
    @objc public func unregister() {
        modules.removeAll()
        isRegistered = false
    }
    
    /**
     * Clears all registered modules (for testing purposes only)
     */
    @objc public func clearRegistry() {
        unregister()
    }
}
