package dev.ulfrx.recipe.ui.components.glass

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import dev.ulfrx.recipe.ui.theme.RecipeGlassStyle
import dev.ulfrx.recipe.ui.theme.RecipeTheme
import io.github.fletchmckee.liquid.liquefiable
import io.github.fletchmckee.liquid.liquid

/**
 * @param recordAsSource Also register this surface as a Liquid source so other
 *   [GlassSurface]s sampling the same backdrop see this surface's refracted
 *   output — needed for nested glass-on-glass (e.g. a press overlay over the
 *   dock substrate). Liquid's ancestor-exclusion prevents this surface from
 *   sampling itself; outside its bounds it contributes nothing, so siblings
 *   that extend past the source's edges fall back to the shell backdrop
 *   seamlessly.
 */
@Composable
fun GlassSurface(
    modifier: Modifier = Modifier,
    cornerRadius: Dp = 28.dp,
    glassStyle: RecipeGlassStyle = RecipeTheme.glass.dock,
    recordAsSource: Boolean = false,
    content: @Composable BoxScope.() -> Unit,
) {
    val backdropState = LocalGlassBackdropState.current
    val shape = RoundedCornerShape(cornerRadius)
    Box(
        modifier =
            modifier
                .clip(shape)
                .then(if (recordAsSource) Modifier.liquefiable(backdropState.liquidState) else Modifier)
                .liquid(backdropState.liquidState) {
                    refraction = glassStyle.refraction
                    curve = glassStyle.curve
                    edge = glassStyle.edge
                    dispersion = glassStyle.dispersion
                    saturation = glassStyle.saturation
                    contrast = glassStyle.contrast
                    frost = glassStyle.frost
                    this.shape = shape
                    glassStyle.tint?.let { this.tint = it }
                },
        content = content,
    )
}
