package com.horrortv.app.presentation.player

import androidx.activity.compose.BackHandler
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.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.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
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.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.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.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
import com.horrortv.app.domain.model.VideoSource
import com.horrortv.app.domain.usecase.VideoExtractor
import com.horrortv.app.presentation.theme.HorrorColors
import com.horrortv.app.presentation.theme.HorrorTypography
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import android.util.Log

private const val TAG = "PlayerScreen"
private val ButtonShape = RoundedCornerShape(12.dp)

@OptIn(ExperimentalMaterial3Api::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 isPlaying by remember { mutableStateOf(false) }
    var currentTimeMs by remember { mutableLongStateOf(0L) }
    var durationMs by remember { mutableLongStateOf(0L) }
    
    val playFocusRequester = remember { FocusRequester() }
    val backFocusRequester = remember { FocusRequester() }
    
    val exoPlayer = remember { ExoPlayer.Builder(context).build() }
    
    LaunchedEffect(imdbId) {
        scope.launch {
            try {
                isLoading = true
                hasError = false
                
                val result = withContext(Dispatchers.IO) {
                    VideoExtractor().extractVideoSource(imdbId)
                }
                
                result.fold(
                    onSuccess = { source ->
                        videoSource = source
                        val mediaItem = MediaItem.fromUri(source.videoUrl)
                        exoPlayer.setMediaItem(mediaItem)
                        exoPlayer.prepare()
                        exoPlayer.playWhenReady = true
                        isLoading = false
                    },
                    onFailure = { error ->
                        hasError = true
                        errorMessage = "Error: ${error.message}"
                        isLoading = false
                    }
                )
            } 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 = exoPlayer.duration
                    }
                    Player.STATE_BUFFERING -> isLoading = true
                    Player.STATE_ENDED -> isPlaying = false
                }
            }
        }
        exoPlayer.addListener(listener)
        onDispose {
            exoPlayer.removeListener(listener)
            exoPlayer.release()
        }
    }
    
    LaunchedEffect(showControls, isPlaying) {
        if (showControls && isPlaying) {
            delay(4000)
            showControls = false
        }
    }
    
    LaunchedEffect(isPlaying) {
        while (isPlaying) {
            currentTimeMs = exoPlayer.currentPosition
            delay(500)
        }
    }
    
    BackHandler(enabled = true) { onNavigateBack() }
    
    LaunchedEffect(!isLoading, showControls) {
        if (!isLoading && showControls) {
            delay(300)
            try {
                playFocusRequester.requestFocus()
            } catch (e: IllegalStateException) {
                Log.d(TAG, "FocusRequester not ready yet, will retry")
            }
        }
    }
    
    Box(
        modifier = modifier.fillMaxSize().background(HorrorColors.HorrorBlack)
    ) {
        if (hasError) {
            PlayerErrorOverlay(
                errorMessage = errorMessage,
                onRetry = {
                    hasError = false
                    isLoading = true
                    scope.launch {
                        val result = withContext(Dispatchers.IO) {
                            VideoExtractor().extractVideoSource(imdbId)
                        }
                        result.fold(
                            onSuccess = { source ->
                                videoSource = source
                                val mediaItem = MediaItem.fromUri(source.videoUrl)
                                exoPlayer.setMediaItem(mediaItem)
                                exoPlayer.prepare()
                                exoPlayer.playWhenReady = true
                                isLoading = false
                            },
                            onFailure = { error ->
                                hasError = true
                                errorMessage = "Error: ${error.message}"
                                isLoading = false
                            }
                        )
                    }
                },
                onBack = onNavigateBack
            )
        } else {
            AndroidView(
                factory = { ctx ->
                    PlayerView(ctx).apply {
                        player = exoPlayer
                        useController = false
                    }
                },
                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(
                    isPlaying = isPlaying,
                    currentTime = currentTimeMs,
                    duration = durationMs,
                    onPlayPause = {
                        if (isPlaying) exoPlayer.pause() else exoPlayer.play()
                        showControls = true
                    },
                    onSeekForward = { exoPlayer.seekTo(exoPlayer.currentPosition + 10000) },
                    onSeekBackward = { exoPlayer.seekTo(exoPlayer.currentPosition - 10000) },
                    onBack = onNavigateBack,
                    playFocusRequester = playFocusRequester,
                    backFocusRequester = backFocusRequester
                )
            }
        }
    }
}

@Composable
private fun PlayerControlsOverlay(
    isPlaying: Boolean,
    currentTime: Long,
    duration: Long,
    onPlayPause: () -> Unit,
    onSeekForward: () -> Unit,
    onSeekBackward: () -> Unit,
    onBack: () -> Unit,
    playFocusRequester: FocusRequester,
    backFocusRequester: FocusRequester
) {
    var isPlayFocused by remember { mutableStateOf(false) }
    var isBackFocused by remember { mutableStateOf(false) }
    var isForwardFocused by remember { mutableStateOf(false) }
    var isBackwardFocused by remember { mutableStateOf(false) }
    
    val playInteraction = remember { MutableInteractionSource() }
    val backInteraction = remember { MutableInteractionSource() }
    val forwardInteraction = remember { MutableInteractionSource() }
    val backwardInteraction = remember { MutableInteractionSource() }
    
    val currentSec = (currentTime / 1000).toInt()
    val durationSec = (duration / 1000).toInt()
    
    Box(modifier = Modifier.fillMaxSize()) {
        Row(
            modifier = Modifier.align(Alignment.TopStart).padding(24.dp),
            horizontalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            PlayerButton(
                iconRes = android.R.drawable.ic_menu_close_clear_cancel,
                label = "BACK",
                isFocused = isBackFocused,
                onClick = onBack,
                focusRequester = backFocusRequester,
                interactionSource = backInteraction,
                onFocusChange = { isBackFocused = it }
            )
        }
        
        Column(
            modifier = Modifier.align(Alignment.BottomCenter).fillMaxWidth().padding(bottom = 48.dp, start = 48.dp, end = 48.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Text(text = formatTime(currentSec), style = HorrorTypography.DetailInfo, color = HorrorColors.HorrorWhite)
                Text(text = formatTime(durationSec), style = HorrorTypography.DetailInfo, color = HorrorColors.HorrorWhite)
            }
            
            Spacer(modifier = Modifier.height(32.dp))
            
            Row(
                horizontalArrangement = Arrangement.spacedBy(24.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                PlayerButton(
                    iconRes = android.R.drawable.ic_media_previous,
                    label = "-10s",
                    isFocused = isBackwardFocused,
                    onClick = onSeekBackward,
                    focusRequester = FocusRequester(),
                    interactionSource = backwardInteraction,
                    onFocusChange = { isBackwardFocused = it }
                )
                
                PlayerButton(
                    iconRes = if (isPlaying) android.R.drawable.ic_media_pause else android.R.drawable.ic_media_play,
                    label = if (isPlaying) "PAUSE" else "PLAY",
                    isFocused = isPlayFocused,
                    onClick = onPlayPause,
                    focusRequester = playFocusRequester,
                    interactionSource = playInteraction,
                    onFocusChange = { isPlayFocused = it }
                )
                
                PlayerButton(
                    iconRes = android.R.drawable.ic_media_next,
                    label = "+10s",
                    isFocused = isForwardFocused,
                    onClick = onSeekForward,
                    focusRequester = FocusRequester(),
                    interactionSource = forwardInteraction,
                    onFocusChange = { isForwardFocused = it }
                )
            }
        }
    }
}

@Composable
private fun PlayerButton(
    iconRes: Int,
    label: String,
    isFocused: Boolean,
    onClick: () -> Unit,
    focusRequester: FocusRequester,
    interactionSource: MutableInteractionSource,
    onFocusChange: (Boolean) -> Unit
) {
    val scale = if (isFocused) 1.1f else 1.0f
    
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        Box(
            modifier = Modifier
                .size(64.dp)
                .graphicsLayer { scaleX = scale; scaleY = scale }
                .clip(ButtonShape)
                .background(if (isFocused) HorrorColors.HorrorAccent else HorrorColors.HorrorGray)
                .border(if (isFocused) 4.dp else 1.dp, if (isFocused) Color.White else HorrorColors.HorrorLightGray, ButtonShape)
                .focusRequester(focusRequester)
                .focusable(interactionSource = interactionSource)
                .onFocusChanged { onFocusChange(it.isFocused) }
                .clickable(interactionSource = interactionSource, indication = null, onClick = onClick),
            contentAlignment = Alignment.Center
        ) {
            Icon(
                painter = painterResource(id = iconRes),
                contentDescription = label,
                tint = HorrorColors.HorrorWhite,
                modifier = Modifier.size(32.dp)
            )
        }
        
        Text(
            text = label,
            style = HorrorTypography.MovieYear,
            color = if (isFocused) HorrorColors.HorrorWhite else HorrorColors.HorrorLightGray
        )
    }
}

@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) { backFocusRequester.requestFocus() }
    
    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 }
                )
            }
        }
    }
}

@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(if (isFocused) 4.dp else 1.dp, if (isFocused) Color.White else HorrorColors.HorrorLightGray, RoundedCornerShape(12.dp))
            .focusRequester(focusRequester)
            .focusable(interactionSource = interactionSource)
            .onFocusChanged { onFocusChange(it.isFocused) }
            .clickable(interactionSource = interactionSource, indication = null, onClick = onClick),
        contentAlignment = Alignment.Center
    ) {
        Text(text = label, style = HorrorTypography.PlayButton, color = HorrorColors.HorrorWhite)
    }
}

private fun formatTime(seconds: Int): String {
    val mins = seconds / 60
    val secs = seconds % 60
    return "%02d:%02d".format(mins, secs)
}