package com.clx.account_center;

import android.Manifest
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Activity
import android.app.AlertDialog
import android.app.DownloadManager
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.media.MediaScannerConnection
import android.net.Uri
import android.net.http.SslError
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.provider.Settings
import android.text.TextUtils
import android.util.Base64
import android.util.Log
import android.webkit.JavascriptInterface
import android.webkit.JsPromptResult
import android.webkit.JsResult
import android.webkit.PermissionRequest
import android.webkit.SslErrorHandler
import android.webkit.URLUtil
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.clx.account_center.WBH5FaceVerifySDK.VIDEO_REQUEST
import com.clx.account_center.databinding.H5ActivityBinding
import org.json.JSONException
import org.json.JSONObject
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.UnsupportedEncodingException
import java.net.URLDecoder


class H5Activity  : ComponentActivity() {

    companion object{
        const val PERMISSION_QUEST_TRTC_CAMERA_VERIFY = 12 //腾讯 trtc模式的权限申请
        const val PERMISSION_QUEST_OLD_CAMERA_VERIFY = 11 //腾讯 录制模式的权限申请
        const val REQUEST_PERMISSION_STORAGE: Int = 0x00  //请求存储权限场景
        const val FILE_CHOOSER_RESULT_CODE = 10000  //上传文件场景
        const val RECORD_VIDEO_REQUEST_CODE = 2002  //快捷 录制视频场景

        //实名scheme
        const val SCHEMA_REAL: String = "esign://demo/realBack"
        //签署scheme
        const val SCHEMA_SIGN: String = "esign://demo/signBack"

        const val PERMISSION_REQUEST_STORAGE = 2003
    }

    private lateinit var binding : H5ActivityBinding
    private var belowApi21 = false // android 5.0以下系统
    private var webChromeClient: H5FaceWebChromeClient? = null

    //上传文件需要的回调
    var uploadMessage: ValueCallback<Uri>? = null
    var uploadMessageAboveL: ValueCallback<Array<Uri>>? = null

    private var curUrl:String?  = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = H5ActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //配置webview
        initWebView()

        //处理传进来的url
        processExtraData()
        binding.btnFinish.setOnClickListener{
            finish()
            return@setOnClickListener
        }
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
        processExtraData()
    }

    //处理首次进入和支付宝返回场景逻辑
    private fun processExtraData() {
        val intent = intent
        val uri = intent.data
        //支付宝返回
        if (uri != null) {
            val callbackUrl = uri.getQueryParameter("realnameUrl")
            LogUtil.e("$callbackUrl")
            if (!TextUtils.isEmpty(callbackUrl)) {
                if (callbackUrl?.startsWith("http") == true || callbackUrl?.startsWith("https") == true) {
                    try {
                        binding.webview?.loadUrl(URLDecoder.decode(callbackUrl, "utf-8"))
                    } catch (e: UnsupportedEncodingException) {
                        e.printStackTrace()
                    }
                }else{
                    //api自己查询结果
                    Toast.makeText(this@H5Activity, "认证完成请调用接口查询结果", Toast.LENGTH_LONG).show()
                    finish()
                }
            }
        } else {
            //正常加载url
            val url = intent.getStringExtra("url")
            LogUtil.e(url)
            //alipays开头的 唤起支付宝
            if (url?.startsWith("alipays") == true) {
                try {
                    val intent2 = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                    startActivity(intent2)
                    return
                } catch (e: Exception) {
                }
            }
            //正常加载流程
            curUrl = url
            url?.let {
                binding.webview?.loadUrl(it)
            }
        }
    }

    override fun onPause() {
        super.onPause()
        binding.webview?.onPause()
    }

    override fun onResume() {
        super.onResume()
        binding.webview?.onResume()
    }

    override fun onStop() {
        super.onStop()
        binding.webview.stopLoading()
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            binding.webview?.removeAllViews()
            binding.webview?.destroy()
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }

        if (dialog?.isShowing == true) {
            dialog?.dismiss()
        }
        dialog = null
    }


    @SuppressLint("SetJavaScriptEnabled")
    private fun initWebView(){
        //webview配置
        WBH5FaceVerifySDK.getInstance().setWebViewSettings(binding.webview,this)

        binding.webview.webViewClient = object : WebViewClient(){

            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                return processUrlLoading(view,url)
            }

            @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
            override fun shouldOverrideUrlLoading(
                view: WebView?,
                request: WebResourceRequest?
            ): Boolean {
                var url = request?.url?.toString()
                return processUrlLoading(view,url)
            }

            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                injectBlobDownloadHandler()
            }

            private fun injectBlobDownloadHandler() {
                val jsCode = """
            (function() {
                var originalClick = HTMLElement.prototype.click;
                HTMLElement.prototype.click = function() {
                    if (this.tagName === 'A' && this.href.startsWith('blob:')) {
                        var url = this.href;
                        var fileName = this.download || 'file_' + Date.now();
                        fetch(url).then(res => res.blob()).then(blob => {
                            var reader = new FileReader();
                            reader.onload = function() {
                                var base64 = reader.result.split(',')[1];
                                Android.downloadBlob(base64, fileName, blob.type);
                            };
                            reader.readAsDataURL(blob);
                        });
                        return false;
                    }
                    return originalClick.apply(this, arguments);
                };
            })();
        """.trimIndent()
                binding.webview.evaluateJavascript(jsCode, null)
            }

            override fun onReceivedError(
                view: WebView?,
                request: WebResourceRequest?,
                error: WebResourceError?
            ) {
                super.onReceivedError(view, request, error)
            }

            override fun onReceivedSslError(
                view: WebView?,
                handler: SslErrorHandler?,
                error: SslError?
            ) {
                super.onReceivedSslError(view, handler, error)
            }
        }

        webChromeClient = H5FaceWebChromeClient(this);
        binding.webview.webChromeClient = webChromeClient
        binding.webview.addJavascriptInterface( WebAppInterface(), "H5CallFlutterInterface")
        // 注册Java与JS的通信桥梁
        binding.webview.addJavascriptInterface(WebAppInterface(), "Android")
        // 添加下载监听
        binding.webview.setDownloadListener { url, userAgent, contentDisposition, mimeType, contentLength ->
            if (url.startsWith("blob:")) {
            } else {
                // 普通HTTP下载逻辑
                handleDownload(url, userAgent, contentDisposition, mimeType)
            }

        }
    }


    //拦截处理地址逻辑
    private fun processUrlLoading(view: WebView?,url: String?): Boolean {
        if (url == null) {
            return false
        }

        val uri = Uri.parse(url)
        LogUtil.e("要加载的地址:" + uri.scheme + " " + url + " ")

        if (uri.scheme == "http" || uri.scheme == "https") {
            view?.loadUrl(url)
            return true
        } else if (url.startsWith(SCHEMA_REAL)) {
            //esign://demo/realBack?status=true&authFlowId=OF-2ecd9c5e3408000d&lang=zh-CN

            //实名结果
            val status = uri.getBooleanQueryParameter("status", false)
            if (status) {
                //认证成功返回
                Toast.makeText(this@H5Activity, "认证成功", Toast.LENGTH_LONG).show()
                finish()
            }

            return true
        } else if (url.startsWith(SCHEMA_SIGN)) {
            // esign://demo/signBack?tsignType=SIGN&tsignCode=0&tsignDes=%E7%AD%BE%E7%BD%B2%E6%88%90%E5%8A%9F  签署结果
            if (url.contains("signResult")) {
                val signResult = uri.getBooleanQueryParameter("signResult", false)
                Toast.makeText(
                    this@H5Activity,
                    "签署结果：  signResult = $signResult",
                    Toast.LENGTH_LONG
                ).show()
            } else if (url.contains("tsignCode")){
                var tsignCode = uri.getQueryParameter("tsignCode")
                tsignCode = if ("0" == tsignCode) {
                    "签署成功"
                } else {
                    "签署失败"
                }
                Toast.makeText(this@H5Activity, "签署结果： $tsignCode", Toast.LENGTH_LONG).show()
            }
            finish()
            return true
        } else if (uri.scheme == "alipays") {
            // 跳转到支付宝刷脸
            // alipays://platformapi/startapp?appId=20000067&pd=NO&url=https%3A%2F%2Fzmcustprod.zmxy.com.cn%2Fcertify%2Fbegin.htm%3Ftoken%3DZM201811133000000050500431389414
            try {
                val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                startActivity(intent)
                return true
            } catch (e: java.lang.Exception) {
                return false
            }
        } else {
            return false
        }

    }

    //处理各种上传文件取消或者权限取消事件

    private fun onPermissionCancel() {
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
            return
        }

        if (null == uploadMessage && null == uploadMessageAboveL) {
            return
        }
        if (uploadMessage != null) {
            uploadMessage?.onReceiveValue(null)
            uploadMessage = null
        }
        if (uploadMessageAboveL != null) {
            uploadMessageAboveL?.onReceiveValue(null)
            uploadMessageAboveL = null
        }

        if (uploadMessageAboveL != null) {
            uploadMessageAboveL?.onReceiveValue(
                WebChromeClient.FileChooserParams.parseResult(
                    -1,
                    null
                )
            )
            uploadMessageAboveL = null
        } else if (uploadMessage != null) {
            uploadMessage?.onReceiveValue(null)
            uploadMessage = null
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private fun onActivityResultAboveL2(requestCode: Int, resultCode: Int, intent: Intent?) {
        if (uploadMessageAboveL == null) {
            return
        }
        var results: Array<Uri>? = null
        if (resultCode == Activity.RESULT_OK) {
            if (intent != null) {
                val dataString = intent.dataString
                val clipData = intent.clipData
                if (clipData != null) {
                    results = Array(clipData.itemCount){
                            i -> clipData.getItemAt(i).uri
                    }
                }
                if (dataString != null)
                    results = arrayOf(Uri.parse(dataString))
            }
        }
        uploadMessageAboveL?.onReceiveValue(results)
        uploadMessageAboveL = null
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        LogUtil.e( "onActivityResult --------$requestCode")
        super.onActivityResult(requestCode, resultCode, data)

        //取消等异常场景处理
        if (resultCode != RESULT_OK || data == null || data.data == null) {
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            onPermissionCancel()
            return
        }

        if (requestCode == VIDEO_REQUEST) { //收到录制模式调用系统相机录制完成视频的结果
            if (WBH5FaceVerifySDK.getInstance()
                    .receiveH5FaceVerifyResult(requestCode, resultCode, data)
            ) {
                return
            }
        } else if (requestCode == PERMISSION_QUEST_TRTC_CAMERA_VERIFY) {
            requestCameraPermission(true, belowApi21)
        } else if (requestCode == PERMISSION_QUEST_OLD_CAMERA_VERIFY) {
            requestCameraPermission(false, belowApi21)
        }else if (requestCode == FILE_CHOOSER_RESULT_CODE) { //
            if (null == uploadMessage && null == uploadMessageAboveL) {
                return
            }
            val result = if (data == null || resultCode != RESULT_OK) null else data.data
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL2(requestCode, resultCode, data)
            } else if (uploadMessage != null) {
                uploadMessage?.onReceiveValue(result)
                uploadMessage = null
            }
        }else if (requestCode == RECORD_VIDEO_REQUEST_CODE){
            val uris = data?.data?.let { arrayOf(it) }
            uploadMessageAboveL?.onReceiveValue(uris)

        }
    }

    /**
     * 针对trtc录制模式，申请相机权限
     */
    private fun requestCameraPermission(trtc: Boolean, belowApi21: Boolean) {
        this.belowApi21 = belowApi21
        if (checkSdkPermission(android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            LogUtil.e( "checkSelfPermission false")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  //23+的情况
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        this@H5Activity,
                        android.Manifest.permission.CAMERA
                    )
                ) {
                    //用户之前拒绝过，这里返回true
                    LogUtil.e( "shouldShowRequestPermissionRationale true")
                    if (trtc) {
                        ActivityCompat.requestPermissions(
                            this,
                            arrayOf<String>(android.Manifest.permission.CAMERA),
                            PERMISSION_QUEST_TRTC_CAMERA_VERIFY
                        )
                    } else {
                        ActivityCompat.requestPermissions(
                            this,
                            arrayOf<String>(android.Manifest.permission.CAMERA),
                            PERMISSION_QUEST_OLD_CAMERA_VERIFY
                        )
                    }
                } else {
                    LogUtil.e( "shouldShowRequestPermissionRationale false")
                    if (trtc) {
                        ActivityCompat.requestPermissions(
                            this,
                            arrayOf<String>(android.Manifest.permission.CAMERA),
                            PERMISSION_QUEST_TRTC_CAMERA_VERIFY
                        )
                    } else {
                        ActivityCompat.requestPermissions(
                            this,
                            arrayOf<String>(android.Manifest.permission.CAMERA),
                            PERMISSION_QUEST_OLD_CAMERA_VERIFY
                        )
                    }
                }
            } else {
                if (trtc) {
                    //23以下没法系统弹窗动态申请权限，只能用户跳转设置页面，自己打开
                    openAppDetail(PERMISSION_QUEST_TRTC_CAMERA_VERIFY)
                } else {
                    //23以下没法系统弹窗动态申请权限，只能用户跳转设置页面，自己打开
                    openAppDetail(PERMISSION_QUEST_OLD_CAMERA_VERIFY)
                }
            }
        } else {
            LogUtil.e( "checkSelfPermission true")
            if (trtc) {
                webChromeClient?.enterTrtcFaceVerify()
            } else {
                webChromeClient?.enterOldModeFaceVerify(belowApi21)
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        onPermissionCancel()
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            PERMISSION_QUEST_TRTC_CAMERA_VERIFY -> if (grantResults.isNotEmpty()) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    LogUtil.e( "onRequestPermissionsResult grant")
                    LogUtil.e("$webChromeClient")
                    webChromeClient?.enterTrtcFaceVerify()
                } else if (grantResults[0] == PackageManager.PERMISSION_DENIED && !ActivityCompat.shouldShowRequestPermissionRationale(
                        this,
                        android.Manifest.permission.CAMERA
                    )
                ) {
                    LogUtil.e( "onRequestPermissionsResult deny")
                    openAppDetail(PERMISSION_QUEST_TRTC_CAMERA_VERIFY)
                } else {
                    LogUtil.e( "拒绝权限并且之前没有点击不再提醒")
                    //权限被拒绝
                    askPermissionError()
                }
            }

            PERMISSION_QUEST_OLD_CAMERA_VERIFY -> if (grantResults.size > 0) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    LogUtil.e( "PERMISSION_QUEST_CAMERA_RECORD_VERIFY GRANTED ")
                    webChromeClient?.enterOldModeFaceVerify(belowApi21)
                } else {
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(
                            this,
                            android.Manifest.permission.CAMERA
                        )
                    ) {
                        Toast.makeText(
                            this@H5Activity,
                            "请前往设置->应用->权限中打开相机权限，否则功能无法正常运行",
                            Toast.LENGTH_LONG
                        ).show()
                        //权限被拒绝
                        openAppDetail(PERMISSION_QUEST_OLD_CAMERA_VERIFY)
                    } else {
                        LogUtil.e( "onRequestPermissionsResult  camera deny")
                        askPermissionError()
                    }
                }
            }
            PERMISSION_REQUEST_STORAGE -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 重新触发下载
                    binding.webview.reload()
                } else {
                    Toast.makeText(
                        this,
                        "需要存储权限才能下载文件",
                        Toast.LENGTH_LONG
                    ).show()
                }
            }
        }
    }

    private fun openAppDetail(requestCode: Int) {
        showWarningDialog(requestCode)
    }


    private fun enterSettingActivity(requestCode: Int) {
        //部分插件化框架中用Activity.getPackageName拿到的不一定是宿主的包名，所以改用applicationContext获取
        val packageName = applicationContext.packageName
        val uri = Uri.fromParts("package", packageName, null)
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, uri)
        val resolveInfo = packageManager.resolveActivity(intent, 0)
        if (resolveInfo != null) {
            startActivityForResult(intent, requestCode)
        }
    }


    private fun askPermissionError() {
        Toast.makeText(this@H5Activity, "用户拒绝了权限,5秒后按钮可再点击", Toast.LENGTH_SHORT)
            .show()
        WBH5FaceVerifySDK.getInstance().resetReceive()
    }


    private var dialog: AlertDialog? = null

    private fun showWarningDialog(requestCode: Int) {
        dialog = AlertDialog.Builder(this)
            .setTitle("权限申请提示")
            .setMessage("请前往设置->应用->权限中打开相关权限，否则功能无法正常运行！")
            .setPositiveButton(
                "确定"
            ) { _, _ -> // 一般情况下如果用户不授权的话，功能是无法运行的，做退出处理,合作方自己根据自身产品决定是退出还是停留
                if (dialog?.isShowing == true) {
                    dialog?.dismiss()
                }
                dialog = null
                enterSettingActivity(requestCode)
            }.setNegativeButton(
                "取消"
            ) { _, _ ->
                if (dialog?.isShowing == true) {
                    dialog?.dismiss()
                }
                dialog = null
                WBH5FaceVerifySDK.getInstance().resetReceive()
            }.setCancelable(false).show()
    }

    private fun checkSdkPermission(permission: String): Int {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val permissionResult = ContextCompat.checkSelfPermission(this, permission)
            LogUtil.e("checkSdkPermission >=23 $permissionResult permission=$permission")
            return permissionResult
        } else {
            val permissionResult = packageManager.checkPermission(permission, packageName)
            LogUtil.e( "checkSdkPermission <23 =$permissionResult permission=$permission")
            return permissionResult
        }
    }

    inner class H5FaceWebChromeClient(private val activity: H5Activity?) : WebChromeClient() {
        private var request: PermissionRequest? = null
        private var webView: WebView? = null

        private var acceptType: String? = null
        private var fileChooserParams: FileChooserParams? = null

        override fun onJsPrompt(
            view: WebView,
            url: String,
            message: String,
            defaultValue: String,
            result: JsPromptResult
        ): Boolean {
            return super.onJsPrompt(view, url, message, defaultValue, result)
        }

        override fun onJsConfirm(
            view: WebView,
            url: String,
            message: String,
            result: JsResult
        ): Boolean {
            result.confirm()
            return true
        }


        /**
         * H5_TRTC 刷脸配置，这里负责处理来自H5页面发出的相机权限申请：先申请终端的相机权限，再授权h5请求
         * @param request 来自H5页面的权限请求
         */
        override fun onPermissionRequest(request: PermissionRequest) {
            LogUtil.e( "onPermissionRequest 发起腾讯h5刷脸的相机授权")
            this.request = request
            activity?.requestCameraPermission(trtc = true, belowApi21 = false)
        }

        /**
         * 相机权限申请成功后，拉起TRTC刷脸界面进行实时刷脸验证
         */
        fun enterTrtcFaceVerify() {
            LogUtil.e( "enterTrtcFaceVerify")
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { // android sdk 21以上
                if (request?.origin != null) {
                    request?.grant(request?.resources)
                    request?.origin
                } else {
                    if (request == null) {
                        if (webView?.canGoBack() == true) {
                            webView?.goBack()
                        }
                    }
                }
            }
        }


        // For Android >= 4.1  老的录制模式中，收到h5页面发送的录制请求
        fun openFileChooser(uploadMsg: ValueCallback<Uri>?, acceptType: String, capture: String?) {
            uploadMessage = uploadMsg
            this.acceptType = acceptType
            WBH5FaceVerifySDK.getInstance().setmUploadMessage(uploadMsg)
            activity?.requestCameraPermission(false, true)
        }

        // For Lollipop 5.0+ Devices  老的录制模式中，收到h5页面发送的录制请求
        @TargetApi(21)
        override fun onShowFileChooser(
            webView: WebView,
            filePathCallback: ValueCallback<Array<Uri>>,
            fileChooserParams: FileChooserParams
        ): Boolean {
            this.webView = webView
            uploadMessageAboveL = filePathCallback
            this.fileChooserParams = fileChooserParams

            var hasVideo = false
            for (item in fileChooserParams.acceptTypes){
                if (item.contains("video")){
                    hasVideo = true
                }
            }
            //上传视频场景  腾讯video/kyc 快捷刷脸 video/*
            if (hasVideo){
                WBH5FaceVerifySDK.getInstance().setmUploadCallbackAboveL(filePathCallback)
                if (WBH5FaceVerifySDK.getInstance()
                        .recordVideoForApi21(webView, uploadMessageAboveL, activity, fileChooserParams)
                ) {  //腾讯的h5刷脸
                    return true
                }else{

                    if (ActivityCompat.checkSelfPermission(
                            activity!!,
                            Manifest.permission.CAMERA
                        ) == PackageManager.PERMISSION_GRANTED
                    ) {
                        recordVideo(filePathCallback)
                    } else {
                        if (activity != null) {
                            ActivityCompat.requestPermissions(
                                activity,
                                arrayOf(Manifest.permission.CAMERA),
                                REQUEST_PERMISSION_STORAGE
                            )
                        }
                    }
                }
            }else{
                openFileInput(webView.context)
            }
            return true
        }

        /**
         * 调用系统前置摄像头进行视频录制，需要保证有摄像头权限。
         */
        private fun recordVideo(filePathCallback: ValueCallback<Array<Uri>>?) {
            uploadMessageAboveL = filePathCallback
            try {
                val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.putExtra("android.intent.extras.CAMERA_FACING", 1) // 调用前置摄像头
                startActivityForResult(intent, RECORD_VIDEO_REQUEST_CODE)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        private fun openFileInput(context: Context) {
            val i = Intent(Intent.ACTION_GET_CONTENT)
            i.addCategory(Intent.CATEGORY_OPENABLE)
            i.setType("*/*")
            if (i.resolveActivity(context.packageManager) != null) {
                activity?.startActivityForResult(
                    Intent.createChooser(i, "Image Chooser"),
                    FILE_CHOOSER_RESULT_CODE
                )
            }
//            if (ActivityCompat.checkSelfPermission(
//                    context,
//                    Manifest.permission.READ_EXTERNAL_STORAGE
//                ) == PackageManager.PERMISSION_GRANTED
//            ) {
//                val i = Intent(Intent.ACTION_GET_CONTENT)
//                i.addCategory(Intent.CATEGORY_OPENABLE)
//                i.setType("*/*")
//                if (i.resolveActivity(context.packageManager) != null) {
//                    activity?.startActivityForResult(
//                        Intent.createChooser(i, "Image Chooser"),
//                        FILE_CHOOSER_RESULT_CODE
//                    )
//                }
//            } else {
//                if (activity != null) {
//                    ActivityCompat.requestPermissions(
//                        activity,
//                        arrayOf<String>(Manifest.permission.READ_EXTERNAL_STORAGE),
//                        REQUEST_PERMISSION_STORAGE
//                    )
//                }
//            }
        }

        //老的录制模式中，拉起系统相机进行录制视频
        fun enterOldModeFaceVerify(belowApi21: Boolean): Boolean {
            LogUtil.e( "enterOldFaceVerify")
            if (belowApi21) { // For Android < 5.0
                if (WBH5FaceVerifySDK.getInstance()
                        .recordVideoForApiBelow21(uploadMessage, acceptType, activity)
                ) { //腾讯的h5刷脸
                    return true
                } else {
                    // todo 合作方如果其他的h5页面处理，则再次补充其他页面逻辑
                }
            } else { // For Android >= 5.0
                if (WBH5FaceVerifySDK.getInstance()
                        .recordVideoForApi21(webView, uploadMessageAboveL, activity, fileChooserParams)
                ) {  //腾讯的h5刷脸
                    return true
                } else {
                    // todo 合作方如果其他的h5页面处理，则再次补充其他页面逻辑
                }
            }
            return false
        }
    }
    inner class WebAppInterface() {
        @JavascriptInterface
        fun onDestroy() {
            Log.d("H5Interaction", "收到 H5 的 onDestroy 调用")
           finish()
        }
        @JavascriptInterface
        fun downloadBlob(base64Data: String, fileName: String, mimeType: String) {
            val data = Base64.decode(base64Data, Base64.DEFAULT)
            saveFile(data, fileName, mimeType)
        }

        fun saveToDownloadsLegacy(data: ByteArray, fileName: String, mimeType: String) {
            val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

            try {
                // 1. 创建目标文件
                val targetFile = File(downloadsDir, fileName).apply {
                    if (!exists()) {
                        parentFile?.mkdirs()
                        createNewFile()
                    }
                }

                // 2. 写入文件数据
                FileOutputStream(targetFile).use { fos ->
                    fos.write(data)
                    fos.flush()
                }

                // 3. 更新媒体库（可选）
                MediaScannerConnection.scanFile(
                    this@H5Activity,
                    arrayOf(targetFile.absolutePath),
                    arrayOf(mimeType),
                    null
                )

                showToast("文件保存成功: ${targetFile.absolutePath}")
            } catch (e: IOException) {
                showToast("保存失败: ${e.localizedMessage}")
            }
        }

        @RequiresApi(Build.VERSION_CODES.Q)
        fun saveToDownloadsModern(data: ByteArray, fileName: String, mimeType: String) {
            val resolver = contentResolver
            val values = ContentValues().apply {
                put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
                put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
                put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
            }

            try {
                resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)?.let { uri ->
                    resolver.openOutputStream(uri)?.use { stream ->
                        stream.write(data)
                        showToast("文件保存成功: $fileName")
                    }
                } ?: throw IOException("URI创建失败")
            } catch (e: Exception) {
                showToast("保存失败: ${e.localizedMessage}")
            }
        }

        // 统一调用入口
        private fun saveFile(data: ByteArray, fileName: String, mimeType: String) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                saveToDownloadsModern(data, fileName, mimeType)
            } else {
                // 检查存储权限
                if (ContextCompat.checkSelfPermission(
                        this@H5Activity,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                    ) != PackageManager.PERMISSION_GRANTED
                ) {
                    ActivityCompat.requestPermissions(
                        this@H5Activity,
                        arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                        PERMISSION_REQUEST_STORAGE
                    )
                    return
                }
                saveToDownloadsLegacy(data, fileName, mimeType)
            }
        }
    }

    private fun handleDownload(
        url: String,
        userAgent: String?,
        contentDisposition: String?,
        mimeType: String?
    ) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // 开始下载
            startDownload(url, userAgent, contentDisposition, mimeType)
            return
        }
        // 检查存储权限
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                PERMISSION_REQUEST_STORAGE
            )
            return
        }
        startDownload(url, userAgent, contentDisposition, mimeType)


    }

    private fun startDownload(
        url: String,
        userAgent: String?,
        contentDisposition: String?,
        mimeType: String?
    ) {
        try {
            val request = DownloadManager.Request(Uri.parse(url))
                .setMimeType(mimeType)
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
                .setAllowedOverMetered(true)
                .setAllowedOverRoaming(true)

            // 获取文件名
            val fileName = URLUtil.guessFileName(url, contentDisposition, mimeType)

            // 设置保存路径
            val downloadDir = Environment.DIRECTORY_DOWNLOADS
            request.setDestinationInExternalPublicDir(downloadDir, fileName)

            // 设置描述
            request.setTitle("下载文件")
            request.setDescription("正在下载 $fileName")

            // 获取下载管理器
            val downloadManager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
            downloadManager.enqueue(request)

            Toast.makeText(this, "开始下载：请前往系统下载查看。", Toast.LENGTH_SHORT).show()
        } catch (e: Exception) {
            Toast.makeText(this, "下载失败：${e.message}", Toast.LENGTH_SHORT).show()
            e.printStackTrace()
        }
    }


    private fun showToast(s: String) {
        Toast.makeText(this, s, Toast.LENGTH_SHORT).show()

    }

    // MIME 类型 → 扩展名映射表
    val mimeTypeToExtension = mapOf(
        "image/jpeg" to "jpg",
        "image/png" to "png",
        "application/pdf" to "pdf",
        "text/plain" to "txt",
        "application/zip" to "zip",
        "audio/mpeg" to "mp3",
        "video/mp4" to "mp4",
        "application/vnd.ms-excel" to "xls",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" to "xlsx",
        // 更多类型...
    )

    // 根据 MIME 类型推断扩展名（默认返回 "bin"）
    fun getExtensionFromMimeType(mimeType: String): String {
        return mimeTypeToExtension[mimeType] ?: mimeType.split("/").lastOrNull() ?: "bin"
    }
}





