package com.gmplayer.app

import android.net.Uri
import android.os.Bundle
import android.widget.VideoView
import androidx.activity.compose.BackHandler
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
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.Row
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.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.lightColorScheme
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.mutableStateListOf
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.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import kotlinx.coroutines.delay

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            GMPlayerApp()
        }
    }
}

@Composable
private fun GMPlayerApp() {
    MaterialTheme(
        colorScheme = lightColorScheme(
            primary = Color(0xFF266C72),
            background = Color(0xFFF4F7F8),
            surface = Color.White
        )
    ) {
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colorScheme.background
        ) {
            PlayerScreen()
        }
    }
}

@Composable
private fun PlayerScreen() {
    var inputValue by remember { mutableStateOf("") }
    var message by remember { mutableStateOf("") }
    var isError by remember { mutableStateOf(false) }
    var playingUrl by remember { mutableStateOf<String?>(null) }
    val recentUrls = remember { mutableStateListOf<String>() }

    fun addUrl(rawValue: String) {
        val url = rawValue.trim()
        if (!isSupportedVideoUrl(url)) {
            isError = true
            message = "Enter a valid http or https video URL ending in .m3u8 or .mp4."
            return
        }

        isError = false
        message = "Added ${Uri.parse(url).lastPathSegment ?: url}"
        recentUrls.remove(url)
        recentUrls.add(0, url)
        while (recentUrls.size > 3) {
            recentUrls.removeAt(recentUrls.lastIndex)
        }
        playingUrl = url
    }

    playingUrl?.let { url ->
        AndroidPlayerScreen(
            url = url,
            onClose = { playingUrl = null }
        )
        return
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(horizontal = 20.dp, vertical = 28.dp),
        verticalArrangement = Arrangement.spacedBy(18.dp)
    ) {
        Text(
            text = "Video URLs",
            style = MaterialTheme.typography.headlineMedium,
            fontWeight = FontWeight.Bold
        )
        Text(
            text = "Enter an mp4 or m3u8 video URL to keep it in the list.",
            style = MaterialTheme.typography.bodyMedium,
            color = Color(0xFF5E6A70)
        )
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(10.dp)
        ) {
            OutlinedTextField(
                value = inputValue,
                onValueChange = { inputValue = it },
                modifier = Modifier.weight(1f),
                singleLine = true,
                placeholder = { Text("https://example.com/video.m3u8") },
                keyboardOptions = KeyboardOptions(
                    capitalization = KeyboardCapitalization.None,
                    keyboardType = KeyboardType.Uri,
                    imeAction = ImeAction.Go
                ),
                keyboardActions = KeyboardActions(onGo = { addUrl(inputValue) })
            )
            Button(
                onClick = { addUrl(inputValue) },
                colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary),
                shape = RoundedCornerShape(8.dp)
            ) {
                Text("Add", fontWeight = FontWeight.SemiBold)
            }
        }
        if (message.isNotBlank()) {
            Text(
                text = message,
                style = MaterialTheme.typography.bodySmall,
                color = if (isError) Color(0xFFC62828) else Color(0xFF5E6A70)
            )
        }
        Text(
            text = "History",
            style = MaterialTheme.typography.titleMedium,
            fontWeight = FontWeight.SemiBold
        )
        if (recentUrls.isEmpty()) {
            QueueItem("No videos added yet", enabled = false, onClick = {})
        } else {
            recentUrls.forEach { url ->
                QueueItem(url, enabled = true) {
                    inputValue = url
                }
            }
        }
    }
}

@Composable
private fun AndroidPlayerScreen(url: String, onClose: () -> Unit) {
    var controlsVisible by remember { mutableStateOf(true) }
    var autoHideTick by remember { mutableLongStateOf(0L) }
    var controllerState by remember { mutableStateOf(MobileMainControllerState.Play) }
    var videoView by remember { mutableStateOf<VideoView?>(null) }

    fun registerControlsInteraction() {
        controlsVisible = true
        autoHideTick += 1
    }

    BackHandler(onBack = onClose)

    LaunchedEffect(controlsVisible, autoHideTick) {
        if (controlsVisible) {
            delay(4_000)
            controlsVisible = false
        }
    }

    DisposableEffect(Unit) {
        onDispose {
            videoView?.stopPlayback()
        }
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .clickable {
                controlsVisible = !controlsVisible
                if (controlsVisible) {
                    autoHideTick += 1
                }
            },
        contentAlignment = Alignment.Center
    ) {
        AndroidView(
            modifier = Modifier.fillMaxSize(),
            factory = { context ->
                VideoView(context).apply {
                    setVideoURI(Uri.parse(url))
                    setOnPreparedListener { mediaPlayer ->
                        mediaPlayer.isLooping = false
                        start()
                        controllerState = MobileMainControllerState.Pause
                        registerControlsInteraction()
                    }
                    setOnCompletionListener {
                        controllerState = MobileMainControllerState.Replay
                        controlsVisible = true
                    }
                    videoView = this
                }
            },
            update = { view ->
                if (videoView !== view) {
                    videoView = view
                }
            }
        )

        AnimatedVisibility(
            visible = controlsVisible,
            enter = fadeIn(animationSpec = tween(durationMillis = 220)),
            exit = fadeOut(animationSpec = tween(durationMillis = 220)),
            modifier = Modifier.align(Alignment.Center)
        ) {
            MobilePlaybackControls(
                state = controllerState,
                onBack15 = {
                    registerControlsInteraction()
                    videoView?.let { view ->
                        view.seekTo((view.currentPosition - 15_000).coerceAtLeast(0))
                    }
                },
                onMainClick = {
                    registerControlsInteraction()
                    videoView?.let { view ->
                        when (controllerState) {
                            MobileMainControllerState.Replay -> {
                                view.seekTo(0)
                                view.start()
                                controllerState = MobileMainControllerState.Pause
                            }
                            MobileMainControllerState.Pause -> {
                                view.pause()
                                controllerState = MobileMainControllerState.Play
                            }
                            MobileMainControllerState.Play -> {
                                view.start()
                                controllerState = MobileMainControllerState.Pause
                            }
                        }
                    }
                },
                onForward15 = {
                    registerControlsInteraction()
                    videoView?.let { view ->
                        val duration = view.duration.takeIf { it > 0 } ?: Int.MAX_VALUE
                        view.seekTo((view.currentPosition + 15_000).coerceAtMost(duration))
                    }
                },
                onPrevious = { registerControlsInteraction() },
                onNext = { registerControlsInteraction() }
            )
        }

        AnimatedVisibility(
            visible = controlsVisible,
            enter = fadeIn(animationSpec = tween(durationMillis = 220)),
            exit = fadeOut(animationSpec = tween(durationMillis = 220)),
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .height(106.dp)
                .clickable { registerControlsInteraction() }
        ) {
            MobileProgressBarInfo(
                title = Uri.parse(url).lastPathSegment ?: "Internet Video",
                info = "",
                currentTime = "--:--",
                totalTime = "--:--",
                progress = 0f,
                showInfo = false
            )
        }
    }
}

@Composable
private fun QueueItem(title: String, enabled: Boolean, onClick: () -> Unit) {
    Surface(
        onClick = onClick,
        enabled = enabled,
        modifier = Modifier.fillMaxWidth(),
        color = MaterialTheme.colorScheme.surface,
        shape = RoundedCornerShape(8.dp)
    ) {
        Text(
            text = title,
            modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp),
            style = MaterialTheme.typography.bodyLarge,
            color = if (enabled) Color.Black else Color(0xFF8A8F94),
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
    }
}

private fun isSupportedVideoUrl(value: String): Boolean {
    val uri = Uri.parse(value)
    val scheme = uri.scheme?.lowercase()
    if (scheme != "http" && scheme != "https") return false
    val path = uri.path?.lowercase().orEmpty()
    return path.endsWith(".m3u8") || path.endsWith(".mp4")
}

@Preview(showBackground = true)
@Composable
private fun PlayerScreenPreview() {
    GMPlayerApp()
}
