package com.rosetta.messenger.ui.components.metaball

import android.graphics.ColorMatrixColorFilter
import android.graphics.RenderEffect
import android.graphics.Shader
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asComposeRenderEffect
import androidx.compose.ui.graphics.graphicsLayer

/**
 * Alpha threshold color matrix for metaball effect.
 * Same as GPU_ALPHA_THRESHOLD_MATRIX in ProfileMetaballOverlay:
 * newAlpha = oldAlpha * 51 - 6375 → values above ~125/255 become opaque.
 * Works on API 31+ (Android 12) — no AGSL/RuntimeShader needed.
 */
private val METABALL_ALPHA_THRESHOLD_MATRIX = floatArrayOf(
    1f, 0f, 0f, 0f, 0f,
    0f, 1f, 0f, 0f, 0f,
    0f, 0f, 1f, 0f, 0f,
    0f, 0f, 0f, 51f, 51f * -125f
)

/**
 * Container that applies the metaball alpha-threshold effect to its children.
 *
 * Children should use [customBlur] modifier to be part of the metaball effect.
 * When blurred shapes overlap, their alpha values combine,
 * exceeding the threshold and creating a merged "liquid" appearance.
 *
 * Uses ColorMatrixColorFilter instead of AGSL shader — works on API 31+ (Android 12).
 *
 * @param modifier Modifier for the container
 * @param content Composable content (should contain MetaEntity elements)
 */
@RequiresApi(Build.VERSION_CODES.S)
@Composable
fun MetaContainer(
    modifier: Modifier = Modifier,
    content: @Composable BoxScope.() -> Unit,
) {
    Box(
        modifier = modifier.graphicsLayer {
            renderEffect = RenderEffect.createColorFilterEffect(
                ColorMatrixColorFilter(METABALL_ALPHA_THRESHOLD_MATRIX)
            ).asComposeRenderEffect()
        },
        content = content,
    )
}

/**
 * Modifier that applies GPU-accelerated blur effect.
 *
 * Use this on shapes inside [MetaContainer] to create the metaball effect.
 * The blur radius determines how "soft" the edges are before threshold is applied.
 *
 * @param blur Blur radius in pixels. Higher = softer edges, larger merge area
 */
@RequiresApi(Build.VERSION_CODES.S)
fun Modifier.customBlur(blur: Float) = this.then(
    graphicsLayer {
        if (blur > 0f) {
            renderEffect = RenderEffect
                .createBlurEffect(
                    blur,
                    blur,
                    Shader.TileMode.CLAMP,
                )
                .asComposeRenderEffect()
        }
    }
)

/**
 * A composable that wraps content with metaball-capable blur.
 *
 * This creates a layered effect:
 * - metaContent: The blurred shape that participates in metaball merging
 * - content: The actual visible content (not blurred)
 *
 * @param modifier Modifier for the entity
 * @param blur Blur radius for the metaball effect
 * @param metaContent The shape that will be blurred and merged (usually a solid color Box)
 * @param content The visible content rendered on top
 */
@RequiresApi(Build.VERSION_CODES.S)
@Composable
fun MetaEntity(
    modifier: Modifier = Modifier,
    blur: Float = 30f,
    metaContent: @Composable BoxScope.() -> Unit,
    content: @Composable BoxScope.() -> Unit = {},
) {
    Box(modifier = modifier) {
        Box(
            modifier = Modifier.customBlur(blur),
            content = metaContent,
        )
        content()
    }
}
