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: Any] = [:]
    private var isRegistered: Bool = false
    public weak var eventEmitter: RCTEventEmitter?
    
    public override init() {
        super.init()
    }
    
    // MARK: - Module Registration
    
    /**
     * Registers an array of Brick modules (Swift API)
     * Each module must implement BrickModuleBase and its respective TypeModule protocol
     * This should be called once during app initialization
     */
    public func register(_ modules: [BrickModuleBase]) {
        guard !isRegistered else {
            print("⚠️ BrickModuleRegistry: Modules already registered. Skipping re-registration.")
            return
        }
        
        for module in modules {
            registerSingleModule(module)
        }
        
        isRegistered = true
        print("✅ BrickModuleRegistry: Successfully registered \(self.modules.count) modules")

        if ProcessInfo.processInfo.environment["GRANITE_DEBUG"] == "1" {
            debugPrintRegisteredModules()
        }
    }
    
    /**
     * 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
        }
        
        // Check for module name conflicts
        if modules.keys.contains(moduleName) {
            print("⚠️ BrickModuleRegistry: Module '\(moduleName)' is already registered. Skipping.")
            return
        }
        
        // Register the module
        modules[moduleName] = module
        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]
    }
    
    /**
     * Returns list of registered module names
     */
    @objc public func getRegisteredModules() -> [String] {
        return Array(modules.keys).sorted()
    }
    
    // MARK: - Event Emitter Management
    
    /**
     * Sets the React Native event emitter instance for event emission
     * This should be called during app initialization from the main BrickModule
     */
    @objc public func setEventEmitter(_ eventEmitter: RCTEventEmitter) {
        self.eventEmitter = eventEmitter
        print("📡 BrickModuleRegistry: Event emitter connected for event emission")
    }
    
    /**
     * Returns the React Native event emitter instance for event emission
     * Used by generated module code to emit events to JavaScript
     */
    @objc public func getEventEmitter() -> RCTEventEmitter? {
        return eventEmitter
    }
    
    // MARK: - Debug & Development
    
    private func debugPrintRegisteredModules() {
        print("🔍 BrickModuleRegistry Debug Info:")
        print("  Total Modules: \(modules.count)")
        
        for (moduleName, module) in modules.sorted(by: { $0.key < $1.key }) {
            let moduleType = String(describing: type(of: module))
            print("  📦 \(moduleName) (\(moduleType))")
        }
    }
    
    /**
     * Clears all registered modules (for testing purposes only)
     */
    @objc public func clearRegistry() {
        guard ProcessInfo.processInfo.environment["NODE_ENV"] == "test" ||
              ProcessInfo.processInfo.environment["GRANITE_ALLOW_CLEAR"] == "1" else {
            print("⚠️ BrickModuleRegistry: clearRegistry() is only allowed in test environment")
            return
        }
        
        modules.removeAll()
        isRegistered = false
        
        print("🧹 BrickModuleRegistry: Registry cleared")
    }
}

public class ModuleRegistry {
    
}
