package com.tencent.qian.webview.permission

import android.app.Activity
import android.content.pm.PackageManager
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment

/**
 * 运行时权限申请器(基于 ActivityResultContracts.RequestMultiplePermissions)。
 *
 * **使用方式**:
 * - SDK 内置的 [com.tencent.qian.webview.TencentQianWebViewActivity] 在 `onCreate` 之前注册
 * - 配置模式下,客户在自己 Activity / Fragment 的初始化阶段调 [register]
 *
 * **API 设计**:
 * - 注册返回的 launcher 由调用方持有引用,launch 时传 [Callback]
 * - **不**使用 suspend(避免强制依赖 kotlinx.coroutines)
 *
 * **关键约束(AndroidX)**:`registerForActivityResult` 必须在 `Activity#onCreate` /
 * `Fragment#onAttach` 之前调用,否则抛 `IllegalStateException`。
 */
public class RuntimePermissionRequester private constructor(
    private val launcher: ActivityResultLauncher<Array<String>>,
    private val state: State
) {

    private class State {
        var pending: Callback? = null
    }

    public fun interface Callback {
        public fun onResult(grantResults: Map<String, Boolean>)
    }

    /** 同步检查权限是否已授予。 */
    public fun isGranted(activity: Activity, permission: String): Boolean {
        return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 发起申请。如已全部 granted,直接同步回调。
     */
    public fun request(activity: Activity, permissions: Array<String>, callback: Callback) {
        val all = permissions.all { isGranted(activity, it) }
        if (all) {
            callback.onResult(permissions.associateWith { true })
            return
        }
        state.pending = callback
        launcher.launch(permissions)
    }

    public companion object {

        /**
         * 在 [activity] 的 `onCreate` 之前注册,返回可复用 requester。
         */
        @JvmStatic
        public fun register(activity: ComponentActivity): RuntimePermissionRequester {
            val state = State()
            val launcher = activity.registerForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { grants ->
                state.pending?.onResult(grants)
                state.pending = null
            }
            return RuntimePermissionRequester(launcher, state)
        }

        /** Fragment 重载。 */
        @JvmStatic
        public fun register(fragment: Fragment): RuntimePermissionRequester {
            val state = State()
            val launcher = fragment.registerForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { grants ->
                state.pending?.onResult(grants)
                state.pending = null
            }
            return RuntimePermissionRequester(launcher, state)
        }
    }
}
