package com.pixelized.biblib.ui.composable

import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.pullrefresh.PullRefreshState
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.unit.Dp
import androidx.compose.ui.unit.dp

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun Loader(
    modifier: Modifier = Modifier,
    isLoading: State<Boolean>,
    refreshState: PullRefreshState
) {
    val state = rememberLoaderState(refreshState)

    Box(
        modifier = modifier,
        contentAlignment = Alignment.Center,
    ) {
        Divider()

        Crossfade(targetState = isLoading.value) { loading ->
            if (loading) {
                LinearProgressIndicator(
                    modifier = Modifier
                        .fillMaxWidth()
                        .clip(shape = CircleShape)
                )
            } else {
                Box(
                    modifier = Modifier
                        .height(height = state.height)
                        .fillMaxWidth(fraction = state.faction)
                        .background(
                            shape = CircleShape,
                            color = state.color,
                        )
                )
            }
        }
    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun rememberLoaderState(
    refreshState: PullRefreshState,
): LoaderState {
    val color = MaterialTheme.colors.primary

    val state by remember {
        derivedStateOf {
            LoaderState(
                color = color.copy(
                    alpha = (3f * refreshState.progress / 4f + 0.25f).coerceIn(0f, 1f))
                ,
                height = 1.dp + 2.dp * refreshState.progress,
                faction = refreshState.progress * 0.75f,
            )
        }
    }
    return state
}

@Stable
data class LoaderState(
    val color: Color,
    val height: Dp,
    val faction: Float,
)