package com.airbnb.lottie.sample.compose.player

import androidx.activity.OnBackPressedDispatcher
import androidx.compose.foundation.ScrollableColumn
import androidx.compose.foundation.ScrollableRow
import androidx.compose.foundation.Text
import androidx.compose.foundation.background
import androidx.compose.foundation.border
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.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.preferredSize
import androidx.compose.foundation.layout.preferredWidth
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.RemoveRedEye
import androidx.compose.material.icons.filled.Repeat
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedTask
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Providers
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.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.ui.tooling.preview.Preview
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieAnimationSpec
import com.airbnb.lottie.compose.LottieAnimationState
import com.airbnb.lottie.compose.LottieCompositionResult
import com.airbnb.lottie.compose.rememberLottieAnimationState
import com.airbnb.lottie.compose.rememberLottieComposition
import com.airbnb.lottie.sample.compose.BackPressedDispatcherAmbient
import com.airbnb.lottie.sample.compose.R
import com.airbnb.lottie.sample.compose.composables.DebouncedCircularProgressIndicator
import com.airbnb.lottie.sample.compose.composables.SeekBar
import com.airbnb.lottie.sample.compose.ui.Teal
import com.airbnb.lottie.sample.compose.utils.drawTopBorder
import com.airbnb.lottie.sample.compose.utils.maybeBackground
import com.airbnb.lottie.sample.compose.utils.maybeDrawBorder
import com.airbnb.lottie.sample.compose.utils.quantityStringResource
import kotlin.math.ceil
import kotlin.math.roundToInt

@Composable
fun PlayerPage(
    spec: LottieAnimationSpec,
    animationBackgroundColor: Color? = null,
) {
    val backPressedDispatcher = BackPressedDispatcherAmbient.current
    val compositionResult = rememberLottieComposition(spec)
    val animationState = rememberLottieAnimationState(autoPlay = true, repeatCount = Integer.MAX_VALUE)
    val scaffoldState = rememberScaffoldState()
    var focusMode by remember { mutableStateOf(false) }
    var backgroundColor by remember { mutableStateOf(animationBackgroundColor) }

    val borderToolbar = remember { mutableStateOf(false) }
    val speedToolbar = remember { mutableStateOf(false) }
    val backgroundColorToolbar = remember { mutableStateOf(false) }

    val failedMessage = stringResource(R.string.failed_to_load)
    val okMessage = stringResource(R.string.ok)

    LaunchedTask(compositionResult) {
        if (compositionResult is LottieCompositionResult.Fail) {
            scaffoldState.snackbarHostState.showSnackbar(
                message = failedMessage,
                actionLabel = okMessage,
            )
        }
    }

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = {
            TopAppBar(
                title = {},
                backgroundColor = Color.Transparent,
                elevation = 0.dp,
                navigationIcon = {
                    IconButton(
                        onClick = { backPressedDispatcher.onBackPressed() },
                    ) {
                        Icon(Icons.Default.Close)
                    }
                },
                actions = {
                    IconButton(
                        onClick = { focusMode = !focusMode },
                    ) {
                        Icon(
                            Icons.Filled.RemoveRedEye,
                            tint = if (focusMode) Teal else Color.Black,
                        )
                    }
                }
            )
        },
    ) {
        Column(
            verticalArrangement = Arrangement.SpaceBetween,
            modifier = Modifier.fillMaxHeight()
        ) {
            Box(
                alignment = Alignment.Center,
                modifier = Modifier
                    .weight(1f)
                    .maybeBackground(backgroundColor)
                    .fillMaxWidth()
            ) {
                LottieAnimation(
                    compositionResult,
                    animationState,
                    modifier = Modifier
                        .fillMaxSize()
                        .align(Alignment.Center)
                        .maybeDrawBorder(borderToolbar.value)
                )
                if (compositionResult is LottieCompositionResult.Loading) {
                    DebouncedCircularProgressIndicator(
                        color = Teal,
                        modifier = Modifier
                            .preferredSize(48.dp)
                    )
                }
            }
            if (speedToolbar.value && !focusMode) {
                SpeedToolbar(
                    speed = animationState.speed,
                    onSpeedChanged = { animationState.speed = it }
                )
            }
            if (backgroundColorToolbar.value && !focusMode) {
                BackgroundColorToolbar(
                    animationBackgroundColor = animationBackgroundColor,
                    onColorChanged = { backgroundColor = it }
                )
            }
            if (!focusMode) {
                PlayerControlsRow(animationState, compositionResult())
                Toolbar(
                    border = borderToolbar,
                    speed = speedToolbar,
                    backgroundColor = backgroundColorToolbar,
                    warnings = compositionResult()?.warnings ?: emptyList()
                )
            }
        }
    }
}

@Composable
private fun PlayerControlsRow(
    animationState: LottieAnimationState,
    composition: LottieComposition?,
) {
    val totalTime = ((composition?.duration ?: 0L / animationState.speed) / 1000.0)
    val totalTimeFormatted = ("%.1f").format(totalTime)

    val progress = (totalTime / 100.0) * ((animationState.progress * 100.0).roundToInt())
    val progressFormatted = ("%.1f").format(progress)

    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .drawTopBorder()
    ) {
        Box(
            alignment = Alignment.Center
        ) {
            IconButton(
                onClick = { animationState.toggleIsPlaying() },
            ) {
                Icon(if (animationState.isPlaying) Icons.Filled.Pause else Icons.Filled.PlayArrow)
            }
            Text(
                "${animationState.frame}/${ceil(composition?.durationFrames ?: 0f).toInt()}\n${progressFormatted}/$totalTimeFormatted",
                style = TextStyle(fontSize = 8.sp),
                textAlign = TextAlign.Center,
                modifier = Modifier
                    .padding(top = 48.dp, bottom = 8.dp)
            )
        }
        SeekBar(
            progress = animationState.progress,
            onProgressChanged = {
                animationState.progress = it
            },
            modifier = Modifier.weight(1f)
        )
        IconButton(onClick = {
            val repeatCount = if (animationState.repeatCount == Integer.MAX_VALUE) 0 else Integer.MAX_VALUE
            animationState.repeatCount = repeatCount
        }) {
            Icon(
                Icons.Filled.Repeat,
                tint = if (animationState.repeatCount > 0) Teal else Color.Black,
            )
        }
    }
}

@Composable
private fun SpeedToolbar(
    speed: Float,
    onSpeedChanged: (Float) -> Unit,
) {
    Row(
        horizontalArrangement = Arrangement.SpaceBetween,
        modifier = Modifier
            .drawTopBorder()
            .padding(vertical = 12.dp, horizontal = 16.dp)
            .fillMaxWidth()
    ) {
        ToolbarChip(
            label = "0.5x",
            isActivated = speed == 0.5f,
            onClick = { onSpeedChanged(0.5f) },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            label = "1x",
            isActivated = speed == 1f,
            onClick = { onSpeedChanged(1f) },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            label = "1.5x",
            isActivated = speed == 1.5f,
            onClick = { onSpeedChanged(1.5f) },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            label = "2x",
            isActivated = speed == 2f,
            onClick = { onSpeedChanged(2f) },
            modifier = Modifier.padding(end = 8.dp)
        )
    }
}

@Composable
private fun BackgroundColorToolbar(
    animationBackgroundColor: Color?,
    onColorChanged: (Color) -> Unit,
) {
    Row(
        horizontalArrangement = Arrangement.SpaceBetween,
        modifier = Modifier
            .drawTopBorder()
            .padding(vertical = 12.dp, horizontal = 16.dp)
            .fillMaxWidth()
    ) {
        listOfNotNull(
            colorResource(R.color.background_color1),
            colorResource(R.color.background_color2),
            colorResource(R.color.background_color3),
            colorResource(R.color.background_color4),
            colorResource(R.color.background_color5),
            colorResource(R.color.background_color6),
            animationBackgroundColor.takeIf { it != Color.White },
        ).forEachIndexed { i, color ->
            val strokeColor = if (i == 0) colorResource(R.color.background_color1_stroke) else color
            BackgroundToolbarItem(
                color = color,
                strokeColor = strokeColor,
                onClick = { onColorChanged(color) }
            )
        }
    }
}

@Composable
private fun BackgroundToolbarItem(
    color: Color,
    strokeColor: Color = color,
    onClick: () -> Unit,
) {
    Box(
        modifier = Modifier
            .clip(CircleShape)
            .background(color)
            .clickable(onClick = onClick)
            .preferredSize(24.dp)
            .border(1.dp, strokeColor, shape = CircleShape)
    )
}

@Composable
private fun Toolbar(
    border: MutableState<Boolean>,
    speed: MutableState<Boolean>,
    backgroundColor: MutableState<Boolean>,
    warnings: List<String>,
) {
    var showWarningsDialog by remember { mutableStateOf(false) }

    if (showWarningsDialog) {
        WarningDialog(warnings = warnings, onDismiss = { showWarningsDialog = false })
    }

    ScrollableRow(
        contentPadding = PaddingValues(start = 16.dp, top = 12.dp, end = 16.dp, bottom = 12.dp),
        modifier = Modifier
            .drawTopBorder()
            .fillMaxWidth()
    ) {
        if (warnings.isNotEmpty()) {
            ToolbarChip(
                iconRes = R.drawable.ic_warning,
                label = quantityStringResource(R.plurals.toolbar_item_warning, warnings.size, warnings.size),
                isActivated = true,
                onClick = { showWarningsDialog = true },
                modifier = Modifier.padding(end = 8.dp)
            )
        }
        ToolbarChip(
            iconRes = R.drawable.ic_border,
            label = stringResource(R.string.toolbar_item_border),
            isActivated = border.value,
            onClick = { border.value = it },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            iconRes = R.drawable.ic_speed,
            label = stringResource(R.string.toolbar_item_speed),
            isActivated = speed.value,
            onClick = { speed.value = it },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            iconRes = R.drawable.ic_color,
            label = stringResource(R.string.toolbar_item_color),
            isActivated = backgroundColor.value,
            onClick = { backgroundColor.value = it },
            modifier = Modifier.padding(end = 8.dp)
        )
    }
}

@Composable
fun WarningDialog(
    warnings: List<String>,
    onDismiss: () -> Unit,
) {
    Dialog(onDismissRequest = onDismiss) {
        Surface(
            shape = RoundedCornerShape(4.dp),
            modifier = Modifier
                .preferredWidth(400.dp)
                .heightIn(min = 32.dp, max = 500.dp)
        ) {
            Box(
                alignment = Alignment.TopCenter,
                modifier = Modifier
            ) {
                ScrollableColumn {
                    warnings.forEachIndexed { i, warning ->
                        Text(
                            warning,
                            fontSize = 8.sp,
                            textAlign = TextAlign.Left,
                            modifier = Modifier
                                .fillMaxWidth()
                                .run { if (i != 0) drawTopBorder() else this }
                                .padding(vertical = 12.dp, horizontal = 16.dp)
                        )
                    }
                }
            }
        }
    }
}

@Preview
@Composable
fun SpeedToolbarPreview() {
    SpeedToolbar(speed = 1f, onSpeedChanged = {})
}

@Preview(name = "Player")
@Composable
fun PlayerPagePreview() {
    Providers(
        BackPressedDispatcherAmbient provides OnBackPressedDispatcher()
    ) {
        PlayerPage(LottieAnimationSpec.Url("https://lottiefiles.com/download/public/32922"))
    }
}