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

import android.util.Log
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.*
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.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import com.airbnb.lottie.ImageAssetDelegate
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.compose.*
import com.airbnb.lottie.sample.compose.BuildConfig
import com.airbnb.lottie.sample.compose.R
import com.airbnb.lottie.sample.compose.composables.DebouncedCircularProgressIndicator
import com.airbnb.lottie.sample.compose.ui.Teal
import com.airbnb.lottie.sample.compose.utils.drawBottomBorder
import com.airbnb.lottie.sample.compose.utils.maybeBackground
import com.airbnb.lottie.sample.compose.utils.maybeDrawBorder
import com.airbnb.lottie.sample.compose.utils.toDummyBitmap
import kotlin.math.ceil
import kotlin.math.roundToInt

@Stable
class PlayerPageState {
    var playMode by mutableStateOf(LottiePlayMode.Play)
    var outlineMasksAndMattes by mutableStateOf(false)
    var applyOpacityToLayers by mutableStateOf(false)
    var enableMergePaths by mutableStateOf(false)
    var focusMode by mutableStateOf(false)
    var showWarningsDialog by mutableStateOf(false)

    var borderToolbar by mutableStateOf(false)
    var speedToolbar by mutableStateOf(false)
    var backgroundColorToolbar by mutableStateOf(false)
}

@Composable
fun PlayerPage(
    spec: LottieCompositionSpec,
    animationBackgroundColor: Color? = null,
) {
    val scaffoldState = rememberScaffoldState()
    val state = remember { PlayerPageState() }

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

    val compositionResult = lottieComposition(spec)

    LaunchedEffect(compositionResult.isFailure) {
        if (!compositionResult.isFailure) return@LaunchedEffect
        scaffoldState.snackbarHostState.showSnackbar(
            message = failedMessage,
            actionLabel = okMessage,
        )
    }

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = { PlayerPageTopAppBar(state, compositionResult.value) },
    ) {
        PlayerPageContent(
            state,
            compositionResult.value,
            compositionResult.isLoading,
            animationBackgroundColor
        )
    }

    if (state.showWarningsDialog) {
        WarningDialog(warnings = compositionResult.value?.warnings ?: emptyList(), onDismiss = { state.showWarningsDialog = false })
    }
}

@Composable
private fun ColumnScope.ExpandVisibility(
    visible: Boolean,
    content: @Composable () -> Unit,
) {
    AnimatedVisibility(
        visible = visible,
        enter = expandVertically(),
        exit = shrinkVertically()
    ) {
        content()
    }
}

@Composable
private fun PlayerPageTopAppBar(
    state: PlayerPageState,
    composition: LottieComposition?,
) {
    val backPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher

    TopAppBar(
        title = {},
        backgroundColor = Color.Transparent,
        elevation = 0.dp,
        navigationIcon = {
            IconButton(
                onClick = { backPressedDispatcher?.onBackPressed() },
            ) {
                Icon(
                    Icons.Default.Close,
                    contentDescription = null
                )
            }
        },
        actions = {
            if (composition?.warnings?.isNotEmpty() == true) {
                IconButton(
                    onClick = { state.showWarningsDialog = true }
                ) {
                    Icon(
                        Icons.Filled.Warning,
                        tint = Color.Black,
                        contentDescription = null
                    )
                }
            }
            IconButton(
                onClick = { state.focusMode = !state.focusMode },
            ) {
                Icon(
                    Icons.Filled.RemoveRedEye,
                    tint = if (state.focusMode) Teal else Color.Black,
                    contentDescription = null
                )
            }
        }
    )
}

@Composable
fun PlayerPageContent(
    state: PlayerPageState,
    composition: LottieComposition?,
    isLoading: Boolean,
    animationBackgroundColor: Color?,
) {
    var backgroundColor by remember(animationBackgroundColor) { mutableStateOf(animationBackgroundColor) }
    val dummyBitmapStrokeWidth = with(LocalDensity.current) { 3.dp.toPx() }
    val imageAssetDelegate = remember(composition) {
        if (composition?.images?.any { (_, asset) -> asset.hasBitmap() } == true) {
            null
        } else {
            ImageAssetDelegate { if (it.hasBitmap()) null else it.toDummyBitmap(dummyBitmapStrokeWidth) }
        }
    }
    val animationState = animateLottieComposition(
        composition,
        playMode = state.playMode,
        iterations = Integer.MAX_VALUE,
    )
    LaunchedEffect(animationState.iteration, animationState.iterations) {
        Log.d("Gabe", "Iteration ${animationState.iteration}/${animationState.iterations}")
    }

    Column(
        verticalArrangement = Arrangement.SpaceBetween,
        modifier = Modifier.fillMaxHeight()
    ) {
        Box(
            contentAlignment = Alignment.Center,
            modifier = Modifier
                .weight(1f)
                .maybeBackground(backgroundColor)
                .fillMaxWidth()
        ) {
            LottieAnimation(
                composition,
                animationState.value,
                imageAssetDelegate = imageAssetDelegate,
                modifier = Modifier
                    .fillMaxSize()
                    .align(Alignment.Center)
                    .maybeDrawBorder(state.borderToolbar)
            )
            if (isLoading) {
                DebouncedCircularProgressIndicator(
                    color = Teal,
                    modifier = Modifier
                        .size(48.dp)
                )
            }
        }
        ExpandVisibility(state.speedToolbar && !state.focusMode) {
            SpeedToolbar(animationState)
        }
        ExpandVisibility(!state.focusMode && state.backgroundColorToolbar) {
            BackgroundColorToolbar(
                animationBackgroundColor = animationBackgroundColor,
                onColorChanged = { backgroundColor = it }
            )
        }
        ExpandVisibility(!state.focusMode) {
            PlayerControlsRow(composition, state, animationState)
        }
        ExpandVisibility(!state.focusMode) {
            Toolbar(state)
        }
    }
}

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

    val progressFormatted = ("%.1f").format(animationState.value * totalTime)

    val frame = composition?.getFrameForProgress(animationState.value)?.roundToInt() ?: 0
    val durationFrames = ceil(composition?.durationFrames ?: 0f).roundToInt()
    Box(
        modifier = Modifier
            .fillMaxWidth()
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Box(
                contentAlignment = Alignment.Center
            ) {
                IconButton(
                    onClick = { state.playMode = !state.playMode },
                ) {
                    Icon(
                        if (animationState.isPlaying) Icons.Filled.Pause
                        else Icons.Filled.PlayArrow,
                        contentDescription = null
                    )
                }
                Text(
                    "$frame/$durationFrames\n${progressFormatted}/$totalTimeFormatted",
                    style = TextStyle(fontSize = 8.sp),
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .padding(top = 48.dp, bottom = 8.dp)
                )
            }
            Slider(
                value = animationState.value,
                onValueChange = { animationState.value = it },
                modifier = Modifier.weight(1f)
            )
            IconButton(
                onClick = {
                    animationState.iterations = if (animationState.iterations == Integer.MAX_VALUE) 1 else Integer.MAX_VALUE
                },
            ) {
                Icon(
                    Icons.Filled.Repeat,
                    tint = if (animationState.iterations == Integer.MAX_VALUE) Teal else Color.Black,
                    contentDescription = null
                )
            }
        }
        Text(
            BuildConfig.VERSION_NAME,
            fontSize = 6.sp,
            color = Color.Gray,
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .padding(bottom = 12.dp)
        )
    }
}

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

@Composable
private fun BackgroundColorToolbar(
    animationBackgroundColor: Color?,
    onColorChanged: (Color) -> Unit,
) {
    Row(
        horizontalArrangement = Arrangement.SpaceBetween,
        modifier = Modifier
            .drawBottomBorder()
            .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)
            .size(24.dp)
            .border(1.dp, strokeColor, shape = CircleShape)
    )
}

@Composable
private fun Toolbar(state: PlayerPageState) {
    Row(
        modifier = Modifier
            .horizontalScroll(rememberScrollState())
            .padding(horizontal = 8.dp)
            .padding(bottom = 8.dp)
    ) {
        ToolbarChip(
            iconPainter = painterResource(R.drawable.ic_masks_and_mattes),
            label = stringResource(R.string.toolbar_item_masks),
            isActivated = state.outlineMasksAndMattes,
            onClick = { state.outlineMasksAndMattes = it },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            iconPainter = painterResource(R.drawable.ic_layers),
            label = stringResource(R.string.toolbar_item_opacity_layers),
            isActivated = state.applyOpacityToLayers,
            onClick = { state.applyOpacityToLayers = it },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            iconPainter = painterResource(R.drawable.ic_color),
            label = stringResource(R.string.toolbar_item_color),
            isActivated = state.backgroundColorToolbar,
            onClick = { state.backgroundColorToolbar = it },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            iconPainter = painterResource(R.drawable.ic_speed),
            label = stringResource(R.string.toolbar_item_speed),
            isActivated = state.speedToolbar,
            onClick = { state.speedToolbar = it },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            iconPainter = painterResource(R.drawable.ic_border),
            label = stringResource(R.string.toolbar_item_border),
            isActivated = state.borderToolbar,
            onClick = { state.borderToolbar = it },
            modifier = Modifier.padding(end = 8.dp)
        )
        ToolbarChip(
            iconPainter = rememberVectorPainter(Icons.Default.MergeType),
            label = stringResource(R.string.toolbar_item_merge_paths),
            isActivated = state.enableMergePaths,
            onClick = { state.enableMergePaths = 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
                .width(400.dp)
                .heightIn(min = 32.dp, max = 500.dp)
        ) {
            Box(
                contentAlignment = Alignment.TopCenter,
                modifier = Modifier
            ) {
                LazyColumn {
                    itemsIndexed(warnings) { i, warning ->
                        Text(
                            warning,
                            fontSize = 8.sp,
                            textAlign = TextAlign.Left,
                            modifier = Modifier
                                .fillMaxWidth()
                                .run { if (i != 0) drawBottomBorder() else this }
                                .padding(vertical = 12.dp, horizontal = 16.dp)
                        )
                    }
                }
            }
        }
    }
}

@Preview
@Composable
fun SpeedToolbarPreview() {
    val state = animateLottieComposition(null)
    SpeedToolbar(state)
}

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