package com.example.stage_app.screen

import android.util.Log
import android.webkit.WebView
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import kotlinx.coroutines.launch
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.core.getAndroidId
import com.example.core.getDeviceName
import com.example.design_system.PspWebView
import com.example.stage_app.viewmodel.StageViewModel

private const val tisWebUrl = "http://192.168.128.73:5000"
private const val stageWebViewTag = "StageWebViewScreen"

@Composable
fun StageWebViewScreen(
    modifier: Modifier = Modifier,
    viewModel: StageViewModel = hiltViewModel()
) {

    val context = LocalContext.current
    var webView: WebView? by remember { mutableStateOf(null) }
    var currentPaymentId by rememberSaveable { mutableStateOf<String?>(null) }
    var isPaymentProcessing by rememberSaveable { mutableStateOf(false) }
    var isPrinting by rememberSaveable { mutableStateOf(false) }
    var initialCallbackSent by rememberSaveable { mutableStateOf(false) }
    val coroutineScope = rememberCoroutineScope()
    val deviceInfo by remember {
        mutableStateOf(
            viewModel.deviceInfoJson(
                androidId = getAndroidId(context),
                getDeviceName()
            )
        )
    }

    // launcher to handle POS app result
    val posLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) { result ->
        val paymentResultEntity = viewModel.paymentResult(
            id = currentPaymentId,
            activityResult = result
        )
        val jsResult = viewModel.postPaymentResult(paymentResultEntity)
        val currentWebView = webView
        if (currentWebView == null) {
            Log.w(stageWebViewTag, "Skipping onPaymentResult JS callback: WebView is not ready yet.")
        } else {
            currentWebView.post {
                currentWebView.evaluateJavascript(jsResult, null)
            }
        }
        isPaymentProcessing = false
    }



    PspWebView(
        url = tisWebUrl,
        modifier = modifier,
        onPayClick = { amount: Long, id: String? ->
            if (isPaymentProcessing) return@PspWebView
            isPaymentProcessing = true
            currentPaymentId = id
            viewModel.pay(amount)
                .also(posLauncher::launch)
        },
        onPrintClick = { printEntities ->
            if (isPrinting) return@PspWebView
            isPrinting = true
            coroutineScope.launch {
                try {
                    viewModel.print(printEntities)
                } finally {
                    isPrinting = false
                }
            }
        },
        onDeviceInfo = {
            deviceInfo
        },
        onWebViewReady = { readyWebView ->
            webView = readyWebView
        },
        onPageFinished = { loadedWebView ->
            if (!initialCallbackSent) {
                loadedWebView.evaluateJavascript(viewModel.postPaymentResult(null), null)
                initialCallbackSent = true
            }
        }
    )
}
