package com.horrortv.app.presentation.player

import android.graphics.Typeface
import android.net.Uri
import android.util.Log
import android.util.TypedValue
import android.view.KeyEvent
import androidx.media3.ui.CaptionStyleCompat
import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable

import androidx.compose.foundation.focusable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
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.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester

import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.graphics.graphicsLayer

import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.TrackSelectionOverride
import androidx.media3.common.Tracks
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.DefaultRenderersFactory
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import androidx.media3.ui.PlayerView
import com.horrortv.app.domain.model.VideoSource
import com.horrortv.app.domain.usecase.VideoExtractor
import com.horrortv.app.presentation.MainActivity
import com.horrortv.app.presentation.theme.HorrorColors
import com.horrortv.app.presentation.theme.HorrorTypography
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

private const val TAG = "PlayerScreen"
private const val AUTO_HIDE_DELAY_MS = 5000L
private const val SEEK_STEP_MS = 5000L
private val ButtonShape = RoundedCornerShape(12.dp)
private val SeekBarShape = RoundedCornerShape(8.dp)

data class SubtitleOption(val label: String, val languageCode: String?, val trackIndex: Int = -1) {
    companion object {
        val OFF = SubtitleOption("Off", null)
    }
}

@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
@Composable
fun PlayerScreen(
    imdbId: String,
    title: String = "Horror TV",
    onNavigateBack: () -> Unit,
    modifier: Modifier = Modifier
) {
    val context = LocalContext.current
    val scope = rememberCoroutineScope()

    var videoSource by remember { mutableStateOf<VideoSource?>(null) }
    var isLoading by remember { mutableStateOf(true) }
    var hasError by remember { mutableStateOf(false) }
    var errorMessage by remember { mutableStateOf("") }
    var showControls by remember { mutableStateOf(true) }
    var selectedButton by remember { mutableStateOf(1) } // 0=seekback, 1=play, 2=seekforward, 3=subtitle
    var isPlaying by remember { mutableStateOf(false) }
    var currentTimeMs by remember { mutableLongStateOf(0L) }
    var durationMs by remember { mutableLongStateOf(0L) }
    var selectedSubtitle by remember { mutableStateOf(SubtitleOption.OFF) }
    var showSubtitlePicker by remember { mutableStateOf(false) }
    var seekMode by remember { mutableStateOf(false) }
    var seekPositionMs by remember { mutableLongStateOf(0L) }
    var selectedSubtitleIndex by remember { mutableStateOf(0) }

    val availableSubtitles = remember(videoSource) {
        buildList {
            add(SubtitleOption.OFF)
            videoSource?.subtitleTracks?.forEachIndexed { index, track ->
                add(SubtitleOption(track.label, track.language, index))
            }
        }
    }

    val trackSelector = remember {
        DefaultTrackSelector(context).apply {
            setParameters(
                buildUponParameters()
                    .setForceHighestSupportedBitrate(false)
                    .setTunnelingEnabled(false)  // was true — breaks subtitles on many TVs
            )
        }
    }

    val exoPlayer = remember {
        ExoPlayer.Builder(context)
            .setRenderersFactory(DefaultRenderersFactory(context).setEnableDecoderFallback(true))
            .setTrackSelector(trackSelector)
            .setLoadControl(
                DefaultLoadControl.Builder()
                    .setBufferDurationsMs(
                        15_000,  // minBuffer: 15s — enough to absorb jitter
                        30_000,  // maxBuffer: 30s — don't hog RAM on Chromecast
                        2_000,   // playAfterBuffer: 2s
                        3_000    // playAfterRebuffer: 3s — resume faster after stalls
                    )
                    .build()
            )
            .build()
    }

    class AutoHideHolder(var job: kotlinx.coroutines.Job? = null)
    val autoHide = remember { AutoHideHolder() }

    val resetAutoHideTimer = remember(autoHide, scope, isPlaying, showSubtitlePicker, seekMode) {
        {
            autoHide.job?.cancel()
            autoHide.job = scope.launch {
                delay(AUTO_HIDE_DELAY_MS)
                if (isPlaying && !showSubtitlePicker && !seekMode) {
                    showControls = false
                }
            }
        }
    }

    // Register D-pad key handler at Activity level (before PlayerView steals events)
    // Key: availableSubtitles changes when videoSource loads, handler must see updated list
    DisposableEffect(availableSubtitles) {
        MainActivity.keyEventHandler = handler@{ event ->
            if (event.action == KeyEvent.ACTION_DOWN) {
                when (event.keyCode) {
                    KeyEvent.KEYCODE_DPAD_CENTER, KeyEvent.KEYCODE_ENTER -> {
                        if (event.repeatCount > 0) return@handler false
                        if (!isLoading && !hasError) {
                            when {
                                showSubtitlePicker -> {
                                    val option = availableSubtitles.getOrNull(selectedSubtitleIndex)
                                    if (option != null) {
                                        selectedSubtitle = option
                                        updateSubtitleTrack(exoPlayer, trackSelector, option)
                                    }
                                    showSubtitlePicker = false
                                    resetAutoHideTimer()
                                    true
                                }
                                seekMode -> {
                                    exoPlayer.seekTo(seekPositionMs)
                                    currentTimeMs = seekPositionMs
                                    seekMode = false
                                    resetAutoHideTimer()
                                    true
                                }
                                !showControls -> {
                                    showControls = true
                                    resetAutoHideTimer()
                                    true
                                }
                                else -> {
                                    // Execute selected button's action
                                    when (selectedButton) {
                                        0 -> {
                                            val newPos = (exoPlayer.currentPosition - SEEK_STEP_MS).coerceAtLeast(0L)
                                            exoPlayer.seekTo(newPos)
                                            currentTimeMs = newPos
                                            resetAutoHideTimer()
                                        }
                                        1 -> {
                                            if (isPlaying) exoPlayer.pause() else exoPlayer.play()
                                            resetAutoHideTimer()
                                        }
                                        2 -> {
                                            val newPos = (exoPlayer.currentPosition + SEEK_STEP_MS).coerceAtMost(durationMs)
                                            exoPlayer.seekTo(newPos)
                                            currentTimeMs = newPos
                                            resetAutoHideTimer()
                                        }
                                        3 -> {
                                            showSubtitlePicker = true
                                            selectedSubtitleIndex = availableSubtitles.indexOf(selectedSubtitle).coerceAtLeast(0)
                                            resetAutoHideTimer()
                                        }
                                    }
                                    true
                                }
                            }
                        } else false
                    }
                    KeyEvent.KEYCODE_DPAD_LEFT -> {
                        if (!isLoading && !hasError) {
                            when {
                                showSubtitlePicker -> false
                                seekMode -> {
                                    seekPositionMs = (seekPositionMs - 10000).coerceAtLeast(0L)
                                    true
                                }
                                !showControls -> {
                                    showControls = true
                                    resetAutoHideTimer()
                                    true
                                }
                                else -> {
                                    if (selectedButton > 0) {
                                        selectedButton--
                                        resetAutoHideTimer()
                                    }
                                    true
                                }
                            }
                        } else false
                    }
                    KeyEvent.KEYCODE_DPAD_RIGHT -> {
                        if (!isLoading && !hasError) {
                            when {
                                showSubtitlePicker -> false
                                seekMode -> {
                                    seekPositionMs = (seekPositionMs + 10000).coerceAtMost(durationMs)
                                    true
                                }
                                !showControls -> {
                                    showControls = true
                                    resetAutoHideTimer()
                                    true
                                }
                                else -> {
                                    if (selectedButton < 3) {
                                        selectedButton++
                                        resetAutoHideTimer()
                                    }
                                    true
                                }
                            }
                        } else false
                    }
                    KeyEvent.KEYCODE_DPAD_UP -> {
                        if (!isLoading && !hasError) {
                            when {
                                showSubtitlePicker -> {
                                    if (selectedSubtitleIndex > 0) {
                                        selectedSubtitleIndex--
                                    }
                                    true
                                }
                                seekMode -> true
                                !showControls -> {
                                    showControls = true
                                    resetAutoHideTimer()
                                    true
                                }
                                else -> {
                                    seekMode = true
                                    seekPositionMs = currentTimeMs
                                    resetAutoHideTimer()
                                    true
                                }
                            }
                        } else false
                    }
                    KeyEvent.KEYCODE_DPAD_DOWN -> {
                        if (!isLoading && !hasError) {
                            when {
                                showSubtitlePicker -> {
                                    if (selectedSubtitleIndex < availableSubtitles.lastIndex) {
                                        selectedSubtitleIndex++
                                    }
                                    true
                                }
                                seekMode -> {
                                    exoPlayer.seekTo(seekPositionMs)
                                    currentTimeMs = seekPositionMs
                                    seekMode = false
                                    resetAutoHideTimer()
                                    true
                                }
                                !showControls -> {
                                    showControls = true
                                    resetAutoHideTimer()
                                    true
                                }
                                else -> {
                                    resetAutoHideTimer()
                                    false
                                }
                            }
                        } else false
                    }
                    KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_ESCAPE -> {
                        when {
                            showSubtitlePicker -> {
                                showSubtitlePicker = false
                                resetAutoHideTimer()
                                true
                            }
                            seekMode -> {
                                seekMode = false
                                resetAutoHideTimer()
                                true
                            }
                            else -> false
                        }
                    }
                    else -> false
                }
            } else {
                false
            }
        }
        onDispose {
            MainActivity.keyEventHandler = null
        }
    }

    LaunchedEffect(imdbId) {
        isLoading = true
        hasError = false
        try {
            val result = withContext(Dispatchers.IO) {
                VideoExtractor().extractVideoSource(imdbId, context.cacheDir)
            }
            result.fold(
                onSuccess = { source ->
                    videoSource = source
                    val mediaItem = buildMediaItemWithSubtitles(source)
                    exoPlayer.setMediaItem(mediaItem)
                    exoPlayer.prepare()
                    exoPlayer.playWhenReady = true
                    isLoading = false
                },
                onFailure = { error ->
                    hasError = true
                    errorMessage = "Error: ${error.message}"
                    isLoading = false
                }
            )
        } catch (e: CancellationException) {
            throw e
        } catch (e: Exception) {
            hasError = true
            errorMessage = "Error: ${e.message}"
            isLoading = false
        }
    }

    DisposableEffect(exoPlayer) {
        val listener = object : Player.Listener {
            override fun onIsPlayingChanged(playing: Boolean) {
                isPlaying = playing
            }

            override fun onPlaybackStateChanged(playbackState: Int) {
                when (playbackState) {
                    Player.STATE_READY -> {
                        isLoading = false
                        durationMs = if (exoPlayer.duration == C.TIME_UNSET) 0L else exoPlayer.duration
                    }
                    Player.STATE_BUFFERING -> isLoading = true
                    Player.STATE_IDLE -> {
                        isLoading = false
                        isPlaying = false
                    }
                    Player.STATE_ENDED -> isPlaying = false
                }
            }

            override fun onTracksChanged(tracks: Tracks) {
                updateSubtitleTrack(exoPlayer, trackSelector, selectedSubtitle)
            }

            override fun onPlayerError(error: PlaybackException) {
                hasError = true
                errorMessage = error.localizedMessage ?: "Error de reproducción"
                isLoading = false
            }
        }
        exoPlayer.addListener(listener)
        onDispose {
            exoPlayer.removeListener(listener)
            isPlaying = false
            exoPlayer.release()
        }
    }

    LaunchedEffect(showControls, isPlaying, showSubtitlePicker, seekMode) {
        if (showControls && isPlaying && !showSubtitlePicker && !seekMode) {
            resetAutoHideTimer()
        }
    }

    LaunchedEffect(isPlaying, showControls) {
        if (showControls && isPlaying) {
            currentTimeMs = exoPlayer.currentPosition  // Immediate update when controls appear
            while (isPlaying) {
                delay(500)
                currentTimeMs = exoPlayer.currentPosition
            }
        }
    }

    LaunchedEffect(showControls) {
        if (showControls) {
            selectedButton = 1 // Default to play button
            seekMode = false
        }
    }

    BackHandler(enabled = true) {
        when {
            showSubtitlePicker -> {
                showSubtitlePicker = false
                resetAutoHideTimer()
            }
            seekMode -> {
                seekMode = false
                resetAutoHideTimer()
            }
            showControls -> {
                showControls = false
            }
            else -> {
                onNavigateBack()
            }
        }
    }

    Box(
        modifier = modifier
            .fillMaxSize()
            .background(HorrorColors.HorrorBlack)
    ) {
        if (hasError) {
            PlayerErrorOverlay(
                errorMessage = errorMessage,
                onRetry = {
                    hasError = false
                    isLoading = true
                    scope.launch {
                        try {
                            val result = withContext(Dispatchers.IO) {
                                VideoExtractor().extractVideoSource(imdbId, context.cacheDir)
                            }
                            result.fold(
                                onSuccess = { source ->
                                    videoSource = source
                                    val mediaItem = buildMediaItemWithSubtitles(source)
                                    exoPlayer.setMediaItem(mediaItem)
                                    exoPlayer.prepare()
                                    exoPlayer.playWhenReady = true
                                    isLoading = false
                                },
                                onFailure = { error ->
                                    hasError = true
                                    errorMessage = "Error: ${error.message}"
                                    isLoading = false
                                }
                            )
                        } catch (e: CancellationException) {
                            throw e
                        } catch (e: Exception) {
                            hasError = true
                            errorMessage = "Error: ${e.message}"
                            isLoading = false
                        }
                    }
                },
                onBack = onNavigateBack
            )
        } else {
            AndroidView(
                factory = { ctx ->
                    PlayerView(ctx).apply {
                        player = exoPlayer
                        useController = false
                        isFocusable = false
                        descendantFocusability = android.view.ViewGroup.FOCUS_BLOCK_DESCENDANTS
                        keepScreenOn = true
                        setOnKeyListener { _, _, _ -> false }
                        subtitleView?.apply {
                            val captionStyle = CaptionStyleCompat(
                                android.graphics.Color.WHITE,
                                android.graphics.Color.BLACK,
                                android.graphics.Color.TRANSPARENT,
                                CaptionStyleCompat.EDGE_TYPE_OUTLINE,
                                android.graphics.Color.BLACK,
                                Typeface.DEFAULT_BOLD
                            )
                            setApplyEmbeddedStyles(false)
                            setApplyEmbeddedFontSizes(false)
                            setStyle(captionStyle)
                            setFixedTextSize(TypedValue.COMPLEX_UNIT_SP, 24f)
                            setBottomPaddingFraction(0.08f)
                        }
                    }
                },
                update = { playerView ->
                    playerView.keepScreenOn = isPlaying
                },
                onRelease = { playerView ->
                    playerView.player = null
                },
                modifier = Modifier
                    .fillMaxSize()
            )

            if (isLoading) {
                Box(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(Color.Black.copy(alpha = 0.6f)),
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        text = "Cargando...",
                        style = HorrorTypography.DetailInfo,
                        color = HorrorColors.HorrorWhite
                    )
                }
            }

            if (showControls && !isLoading) {
                PlayerControlsOverlay(
                    title = title,
                    isPlaying = isPlaying,
                    currentTime = currentTimeMs,
                    duration = durationMs,
                    selectedSubtitle = selectedSubtitle,
                    subtitleOptions = availableSubtitles,
                    showSubtitlePicker = showSubtitlePicker,
                    selectedButton = selectedButton,
                    seekMode = seekMode,
                    seekPosition = seekPositionMs,
                    selectedSubtitleIndex = selectedSubtitleIndex,
                    onPlayPause = {
                        if (isPlaying) exoPlayer.pause() else exoPlayer.play()
                        showControls = true
                        resetAutoHideTimer()
                    },
                    onSeekForward = {
                        val newPos = (exoPlayer.currentPosition + SEEK_STEP_MS).coerceAtMost(durationMs)
                        exoPlayer.seekTo(newPos)
                        currentTimeMs = newPos
                        resetAutoHideTimer()
                    },
                    onSeekBackward = {
                        val newPos = (exoPlayer.currentPosition - SEEK_STEP_MS).coerceAtLeast(0L)
                        exoPlayer.seekTo(newPos)
                        currentTimeMs = newPos
                        resetAutoHideTimer()
                    },
                    onSubtitleToggle = {
                        showSubtitlePicker = !showSubtitlePicker
                        if (showSubtitlePicker) {
                            selectedSubtitleIndex = availableSubtitles.indexOf(selectedSubtitle).coerceAtLeast(0)
                        }
                        resetAutoHideTimer()
                    },
                    onSubtitleSelected = { option ->
                        selectedSubtitle = option
                        updateSubtitleTrack(exoPlayer, trackSelector, option)
                        showSubtitlePicker = false
                        resetAutoHideTimer()
                    },
                    onSubtitlePickerDismiss = {
                        showSubtitlePicker = false
                        resetAutoHideTimer()
                    },
                    onBack = onNavigateBack,
                    onControlsReset = { resetAutoHideTimer() }
                )
            }
        }
    }
}

private fun tryRequestFocus(focusRequester: FocusRequester, tag: String) {
    try {
        focusRequester.requestFocus()
    } catch (e: IllegalStateException) {
        Log.d(TAG, "FocusRequester '$tag' not ready: ${e.message}")
    }
}

private fun buildMediaItemWithSubtitles(source: VideoSource): MediaItem {
    val builder = MediaItem.Builder()
        .setUri(source.videoUrl)

    val subtitleConfigs = source.subtitleTracks.map { track ->
        MediaItem.SubtitleConfiguration.Builder(Uri.parse(track.url))
            .setMimeType(track.mimeType.ifBlank { getSubtitleMimeType(track.url) })
            .setLanguage(track.language)
            .setLabel(track.label)
            .setSelectionFlags(0)
            .build()
    }

    if (subtitleConfigs.isNotEmpty()) {
        builder.setSubtitleConfigurations(subtitleConfigs)
    }

    return builder.build()
}

private fun getSubtitleMimeType(url: String): String {
    val path = url.substringBefore("?").substringBefore("#")
    return when {
        path.endsWith(".vtt", ignoreCase = true) -> "text/vtt"
        path.endsWith(".srt", ignoreCase = true) -> "application/x-subrip"
        path.endsWith(".ttml", ignoreCase = true) -> "application/ttml+xml"
        else -> "text/vtt"
    }
}

private fun forceHighestVideoQuality(trackSelector: DefaultTrackSelector, player: ExoPlayer) {
    val parameters = trackSelector.buildUponParameters()
        .clearOverridesOfType(C.TRACK_TYPE_VIDEO)
    val tracks = player.currentTracks
    for (trackGroup in tracks.groups) {
        if (trackGroup.type == C.TRACK_TYPE_VIDEO && trackGroup.length > 0) {
            var highestIndex = 0
            var highestBitrate = Int.MIN_VALUE
            for (i in 0 until trackGroup.length) {
                val format = trackGroup.getTrackFormat(i)
                if (format.bitrate > highestBitrate) {
                    highestBitrate = format.bitrate
                    highestIndex = i
                }
            }
            parameters.addOverride(TrackSelectionOverride(trackGroup.mediaTrackGroup, listOf(highestIndex)))
        }
    }
    trackSelector.setParameters(parameters)
}

private fun updateSubtitleTrack(player: ExoPlayer, trackSelector: DefaultTrackSelector, option: SubtitleOption) {
    val parameters = trackSelector.buildUponParameters()
        .clearOverridesOfType(C.TRACK_TYPE_TEXT)

    if (option.languageCode == null) {
        parameters.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, true)
    } else {
        parameters.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, false)
        val tracks = player.currentTracks
        for (trackGroup in tracks.groups) {
            if (trackGroup.type == C.TRACK_TYPE_TEXT) {
                for (i in 0 until trackGroup.length) {
                    val format = trackGroup.getTrackFormat(i)
                    val matchesLanguage = format.language?.startsWith(option.languageCode) == true
                    val matchesLabel = format.label?.toString() == option.label
                    if (matchesLanguage && matchesLabel) {
                        parameters.addOverride(TrackSelectionOverride(trackGroup.mediaTrackGroup, listOf(i)))
                        break
                    }
                }
            }
        }
    }

    trackSelector.setParameters(parameters)
}

@Composable
private fun PlayerControlsOverlay(
    title: String,
    isPlaying: Boolean,
    currentTime: Long,
    duration: Long,
    selectedSubtitle: SubtitleOption,
    subtitleOptions: List<SubtitleOption>,
    showSubtitlePicker: Boolean,
    selectedButton: Int,
    seekMode: Boolean,
    seekPosition: Long,
    selectedSubtitleIndex: Int,
    onPlayPause: () -> Unit,
    onSeekForward: () -> Unit,
    onSeekBackward: () -> Unit,
    onSubtitleToggle: () -> Unit,
    onSubtitleSelected: (SubtitleOption) -> Unit,
    onSubtitlePickerDismiss: () -> Unit,
    onBack: () -> Unit,
    onControlsReset: () -> Unit
) {
    Box(
        modifier = Modifier.fillMaxSize()
    ) {
        Row(
            modifier = Modifier
                .align(Alignment.TopStart)
                .padding(24.dp),
            horizontalArrangement = Arrangement.spacedBy(16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            PlayerButton(
                iconRes = android.R.drawable.ic_menu_close_clear_cancel,
                label = "BACK",
                isFocused = false,
                onClick = {
                    onBack()
                    onControlsReset()
                }
            )

            Spacer(modifier = Modifier.width(16.dp))

            Text(
                text = title,
                style = HorrorTypography.MovieTitle,
                color = HorrorColors.HorrorWhite
            )
        }

        Column(
            modifier = Modifier
                .align(Alignment.Center)
                .fillMaxWidth()
                .padding(horizontal = 48.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = formatTime(currentTime, duration),
                    style = HorrorTypography.DetailInfo,
                    color = HorrorColors.HorrorWhite
                )

                Text(
                    text = formatTime(duration, duration),
                    style = HorrorTypography.DetailInfo,
                    color = HorrorColors.HorrorWhite
                )
            }

            Spacer(modifier = Modifier.height(16.dp))

            PlayerSeekBar(
                currentTime = currentTime,
                duration = duration,
                seekMode = seekMode,
                seekPosition = seekPosition
            )
        }

        Row(
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .padding(bottom = 48.dp, start = 48.dp, end = 48.dp),
            horizontalArrangement = Arrangement.spacedBy(24.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            PlayerButton(
                iconRes = android.R.drawable.ic_media_previous,
                label = "-10s",
                isFocused = selectedButton == 0,
                onClick = {
                    onSeekBackward()
                    onControlsReset()
                }
            )

            PlayerButton(
                iconRes = if (isPlaying) android.R.drawable.ic_media_pause else android.R.drawable.ic_media_play,
                label = if (isPlaying) "PAUSE" else "PLAY",
                isFocused = selectedButton == 1,
                onClick = {
                    onPlayPause()
                    onControlsReset()
                }
            )

            PlayerButton(
                iconRes = android.R.drawable.ic_media_next,
                label = "+10s",
                isFocused = selectedButton == 2,
                onClick = {
                    onSeekForward()
                    onControlsReset()
                }
            )

            PlayerButton(
                iconRes = android.R.drawable.ic_menu_sort_by_size,
                label = "SUBTITLE",
                isFocused = selectedButton == 3,
                onClick = {
                    onSubtitleToggle()
                    onControlsReset()
                }
            )
        }

        if (showSubtitlePicker) {
            SubtitlePickerOverlay(
                options = subtitleOptions,
                selectedOption = selectedSubtitle,
                selectedIndex = selectedSubtitleIndex,
                onOptionSelected = onSubtitleSelected,
                onDismiss = onSubtitlePickerDismiss
            )
        }
    }
}

@Composable
private fun PlayerSeekBar(
    currentTime: Long,
    duration: Long,
    seekMode: Boolean = false,
    seekPosition: Long = 0L
) {
    val progress = if (duration > 0) (currentTime.toFloat() / duration.toFloat()) else 0f
    val seekProgress = if (duration > 0) (seekPosition.toFloat() / duration.toFloat()) else 0f
    val barHeight = if (seekMode) 8.dp else 4.dp

    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        if (seekMode) {
            Text(
                text = formatTime(seekPosition, duration),
                style = HorrorTypography.DetailInfo,
                color = HorrorColors.HorrorWhite,
                modifier = Modifier.padding(bottom = 4.dp)
            )
        }

        BoxWithConstraints(
            modifier = Modifier
                .fillMaxWidth()
                .height(barHeight)
                .clip(RoundedCornerShape(barHeight))
                .background(HorrorColors.HorrorGray.copy(alpha = 0.6f))
        ) {
            Box(
                modifier = Modifier
                    .fillMaxWidth(if (seekMode) seekProgress else progress)
                    .height(barHeight)
                    .background(if (seekMode) Color.White else HorrorColors.HorrorRed)
            )

            if (seekMode) {
                Box(
                    modifier = Modifier
                        .offset(x = (maxWidth * seekProgress - 6.dp).coerceAtLeast(0.dp))
                        .size(12.dp)
                        .clip(RoundedCornerShape(percent = 50))
                        .background(Color.White)
                )
            }
        }
    }
}

@Composable
private fun PlayerButton(
    iconRes: Int,
    label: String,
    isFocused: Boolean,
    onClick: () -> Unit,
) {
    val scale by animateFloatAsState(
        targetValue = if (isFocused) 1.25f else 1.0f,
        animationSpec = tween(150),
        label = "btn_scale"
    )
    val interactionSource = remember { MutableInteractionSource() }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        Box(
            modifier = Modifier
                .size(64.dp)
                .graphicsLayer {
                    scaleX = scale
                    scaleY = scale
                    shadowElevation = if (isFocused) 12f else 0f
                    ambientShadowColor = HorrorColors.HorrorAccent
                    spotShadowColor = HorrorColors.HorrorAccent
                }
                .clip(ButtonShape)
                .background(if (isFocused) Color.White else HorrorColors.HorrorGray)
                .border(
                    width = if (isFocused) 5.dp else 1.dp,
                    color = if (isFocused) HorrorColors.HorrorAccent else HorrorColors.HorrorLightGray,
                    shape = ButtonShape
                )
                .clickable(
                    interactionSource = interactionSource,
                    indication = null,
                    onClick = onClick
                ),
            contentAlignment = Alignment.Center
        ) {
            Icon(
                painter = painterResource(id = iconRes),
                contentDescription = label,
                tint = if (isFocused) HorrorColors.HorrorGray else HorrorColors.HorrorWhite,
                modifier = Modifier.size(32.dp)
            )
        }

        Text(
            text = label,
            style = HorrorTypography.MovieYear,
            color = if (isFocused) Color.White else HorrorColors.HorrorLightGray
        )
    }
}

@Composable
private fun SubtitlePickerOverlay(
    options: List<SubtitleOption>,
    selectedOption: SubtitleOption,
    selectedIndex: Int,
    onOptionSelected: (SubtitleOption) -> Unit,
    onDismiss: () -> Unit
) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Black.copy(alpha = 0.7f)),
        contentAlignment = Alignment.Center
    ) {
        val scrollState = rememberScrollState()
        val density = LocalDensity.current

        // Auto-scroll to keep selected item visible
        LaunchedEffect(selectedIndex) {
            // Each item is 64dp height + 16dp spacing = 80dp
            val itemHeightPx = with(density) { 80.dp.toPx() }.toInt()
            // Title (~40dp) + spacer (8dp) + padding top (24dp) ≈ 72dp
            val headerHeightPx = with(density) { 72.dp.toPx() }.toInt()
            val targetOffset = headerHeightPx + (selectedIndex * itemHeightPx) - itemHeightPx
            scrollState.animateScrollTo(targetOffset.coerceAtLeast(0))
        }

        Column(
            modifier = Modifier
                .width(300.dp)
                .heightIn(max = 400.dp)
                .clip(RoundedCornerShape(16.dp))
                .background(HorrorColors.HorrorGray)
                .border(2.dp, HorrorColors.HorrorAccent, RoundedCornerShape(16.dp))
                .padding(24.dp)
                .verticalScroll(scrollState),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            Text(
                text = "Subtítulos",
                style = HorrorTypography.DetailTitle,
                color = HorrorColors.HorrorWhite
            )

            Spacer(modifier = Modifier.height(8.dp))

            options.forEachIndexed { index, option ->
                val isHighlighted = selectedIndex == index
                val isSelected = option == selectedOption

                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(64.dp)
                        .clip(ButtonShape)
                        .background(
                            if (isHighlighted) HorrorColors.HorrorAccent
                            else if (isSelected) HorrorColors.HorrorRed
                            else HorrorColors.HorrorLightGray
                        )
                        .border(
                            width = if (isHighlighted || isSelected) 4.dp else 1.dp,
                            color = if (isHighlighted) Color.White
                            else if (isSelected) HorrorColors.HorrorAccent
                            else HorrorColors.HorrorLightGray,
                            shape = ButtonShape
                        )
                        .clickable { onOptionSelected(option) },
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        text = option.label,
                        style = HorrorTypography.PlayButton,
                        color = HorrorColors.HorrorWhite
                    )
                }
            }
        }
    }
}

@Composable
private fun PlayerErrorOverlay(
    errorMessage: String,
    onRetry: () -> Unit,
    onBack: () -> Unit
) {
    var isRetryFocused by remember { mutableStateOf(false) }
    var isBackFocused by remember { mutableStateOf(true) }

    val retryFocusRequester = remember { FocusRequester() }
    val backFocusRequester = remember { FocusRequester() }

    LaunchedEffect(Unit) {
        delay(100)
        tryRequestFocus(backFocusRequester, "ErrorBack")
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(HorrorColors.HorrorBlack),
        contentAlignment = Alignment.Center
    ) {
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(24.dp)
        ) {
            Icon(
                painter = painterResource(id = android.R.drawable.ic_menu_close_clear_cancel),
                contentDescription = "Error",
                tint = HorrorColors.HorrorRed,
                modifier = Modifier.size(96.dp)
            )

            Text(
                text = errorMessage,
                style = HorrorTypography.DetailPlot,
                color = HorrorColors.HorrorWhite,
                modifier = Modifier.padding(horizontal = 48.dp)
            )

            Spacer(modifier = Modifier.height(32.dp))

            Row(horizontalArrangement = Arrangement.spacedBy(32.dp)) {
                PlayerActionButton(
                    label = "VOLVER",
                    isFocused = isBackFocused,
                    onClick = onBack,
                    focusRequester = backFocusRequester,
                    onFocusChange = { isBackFocused = it }
                )

                PlayerActionButton(
                    label = "REINTENTAR",
                    isFocused = isRetryFocused,
                    onClick = onRetry,
                    focusRequester = retryFocusRequester,
                    onFocusChange = { isRetryFocused = it }
                )
            }
        }
    }
}

@OptIn(ExperimentalComposeUiApi::class)
@Composable
private fun PlayerActionButton(
    label: String,
    isFocused: Boolean,
    onClick: () -> Unit,
    focusRequester: FocusRequester,
    onFocusChange: (Boolean) -> Unit
) {
    val scale = if (isFocused) 1.08f else 1.0f
    val interactionSource = remember { MutableInteractionSource() }

    Box(
        modifier = Modifier
            .width(200.dp)
            .height(64.dp)
            .graphicsLayer { scaleX = scale; scaleY = scale }
            .clip(RoundedCornerShape(12.dp))
            .background(if (isFocused) HorrorColors.HorrorAccent else HorrorColors.HorrorRed)
            .border(
                width = if (isFocused) 4.dp else 1.dp,
                color = if (isFocused) Color.White else HorrorColors.HorrorLightGray,
                shape = RoundedCornerShape(12.dp)
            )
            .focusRequester(focusRequester)
            .focusable(interactionSource = interactionSource)
            .onFocusChanged { onFocusChange(it.isFocused) }
            .onKeyEvent { event ->
                if (event.nativeKeyEvent?.action != KeyEvent.ACTION_DOWN) return@onKeyEvent false
                if (event.nativeKeyEvent?.repeatCount != 0) return@onKeyEvent false
                val keyCode = event.nativeKeyEvent?.keyCode
                if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
                    onClick()
                    true
                } else false
            },
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = label,
            style = HorrorTypography.PlayButton,
            color = HorrorColors.HorrorWhite
        )
    }
}

private fun formatTime(timeMs: Long, durationMs: Long): String {
    if (timeMs < 0 || durationMs < 0) return "00:00"

    val totalSeconds = (timeMs / 1000).toInt()
    val hours = totalSeconds / 3600
    val minutes = (totalSeconds % 3600) / 60
    val seconds = totalSeconds % 60

    val durationSeconds = (durationMs / 1000).toInt()
    val durationHours = durationSeconds / 3600

    return if (durationHours > 0 || hours > 0) {
        "%02d:%02d:%02d".format(hours, minutes, seconds)
    } else {
        "%02d:%02d".format(minutes, seconds)
    }
}