package com.sample.tabs.kotlin.ui.components

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.webkit.*
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView

@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("SetJavaScriptEnabled")
@Composable
fun FullScreenWebView(
    url: String,
    isConnected: Boolean = true,
    savedState: Bundle? = null,
    onTitleReceived: (String?) -> Unit = {},
    onWebViewCreated: (WebView) -> Unit = {}
) {
    val context = LocalContext.current
    var canGoBack by remember { mutableStateOf(false) }
    var webView: WebView? by remember { mutableStateOf(null) }
    var showNetworkError by remember { mutableStateOf(false) }
    var isLoading by remember { mutableStateOf(true) }
    var isRefreshing by remember { mutableStateOf(false) }

    // Extract main domain from initial URL for error filtering
    val mainDomain = remember(url) {
        try {
            val host = Uri.parse(url)?.host ?: ""
            if (host.matches(Regex("""^\d{1,3}(\.\d{1,3}){3}$"""))) {
                host // IP address - use as-is
            } else {
                val withoutWww = if (host.startsWith("www.")) host.substring(4) else host
                val parts = withoutWww.split(".")
                if (parts.size >= 2) "${parts[parts.size - 2]}.${parts[parts.size - 1]}" else withoutWww
            }
        } catch (e: Exception) { "" }
    }

    // Helper to check if request belongs to main domain
    fun isFromMainDomain(requestUrl: String?): Boolean {
        if (requestUrl.isNullOrBlank() || mainDomain.isBlank()) return false
        return try {
            val requestHost = Uri.parse(requestUrl)?.host ?: return false
            if (requestHost.matches(Regex("""^\d{1,3}(\.\d{1,3}){3}$"""))) {
                requestHost == mainDomain
            } else {
                val withoutWww = if (requestHost.startsWith("www.")) requestHost.substring(4) else requestHost
                withoutWww == mainDomain || withoutWww.endsWith(".$mainDomain")
            }
        } catch (e: Exception) { false }
    }

    // Handle back button
    BackHandler(enabled = canGoBack) {
        webView?.goBack()
    }

    // Auto-hide error when connection is restored
    LaunchedEffect(isConnected) {
        if (isConnected && showNetworkError) {
            showNetworkError = false
            webView?.reload()
        }
    }

    // Sync refresh indicator with page loading state
    LaunchedEffect(isLoading) {
        if (!isLoading && isRefreshing) {
            isRefreshing = false
        }
    }

    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = {
            if (!isConnected) {
                // Show error toast if offline
                Toast.makeText(context, "No internet connection", Toast.LENGTH_SHORT).show()
                isRefreshing = false
            } else {
                // Interrupt current load, clear cache, and reload
                isRefreshing = true
                webView?.apply {
                    stopLoading()
                    clearCache(true)
                    reload()
                }
            }
        },
        modifier = Modifier.fillMaxSize()
    ) {
        Box(modifier = Modifier.fillMaxSize()) {
        AndroidView(
            modifier = Modifier.fillMaxSize(),
        factory = { ctx ->
            WebView(ctx).apply {
                webView = this

                // WebView settings
                settings.apply {
                    javaScriptEnabled = true
                    domStorageEnabled = true
                    databaseEnabled = true
                    setSupportZoom(true)
                    builtInZoomControls = true
                    displayZoomControls = false
                    loadWithOverviewMode = true
                    useWideViewPort = true
                    javaScriptCanOpenWindowsAutomatically = true
                    mediaPlaybackRequiresUserGesture = false
                    allowFileAccess = true
                    allowContentAccess = true
                    setSupportMultipleWindows(true)

                    // Enable mixed content
                    mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
                }

                // WebViewClient
                webViewClient = object : WebViewClient() {
                    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                        super.onPageStarted(view, url, favicon)
                        canGoBack = view?.canGoBack() ?: false
                        isLoading = true
                    }

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

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

                        // Stop loading indicator
                        isLoading = false

                        // Silently ignore errors from third-party domains
                        val requestUrl = request?.url?.toString()
                        if (!isFromMainDomain(requestUrl)) {
                            return
                        }

                        // Detect network-specific errors
                        val isNetworkError = error?.errorCode in listOf(
                            WebViewClient.ERROR_HOST_LOOKUP,
                            WebViewClient.ERROR_CONNECT,
                            WebViewClient.ERROR_TIMEOUT,
                            WebViewClient.ERROR_IO,
                            WebViewClient.ERROR_UNKNOWN
                        )

                        // Show network error overlay only for main frame network errors from main domain
                        if (isNetworkError && request?.isForMainFrame == true) {
                            showNetworkError = true
                        }
                        // Sub-resource errors from main domain are silently ignored
                    }
                }

                // WebChromeClient for advanced features
                webChromeClient = object : WebChromeClient() {
                    // Capture page title
                    override fun onReceivedTitle(view: WebView?, title: String?) {
                        super.onReceivedTitle(view, title)
                        onTitleReceived(title)
                    }

                    // Geolocation permission
                    override fun onGeolocationPermissionsShowPrompt(
                        origin: String?,
                        callback: GeolocationPermissions.Callback?
                    ) {
                        callback?.invoke(origin, true, false)
                    }

                    // Console messages for debugging
                    override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
                        consoleMessage?.let {
                            println("WebView Console: ${it.message()} -- From line ${it.lineNumber()} of ${it.sourceId()}")
                        }
                        return true
                    }

                    // Handle file chooser for uploads
                    override fun onShowFileChooser(
                        webView: WebView?,
                        filePathCallback: ValueCallback<Array<Uri>>?,
                        fileChooserParams: FileChooserParams?
                    ): Boolean {
                        // In a real app, launch file picker here
                        // For now, just return false to use default behavior
                        return false
                    }
                }

                // Download listener
                setDownloadListener { url, userAgent, contentDisposition, mimeType, contentLength ->
                    Toast.makeText(
                        context,
                        "Download started: $url",
                        Toast.LENGTH_SHORT
                    ).show()
                    // In a real app, handle download here
                }

                // Notify that WebView is created
                onWebViewCreated(this)

                // Restore state if available, otherwise load URL
                if (savedState != null && !savedState.isEmpty) {
                    restoreState(savedState)
                } else {
                    loadUrl(url)
                }
            }
        },
            update = { view ->
                // Only reload if URL has changed and no saved state
                if (savedState == null && view.url != url) {
                    view.loadUrl(url)
                }
            }
        )

        // Network error overlay
        NetworkErrorOverlay(
            showError = showNetworkError,
            isConnected = isConnected,
            onRetry = {
                showNetworkError = false
                webView?.reload()
            },
            modifier = Modifier.align(Alignment.TopCenter)
        )

        // Loading overlay
        AnimatedVisibility(
            visible = isLoading,
            enter = fadeIn(),
            exit = fadeOut(),
            modifier = Modifier.fillMaxSize()
        ) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Black.copy(alpha = 0.4f)),
                contentAlignment = Alignment.Center
            ) {
                CircularProgressIndicator(
                    modifier = Modifier.size(48.dp),
                    color = MaterialTheme.colorScheme.primary
                )
            }
        }
        }
    }
}
