package com.za.ui.h5

import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.view.ViewGroup
import android.webkit.JavascriptInterface
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.blankj.utilcode.util.ToastUtils
import com.tencent.smtt.sdk.WebChromeClient
import com.tencent.smtt.sdk.WebSettings
import com.tencent.smtt.sdk.WebView
import com.tencent.smtt.sdk.WebView.setWebContentsDebuggingEnabled
import com.tencent.smtt.sdk.WebViewClient
import com.za.base.AppConfig
import com.za.base.BaseActivity
import com.za.base.view.HeadView
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.ext.finish

class CommonH5Activity : BaseActivity() {
	private var webView : WebView? = null
	private var isDestroyed = false

	@Composable
	override fun ContentView() {
		val url = intent.getStringExtra(EXTRA_URL)
		val title = intent.getStringExtra(EXTRA_TITLE)
		val isCanBack = intent.getBooleanExtra(EXTRA_CAN_BACK, true)

		if (url.isNullOrBlank()) {
			ToastUtils.showLong("无效的URL")
			finish()
			return
		}

		CommonH5Screen(url = url,
			title = title ?: "",
			isCanBack = isCanBack,
			onWebViewCreated = { web ->
				if (! isDestroyed) {
					webView = web
					setupJavascriptInterface(web)
				}
			})
	}

	private fun setupJavascriptInterface(webView : WebView) {
		webView.addJavascriptInterface(JavaScriptInterface(), "android")
	}

	private inner class JavaScriptInterface {
		@JavascriptInterface
		fun sendMessage(message : String) {
			LogUtil.print("commonH5 message", message)
			runOnUiThread {
				handleJavascriptMessage(message)
			}
		}
	}

	private fun handleJavascriptMessage(message : String) {
		if (isDestroyed) return
		when {
			message == "goBack" -> finish()
			message.contains("articleId") -> handleArticleId(message)
		}
	}

	private fun handleArticleId(message : String) {
		val id = message.split("=").lastOrNull()?.takeIf { it.isNotEmpty() } ?: run {
			LogUtil.print("articleId error", "Invalid article ID format")
			return
		}

		val url = buildTrainingUrl(id)
		webView?.loadUrl(url) //		goH5Activity(this, url, title = "")
	}

	private fun buildTrainingUrl(articleId : String) = buildString {
		append(AppConfig.Resource_URL)
		append("/training/training.html")
		append("?id=").append(articleId)
		append("&source=driverApp")
		append("&driverId=").append(GlobalData.driverInfoBean?.userId)
		append("&userId=").append(GlobalData.driverInfoBean?.userId)
	}

	override fun onDestroy() {
		isDestroyed = true
		cleanupWebView()
		super.onDestroy()
	}

	private fun cleanupWebView() {
		webView?.apply {
			loadDataWithBaseURL(null, "", "text/html", "utf-8", null)
			clearHistory()
			clearCache(true)
			(parent as? ViewGroup)?.removeView(this)
			webChromeClient = null
			webViewClient = null
			destroy()
		}
		webView = null
	}

	companion object {
		private const val EXTRA_URL = "url"
		private const val EXTRA_TITLE = "title"
		private const val EXTRA_CAN_BACK = "isCanBack"
		private const val DEFAULT_TIMEOUT = 15000

		fun goH5Activity(context : Context,
			url : String?,
			title : String,
			isCanBack : Boolean = true) {
			if (url.isNullOrBlank()) {
				ToastUtils.showLong("路径为空！！")
				return
			}
			val intent = Intent(context, CommonH5Activity::class.java).apply {
				flags = Intent.FLAG_ACTIVITY_NEW_TASK
				putExtra(EXTRA_URL, url)
				putExtra(EXTRA_TITLE, title)
				putExtra(EXTRA_CAN_BACK, isCanBack)
			}
			context.startActivity(intent)
		}
	}
}

@Composable
private fun CommonH5Screen(url : String,
	title : String,
	isCanBack : Boolean,
	onWebViewCreated : (WebView) -> Unit) {
	val context = LocalContext.current
	var progress by remember { mutableFloatStateOf(0f) }
	var isError by remember { mutableStateOf(false) }
	var webView by remember { mutableStateOf<WebView?>(null) }

	BackHandler(enabled = isCanBack || webView?.canGoBack() == true) {
		handleBackPress(context, webView)
	}

	Scaffold(topBar = {
		if (title.isNotBlank()) {
			HeadView(title = title, onBack = { handleBackPress(context, webView) })
		}
	}) { paddingValues ->
		Box(modifier = Modifier
			.fillMaxSize()
			.padding(paddingValues)) {
			AndroidView(modifier = Modifier.fillMaxSize(), factory = { ctx ->
				WebView(ctx).apply {
					setupWebView(this, context)
					setupWebViewClients(webView = this,
						onProgressChanged = { progress = it / 100f },
						onError = { _, desc ->
							isError = true
							ToastUtils.showLong("加载失败：$desc")
						})
					webView = this
					onWebViewCreated(this)
					loadUrl(url)
				}
			})

			if (progress < 1f && ! isError) {
				LinearProgressIndicator(progress = { progress },
					modifier = Modifier
						.fillMaxWidth()
						.height(2.dp))
			}
		}
	}
}

private fun setupWebViewClients(webView : WebView,
	onProgressChanged : (Int) -> Unit,
	onError : (Int, String?) -> Unit) {
	webView.webChromeClient = object : WebChromeClient() {
		override fun onProgressChanged(view : WebView?, newProgress : Int) {
			onProgressChanged(newProgress)
		}
	}

	webView.webViewClient = object : WebViewClient() {
		override fun onReceivedError(view : WebView?,
			errorCode : Int,
			description : String?,
			failingUrl : String?) {
			onError(errorCode, description)
		}

		override fun onPageFinished(view : WebView?, url : String?) {
			super.onPageFinished(view, url)
			view?.settings?.blockNetworkImage = false
		}

		override fun shouldOverrideUrlLoading(p0 : WebView?, p1 : String?) : Boolean {
			p0?.loadUrl(p1)
			return false
		}
	}
}

private fun setupWebView(webView : WebView, context : Context) {
	webView.settings.apply {
		javaScriptEnabled = true
		domStorageEnabled = true
		allowFileAccess = true

		setAppCacheEnabled(true)
		setAppCacheMaxSize(Long.MAX_VALUE)
		setAppCachePath(context.getDir("appcache", 0).path)
		cacheMode = WebSettings.LOAD_DEFAULT

		layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
		useWideViewPort = true
		loadWithOverviewMode = true
		defaultFontSize = 16
		defaultTextEncodingName = "utf-8"

		setSupportZoom(true)
		builtInZoomControls = true
		displayZoomControls = false

		blockNetworkImage = true
		mixedContentMode = 0

		setSupportMultipleWindows(false)
		setGeolocationEnabled(true)
		databasePath = context.getDir("databases", 0).path

		setWebContentsDebuggingEnabled(! AppConfig.isRelease)
	}

	webView.setBackgroundColor(Color.TRANSPARENT)
}

private fun handleBackPress(context : Context, webView : WebView?) {
	if (webView?.canGoBack() == true) {
		webView.goBack()
	} else {
		context.finish()
	}
}