@file:Suppress("AssignedValueIsNeverRead")

package eu.gaudian.translator.view.exercises

import android.annotation.SuppressLint
import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavController
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.loadOrCueVideo
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
import eu.gaudian.translator.R
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 eu.gaudian.translator.viewmodel.YouTubeExerciseState

@SuppressLint("SetJavaScriptEnabled")
@Composable
fun YouTubeExerciseScreen(
    navController: NavController
) {
    val activity = LocalContext.current.findActivity()
    val exerciseViewModel : ExerciseViewModel = hiltViewModel(activity)
    val context = LocalContext.current
    val lifecycleOwner = androidx.lifecycle.compose.LocalLifecycleOwner.current
    val sessionParams by exerciseViewModel.youTubeSessionParams.collectAsState()
    val exerciseState by exerciseViewModel.youTubeExerciseState.collectAsState()

    val initialUrl = sessionParams?.url
    val videoIdFromUrl = extractVideoId(initialUrl)

    var currentTimeSec by remember { mutableFloatStateOf(0f) }
    val listState = rememberLazyListState()
    var title by remember{ mutableStateOf(String())}

    // Keep a reference to the player to support seeking from the subtitle list
    var youTubePlayerRef by remember { mutableStateOf<YouTubePlayer?>(null) }

    // Video completion detection and manual finish
    @Suppress("VariableNeverRead") var videoEnded by remember { mutableStateOf(false) }
    var userWantsToFinish by remember { mutableStateOf(false) }
    var isGeneratingQuestions by remember { mutableStateOf(false) }
    val textErrorGeneratingQuestions = stringResource(R.string.text_error_generating_questions)

    // Create the player view once and manage its lifecycle
    val playerView = remember {
        YouTubePlayerView(context).apply {
            enableAutomaticInitialization = false
            val listener = object : AbstractYouTubePlayerListener() {
                override fun onReady(youTubePlayer: YouTubePlayer) {
                    youTubePlayerRef = youTubePlayer
                    // Load the initial video when ready
                    videoIdFromUrl?.let { id ->
                        // Best practice: Use loadOrCueVideo to avoid playing in the background
                        // if the view is not resumed.
                        youTubePlayer.loadOrCueVideo(lifecycleOwner.lifecycle, id, 0f)
                        exerciseViewModel.fetchSubtitlesForVideoId(id)
                    }
                }
                override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) {
                    currentTimeSec = second
                }

                override fun onStateChange(youTubePlayer: YouTubePlayer, state: com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants.PlayerState) {
                    if (state == com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants.PlayerState.ENDED) {
                        videoEnded = true
                    }
                }
            }
            // IFramePlayerOptions allow for more control over the player appearance and behavior
            val options = IFramePlayerOptions.Builder(context)
                .controls(1) // Show player controls
                .rel(0)      // Show related videos from the same channel
                .build()
            initialize(listener, options)
        }
    }

    // Attach the player view to the Composable's lifecycle
    DisposableEffect(lifecycleOwner) {
        lifecycleOwner.lifecycle.addObserver(playerView)
        onDispose {
            exerciseViewModel.clearYouTubeSubtitles()
            // It's crucial to release the player resource when the Composable is disposed
            try { playerView.release() } catch (_: Exception) {}
        }
    }

    // Support changing the URL during the session
    LaunchedEffect(videoIdFromUrl) {
        if (videoIdFromUrl != null) {
            // Best practice: Use loadOrCueVideo for subsequent video loads as well.
            youTubePlayerRef?.loadOrCueVideo(lifecycleOwner.lifecycle, videoIdFromUrl, 0f)
            exerciseViewModel.fetchSubtitlesForVideoId(videoIdFromUrl)
        } else {
            exerciseViewModel.clearYouTubeSubtitles()
        }
    }

    fun seekTo(seconds: Float) {
        youTubePlayerRef?.seekTo(seconds)
    }

    // Generate questions when user wants to finish
    LaunchedEffect(userWantsToFinish, exerciseState) {
        if (userWantsToFinish && exerciseState is YouTubeExerciseState.Success && !isGeneratingQuestions) {
            val state = exerciseState as YouTubeExerciseState.Success
            val subtitles = state.subtitles

            if (subtitles.isNotEmpty()) {
                isGeneratingQuestions = true

                // Use ViewModel method to avoid coroutine cancellation issues
                exerciseViewModel.generateAndSaveYouTubeExercise(
                    subtitles = subtitles,
                    videoTitle = title,
                    videoId = videoIdFromUrl ?: "unknown",
                    sourceLanguage = sessionParams?.sourceLanguage,
                    targetLanguage = sessionParams?.targetLanguage,
                    onComplete = { exercise: eu.gaudian.translator.model.Exercise ->
                        // Exercise is saved, now get the questions for the session
                        exerciseViewModel.startExercise(exercise)
                        @Suppress("HardCodedStringLiteral")
                        navController.navigate("exercise_session")
                    },
                    onError = { error ->
                        Toast.makeText(
                            context,
                            "$textErrorGeneratingQuestions $error",
                            Toast.LENGTH_LONG
                        ).show()
                        isGeneratingQuestions = false
                    }
                )
            }
        }
    }

    // Navigation is now handled in the generateAndSaveYouTubeExercise onComplete callback

    fun onFinishVideo() {
        userWantsToFinish = true
    }

    AppScaffold(
        topBar = {
            AppTopAppBar(
                title = title,
                onNavigateBack = { navController.popBackStack() },
                actions = {
                    IconButton(
                        onClick = { onFinishVideo() },
                        enabled = exerciseState is YouTubeExerciseState.Success && !isGeneratingQuestions
                    ) {
                        Icon(
                            AppIcons.Check,
                            contentDescription = stringResource(R.string.text_finish_video_and_start_exercise)
                        )
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding)
        ) {
            // Split mode: video player and subtitles panel
            AndroidView(
                factory = { playerView },
                modifier = Modifier
                    .fillMaxWidth()
                    .weight(1f)
            )

            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .weight(2f)
                    .background(MaterialTheme.colorScheme.surfaceVariant),
                contentAlignment = Alignment.Center
            ) {
                when (val state = exerciseState) {
                    is YouTubeExerciseState.Idle -> Text(stringResource(R.string.text_paste_or_open_a_), textAlign = TextAlign.Center, modifier = Modifier.padding(16.dp))
                    is YouTubeExerciseState.Loading -> CircularProgressIndicator()
                    is YouTubeExerciseState.Error -> Text(
                        stringResource(
                            R.string.text_error_2d,
                            state.message
                        ), color = MaterialTheme.colorScheme.error, textAlign = TextAlign.Center, modifier = Modifier.padding(16.dp))
                    is YouTubeExerciseState.Success -> {
                        title = state.videoTitle
                        val subtitles = state.subtitles
                        val activeIndex = subtitles.indexOfLast { s -> currentTimeSec >= s.start }

                        LaunchedEffect(activeIndex) {
                            if (activeIndex >= 1) {
                                // Animate scroll to the currently active subtitle
                                listState.animateScrollToItem(index = activeIndex)
                            }
                        }

                        // Show loading indicator when generating questions
                        if (isGeneratingQuestions) {
                            Column(
                                modifier = Modifier.fillMaxSize(),
                                horizontalAlignment = Alignment.CenterHorizontally,
                                verticalArrangement = Arrangement.Center
                            ) {
                                CircularProgressIndicator()
                                Text(
                                    text = stringResource(R.string.text_generating_questions_from_video),
                                    modifier = Modifier.padding(top = 16.dp),
                                    style = MaterialTheme.typography.bodyMedium
                                )
                            }
                        } else {
                            LazyColumn(
                                modifier = Modifier.fillMaxSize(),
                                state = listState,
                                contentPadding = androidx.compose.foundation.layout.PaddingValues(vertical = 12.dp)
                            ) {
                                itemsIndexed(items = subtitles, key = { _, item -> item.start }) { index, subtitle ->
                                    val isActive = index == activeIndex
                                    val bg = if (isActive) MaterialTheme.colorScheme.primary.copy(alpha = 0.12f) else MaterialTheme.colorScheme.surfaceVariant
                                    Column(
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .background(bg)
                                            .clickable { seekTo(subtitle.start) }
                                            .padding(horizontal = 16.dp, vertical = 8.dp)
                                    ) {
                                        Text(
                                            text = "${formatTimestamp(subtitle.start)} - ${formatTimestamp(subtitle.end)}",
                                            style = MaterialTheme.typography.labelSmall,
                                            color = if (isActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
                                        )
                                        Text(
                                            text = subtitle.text,
                                            fontWeight = if (isActive) FontWeight.Bold else FontWeight.Normal,
                                            color = MaterialTheme.colorScheme.onSurface,
                                            modifier = Modifier.fillMaxWidth()
                                        )
                                        if (!subtitle.translatedText.isNullOrBlank()) {
                                            Text(
                                                text = subtitle.translatedText,
                                                style = MaterialTheme.typography.bodyMedium,
                                                color = if (isActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
                                                modifier = Modifier
                                                    .fillMaxWidth()
                                                    .padding(top = 4.dp)
                                            )
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

fun extractVideoId(url: String?): String? {
    if (url == null) return null
    @Suppress("RegExpRedundantEscape", "HardCodedStringLiteral") val pattern = "(?<=watch\\?v=|/videos/|embed\\/|youtu.be\\/|\\/v\\/|\\/e\\/|watch\\?v%3D|watch\\?feature=player_embedded&v=|%2Fvideos%2F|embed%2Fvideos%2F|youtu.be%2F)[^#&?]*".toRegex()
    return pattern.find(url)?.value
}

fun formatTimestamp(seconds: Float): String {
    val total = seconds.toInt()
    val mins = total / 60
    val secs = total % 60
    @Suppress("HardCodedStringLiteral")
    return "%d:%02d".format(mins, secs)
}