package com.tencent.qian.webview.internal

import android.util.Log
import com.tencent.qian.webview.model.SignCallback
import com.tencent.qian.webview.model.SignResult

/**
 * 进程内全局回调桥(Phase 1 简单实现:单 slot,容器模式同时只允许 1 个签署窗口)。
 *
 * **为什么不走 Intent extras**:
 * - [SignCallback] 是接口(包含 lambda),不能 [java.io.Serializable] / [android.os.Parcelable] 携带
 * - WeakReference 不必要 —— Activity 销毁前会主动 [clear];进程被杀的话回调也无意义
 *
 * **竞态保护**:如果 `put()` 时已有未消费的 callback(说明上一次签署窗口尚未关闭就又发起了新签署),
 * 会先对旧 callback 派发 [SignResult.EMPTY] 并 log warn,避免旧回调永远丢失。
 *
 * **跨端等价**:iOS 走闭包 capture,无此桥。
 */
internal object IntentBridge {

    private const val TAG = "QianIntentBridge"

    @Volatile
    private var pendingCallback: SignCallback? = null

    @Volatile
    private var pendingConfig: com.tencent.qian.webview.model.TencentQianWebViewConfig? = null

    fun put(
        callback: SignCallback?,
        config: com.tencent.qian.webview.model.TencentQianWebViewConfig
    ) {
        // 竞态保护:旧 callback 未消费时,先派发空结果释放调用方
        val prev = pendingCallback
        if (prev != null) {
            Log.w(TAG, "put() called while previous callback is still pending. " +
                "Dispatching empty result to previous callback to prevent leak.")
            try {
                prev.onSignResult(SignResult.EMPTY)
            } catch (e: Exception) {
                Log.w(TAG, "Error dispatching empty result to previous callback", e)
            }
        }
        pendingCallback = callback
        pendingConfig = config
    }

    fun takeCallback(): SignCallback? {
        val cb = pendingCallback
        pendingCallback = null
        return cb
    }

    fun takeConfig(): com.tencent.qian.webview.model.TencentQianWebViewConfig {
        val cfg = pendingConfig ?: com.tencent.qian.webview.model.TencentQianWebViewConfig.DEFAULT
        pendingConfig = null
        return cfg
    }

    fun clear() {
        pendingCallback = null
        pendingConfig = null
    }

    /** 当前是否有未消费的 callback(用于外部防抖判断)。 */
    val hasPending: Boolean get() = pendingCallback != null
}
