@file:Suppress("AssignedValueIsNeverRead")

package eu.gaudian.translator.view.exercises

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.Color
import android.webkit.CookieManager
import android.webkit.JavascriptInterface
import android.webkit.WebChromeClient
import android.webkit.WebResourceRequest
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavController
import eu.gaudian.translator.utils.findActivity
import eu.gaudian.translator.view.composable.AppIcons
import eu.gaudian.translator.view.composable.AppScaffold
import eu.gaudian.translator.view.composable.AppTopAppBar
import eu.gaudian.translator.viewmodel.ExerciseViewModel
import java.net.URLDecoder

/**
 * A screen that lets the user browse YouTube inside a WebView. When the user taps on a video link,
 * we open the YouTubeExerciseDialog in language-only mode to pick languages, then start the exercise.
 */
@Suppress("HardCodedStringLiteral")
@Composable
@SuppressLint("SetJavaScriptEnabled")
fun YouTubeBrowserScreen(
    navController: NavController
) {

    val activity = LocalContext.current.findActivity()
    val exerciseViewModel : ExerciseViewModel = hiltViewModel(activity)
    var pendingVideoUrl by remember { mutableStateOf<String?>(null) }
    var showLanguageDialog by remember { mutableStateOf(false) }
    var showCustomDialog by remember { mutableStateOf(false) }

    val context = LocalContext.current

    AppScaffold(
        topBar = {
            AppTopAppBar(
                title = "YouTube" ,
                onNavigateBack = { navController.popBackStack() }
            )
        }
    ) { padding ->
        androidx.compose.foundation.layout.Box(
            modifier = Modifier
                .fillMaxSize()
                .padding(padding)
        ) {
            AndroidView(
                modifier = Modifier.fillMaxSize(),
            factory = {
                WebView(context).apply {
                    setBackgroundColor(Color.BLACK)
                    CookieManager.getInstance().setAcceptCookie(true)
                    CookieManager.getInstance().setAcceptThirdPartyCookies(this, true)

                    settings.javaScriptEnabled = true
                    settings.domStorageEnabled = true
                    settings.loadsImagesAutomatically = true
                    settings.mediaPlaybackRequiresUserGesture = false
                    settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
                    settings.useWideViewPort = true
                    settings.loadWithOverviewMode = true

                    webChromeClient = WebChromeClient()
                    webViewClient = object : WebViewClient() {
                        override fun shouldOverrideUrlLoading(
                            view: WebView?,
                            request: WebResourceRequest?
                        ): Boolean {
                            val url = request?.url?.toString() ?: return false
                            if (url.startsWith("intent://")) {
                                extractFallbackFromIntentUrl(url)?.let { fallback ->
                                    return handleUrl(fallback) {
                                        pendingVideoUrl = it
                                        showLanguageDialog = true
                                    }
                                }
                                return true
                            }
                            return handleUrl(url) {
                                pendingVideoUrl = it
                                showLanguageDialog = true
                            }
                        }

                        @Deprecated("Deprecated in Java")
                        override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                            val u = url ?: return false
                            if (u.startsWith("intent://")) {
                                extractFallbackFromIntentUrl(u)?.let { fallback ->
                                    return handleUrl(fallback) {
                                        pendingVideoUrl = it
                                        showLanguageDialog = true
                                    }
                                }
                                return true
                            }
                            return handleUrl(u) {
                                pendingVideoUrl = it
                                showLanguageDialog = true
                            }
                        }

                        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                            super.onPageStarted(view, url, favicon)
                            val u = url ?: return
                            if (!showLanguageDialog && isYouTubeWatchUrl(u)) {
                                pendingVideoUrl = u
                                showLanguageDialog = true
                                view?.stopLoading()
                            }
                        }

                        override fun onPageFinished(view: WebView?, url: String?) {
                            super.onPageFinished(view, url)
                            // Inject JS hooks to catch SPA navigations and link clicks
                            view?.evaluateJavascript(YT_INTERCEPT_JS, null)
                        }
                    }

                    // Bridge: receive URL changes from JS world
                    addJavascriptInterface(YouTubeJsBridge { url ->
                        // Ensure state changes happen on UI thread
                        this.post {
                            if (!showLanguageDialog) {
                                pendingVideoUrl = url
                                showLanguageDialog = true
                                try { stopLoading() } catch (_: Throwable) {}
                            }
                        }
                    }, "YTBridge")

                    // Load mobile YouTube for better interaction in WebView
                    loadUrl("https://m.youtube.com/")
                }
            }
        )
            FloatingActionButton(
                onClick = { showCustomDialog = true },
                modifier = Modifier
                    .align(Alignment.BottomEnd)
                    .padding(16.dp)
            ) {
                Icon(imageVector = AppIcons.Add, contentDescription = "Add YouTube link")
            }
        }
    }

    if (showLanguageDialog && pendingVideoUrl != null) {
        YouTubeExerciseDialog(
            onDismiss = {
                showLanguageDialog = false
                pendingVideoUrl = null
            },
            onCreate = { _, sourceLanguage, targetLanguage ->
                val url = pendingVideoUrl ?: return@YouTubeExerciseDialog
                exerciseViewModel.startYouTubeExercise(url, sourceLanguage, targetLanguage)
                // Navigate to the exercise screen; keep this browser on the back stack so back returns here
                navController.navigate("youtube_exercise")
                showLanguageDialog = false
                pendingVideoUrl = null
            },
            presetUrl = pendingVideoUrl!!,
            languageOnly = true
        )
    }

    if (showCustomDialog) {
        YouTubeExerciseDialog(
            onDismiss = {
                showCustomDialog = false
            },
            onCreate = { youtubeUrl, sourceLanguage, targetLanguage ->
                exerciseViewModel.startYouTubeExercise(youtubeUrl, sourceLanguage, targetLanguage)
                // Navigate to the exercise screen; keep this browser on the back stack so back returns here
                navController.navigate("youtube_exercise")
                showCustomDialog = false
            },
            languageOnly = false
        )
    }
}

private fun isYouTubeWatchUrl(url: String): Boolean {
    @Suppress("HardCodedStringLiteral")
    return url.contains("youtube.com/watch") || url.contains("youtu.be/") || url.contains("youtube.com/shorts/")
}

private inline fun handleUrl(url: String, onVideo: (String) -> Unit): Boolean {
    return if (isYouTubeWatchUrl(url)) {
        onVideo(url)
        true // intercept
    } else {
        false // let WebView load normally
    }
}

@Suppress("HardCodedStringLiteral")
private fun extractFallbackFromIntentUrl(intentUrl: String): String? {
    val match = Regex("S\\.browser_fallback_url=([^;]+)").find(intentUrl) ?: return null
    val encoded = match.groupValues[1]
    return try {
        URLDecoder.decode(encoded, "UTF-8")
    } catch (_: Exception) {
        null
    }
}

// DO NOT EVER TOUCH THIS AGAIN
@Suppress("HardCodedStringLiteral")
private val YT_INTERCEPT_JS: String = (
    "(function(){" +
        "if(window.__ytInterceptInstalled){return;}" +
        "window.__ytInterceptInstalled=true;" +
        "function notify(url){try{YTBridge.onUrlChange(url||location.href);}catch(e){}}" +
        // Hook history API
        "var ps=history.pushState, rs=history.replaceState;" +
        "history.pushState=function(){ps.apply(this,arguments);notify();};" +
        "history.replaceState=function(){rs.apply(this,arguments);notify();};" +
        "window.addEventListener('popstate',function(){notify();},true);" +
        // Intercept link clicks
        "document.addEventListener('click',function(e){" +
            "try{" +
                "var el=e.target;" +
                "while(el && el.tagName && el.tagName.toLowerCase()!=='a'){el=el.parentElement;}" +
                "if(el && el.href){" +
                    "var href=el.href;" +
                    "if(/youtube\\.com\\/watch|youtu\\.be\\/|youtube\\.com\\/shorts\\//.test(href)){" +
                        "e.preventDefault();e.stopPropagation();" +
                        "notify(href);" +
                        "return false;" +
                    "}" +
                "}" +
            "}catch(ex){}" +
        "}, true);" +
        // Initial notify on first load (in case we landed directly on a watch page)
        "setTimeout(function(){notify();},0);" +
    "})();"
)

private class YouTubeJsBridge(private val onVideo: (String) -> Unit) {
    @Suppress("unused", "HardCodedStringLiteral")
    @JavascriptInterface
    fun onUrlChange(url: String) {
        if (isYouTubeWatchUrl(url)) {
            onVideo(url)
        }
    }
}