package com.example.design_system

import android.annotation.SuppressLint
import android.app.Activity
import android.view.ViewGroup
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.compose.BackHandler
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import com.example.core.model.PrintEntity
import com.example.design_system.util.PspJavaScriptInterface
import com.example.design_system.util.snackbar.SnackbarController
import com.example.design_system.util.snackbar.SnackbarEvent
import kotlinx.coroutines.launch

@SuppressLint("JavascriptInterface")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PspWebView(
    url: String,
    webView: WebView?,
    modifier: Modifier = Modifier,
    onWebView: (WebView) -> Unit,
    onPayClick: (amount: Long, id: String?) -> Unit,
    onUUID: () -> Unit,
    onPrintClick: (printEntities: List<PrintEntity>) -> Unit,
) {

    val canGoBack = remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()
    val context = LocalContext.current
    var lastBackTime by remember { mutableLongStateOf(0L) }
    var isPaymentLaunching by remember { mutableStateOf(false) }

    // Use rememberUpdatedState to ensure the bridge always calls the latest callbacks
    val currentOnPayClick by rememberUpdatedState(onPayClick)
    val currentOnPrintClick by rememberUpdatedState(onPrintClick)
    val currentOnUUID by rememberUpdatedState(onUUID)

    val bridge = remember {
        PspJavaScriptInterface(
            onPayClick = { amount, id -> currentOnPayClick(amount, id) },
            onPrintClick = { entities -> currentOnPrintClick(entities) },
            onUUID = { currentOnUUID() }
        )
    }

    BackHandler {
        if (canGoBack.value) {
            webView?.goBack()
        } else {
            val now = System.currentTimeMillis()
            if (now - lastBackTime < 2000) {
                (context as? Activity)?.finish()
            } else {
                lastBackTime = now
                scope.launch {
                    SnackbarController.sendEvent(
                        SnackbarEvent(
                            message = "Press back again to exit"
                        )
                    )
                }
            }
        }
    }

    AndroidView(
        modifier = modifier,
        factory = { ctx ->
            WebView(ctx).apply {
                layoutParams = ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
                )
                webViewClient = object : WebViewClient() {
                    override fun onPageFinished(view: WebView?, url: String?) {
                        super.onPageFinished(view, url)
                        canGoBack.value = view?.canGoBack() ?: false
                    }
                }

                settings.apply {
                    javaScriptEnabled = true
                    domStorageEnabled = true
                    loadWithOverviewMode = true
                    useWideViewPort = true
                    cacheMode = WebSettings.LOAD_DEFAULT
                    mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW

                    userAgentString =
                        "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 Chrome/120.0 Mobile Safari/537.36"
                }

                addJavascriptInterface(bridge, "NativeBridge")


                loadUrl(url)
                onWebView(this)
            }
        },
        update = { view ->
            onWebView(view)
        }
    )

}
