package com.narutohuo.xindazhou.common.bridge

import com.narutohuo.xindazhou.core.log.ILog
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList

/**
 * 桥接服务管理器
 * 
 * 业务层封装，提供便捷的桥接服务调用方式
 * 直接实现 H5 通信和模块间通信功能
 * 
 * 使用方式：
 * ```kotlin
 * // H5通信
 * BridgeManager.callH5Method("showToast", "Hello")
 * BridgeManager.onH5Call("getUserInfo") { result ->
 *     // 处理结果
 * }
 * 
 * // 模块间通信
 * BridgeManager.postEvent("user_login", userData)
 * BridgeManager.subscribeEvent("user_logout") { data ->
 *     // 处理事件
 * }
 * ```
 */
object BridgeManager {
    
    private const val TAG = "BridgeManager"
    
    // H5 方法回调存储
    private val h5Callbacks = ConcurrentHashMap<String, (String) -> Unit>()
    
    // 事件订阅者存储
    private val eventSubscribers = ConcurrentHashMap<String, CopyOnWriteArrayList<(Any?) -> Unit>>()
    
    // H5 调用原生方法的回调（由外部设置，比如 WebView 的 JavaScriptInterface）
    private var h5CallNativeCallback: ((String, String) -> Unit)? = null
    
    /**
     * 设置 H5 调用原生方法的回调
     * 在 WebView 的 JavaScriptInterface 中调用此方法注册回调
     * 
     * @param callback 回调函数（method: 方法名, params: 参数）
     */
    fun setH5CallNativeCallback(callback: (String, String) -> Unit) {
        h5CallNativeCallback = callback
    }
    
    /**
     * 调用 H5 方法
     * 需要在 WebView 的 JavaScriptInterface 中实现对应的方法
     * 
     * @param method 方法名
     * @param params 参数（JSON 字符串）
     */
    fun callH5Method(method: String, params: String = "{}") {
        // 这里需要由外部实现（比如在 WebView 的 JavaScriptInterface 中）
        // 可以通过回调或者事件通知外部执行
        ILog.d(TAG, "callH5Method: $method, params: $params")
        // 实际实现需要在 WebView 的 JavaScriptInterface 中调用
        // 可以通过 postEvent 通知，或者设置回调
    }
    
    /**
     * 监听 H5 调用原生方法
     * 
     * @param method 方法名
     * @param callback 回调函数
     */
    fun onH5Call(method: String, callback: (String) -> Unit) {
        h5Callbacks[method] = callback
    }
    
    /**
     * 处理 H5 调用原生方法（由 WebView 的 JavaScriptInterface 调用）
     * 
     * @param method 方法名
     * @param params 参数（JSON 字符串）
     */
    fun handleH5Call(method: String, params: String) {
        h5Callbacks[method]?.invoke(params) ?: run {
            ILog.w(TAG, "未注册的 H5 方法调用: $method")
        }
    }
    
    /**
     * 发送事件（模块间通信）
     * 
     * @param event 事件名
     * @param data 事件数据
     */
    fun postEvent(event: String, data: Any? = null) {
        val subscribers = eventSubscribers[event]
        if (subscribers != null && subscribers.isNotEmpty()) {
            subscribers.forEach { callback ->
                try {
                    callback(data)
                } catch (e: Exception) {
                    ILog.e(TAG, "事件回调执行失败: $event", e)
                }
            }
        } else {
            ILog.d(TAG, "事件无订阅者: $event")
        }
    }
    
    /**
     * 订阅事件（模块间通信）
     * 
     * @param event 事件名
     * @param callback 回调函数
     */
    fun subscribeEvent(event: String, callback: (Any?) -> Unit) {
        eventSubscribers.getOrPut(event) { CopyOnWriteArrayList() }.add(callback)
    }
    
    /**
     * 取消订阅事件
     * 
     * @param event 事件名
     * @param callback 回调函数
     */
    fun unsubscribeEvent(event: String, callback: (Any?) -> Unit) {
        eventSubscribers[event]?.remove(callback)
    }
    
    /**
     * 清除所有事件订阅
     */
    fun clearAllSubscriptions() {
        eventSubscribers.clear()
    }
}

