package dev.kaizen.app.chat

import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.BlurredEdgeTreatment
import androidx.compose.ui.draw.blur
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.draw.scale
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import dev.kaizen.app.ui.motion.Durations
import dev.kaizen.app.ui.sensor.rememberTiltState
import dev.kaizen.app.ui.theme.LocalKaizenAccent
import dev.kaizen.app.ui.theme.DITHER_ALPHA
import dev.kaizen.app.ui.theme.rememberDitherBrush

/** Mesh/blob background: large, heavily blurred color circles that drift slowly. */
@Composable
fun MeshBackground(animateBlobs: Boolean = true, content: @Composable BoxScope.() -> Unit) {
    val dark = isSystemInDarkTheme()
    val accent = LocalKaizenAccent.current
    val base = MaterialTheme.colorScheme.background
    val factor = if (dark) 1f else 0.78f

    val drift = if (animateBlobs) {
        val transition = rememberInfiniteTransition(label = "blobs")
        val d by transition.animateFloat(
            initialValue = 0f,
            targetValue = 1f,
            animationSpec = infiniteRepeatable(tween(22000, easing = LinearEasing), RepeatMode.Reverse),
            label = "drift",
        )
        d
    } else {
        0.5f
    }

    val ditherBrush = rememberDitherBrush()
    Box(
        Modifier
            .fillMaxSize()
            .background(base)
            .drawWithContent {
                drawContent()
                drawRect(brush = ditherBrush, alpha = DITHER_ALPHA)
            },
    ) {
        Blob(accent.blob1, 440.dp, (-80f + drift * 40f).dp, (-60f + drift * 30f).dp, 0.48f * factor)
        Blob(accent.blob2, 460.dp, (140f - drift * 50f).dp, (200f + drift * 50f).dp, 0.40f * factor)
        Blob(accent.blob3, 400.dp, (-30f + drift * 60f).dp, (450f - drift * 40f).dp, 0.36f * factor)
        Blob(accent.blob4, 420.dp, (180f + drift * 40f).dp, (620f - drift * 44f).dp, 0.38f * factor)
        if (dark) {
            Box(
                Modifier.fillMaxSize().background(
                    Brush.radialGradient(listOf(Color.Transparent, base.copy(alpha = 0.35f))),
                ),
            )
        }
        content()
    }
}

@Composable
private fun BoxScope.Blob(color: Color, size: Dp, x: Dp, y: Dp, alpha: Float) {
    Box(
        Modifier
            .offset(x, y)
            .size(size)
            .blur(96.dp, BlurredEdgeTreatment.Unbounded)
            .background(
                Brush.radialGradient(listOf(color.copy(alpha = alpha), Color.Transparent)),
                CircleShape,
            ),
    )
}

/** 
 * Reusable masterclass liquid-glass orb (hero + assistant avatar + Call-Mode-Orb).
 * 
 * Includes high-fidelity GPU-accelerated graphic layering matching the web version exactly,
 * plus **Native Gyroscope Parallax**: reads the device's tilt sensors and smoothly offsets the
 * specular highlights and inner refraction, creating an interactive, holographic 3D glass effect!
 */
@Composable
fun KaizenOrb(
    size: Dp,
    modifier: Modifier = Modifier,
    streaming: Boolean = false,
    recording: Boolean = false,
    amplitude: Float? = null
) {
    val isDark = isSystemInDarkTheme()
    val accent = LocalKaizenAccent.current
    val transition = rememberInfiniteTransition(label = "orb")
    
    // Slow breathing loop (7s for idle, 2.4s fast breath for streaming/recording thinking)
    val scale by transition.animateFloat(
        initialValue = 1f,
        targetValue = if (streaming || recording) 1.05f else 1.025f,
        animationSpec = infiniteRepeatable(
            tween(if (streaming || recording) Durations.ORB_BREATH_STREAMING else Durations.ORB_BREATH, easing = FastOutSlowInEasing),
            RepeatMode.Reverse,
        ),
        label = "breath",
    )

    val reactiveScale = amplitude?.let { 1f + it * 0.12f } ?: 1f

    val tilt by rememberTiltState()
    val tiltX = tilt.x
    val tiltY = tilt.y

    Box(
        modifier = modifier
            .size(size)
            .scale(scale * reactiveScale)
            .pointerInput(Unit) {},
        contentAlignment = Alignment.Center
    ) {
        // --- LAYER 1: Ambient Outer Halo ---
        Box(
            Modifier
                .size(size * 1.5f)
                .align(Alignment.Center)
                .blur(if (size <= 40.dp) 8.dp else 24.dp, BlurredEdgeTreatment.Unbounded)
                .background(
                    Brush.radialGradient(
                        colors = if (recording) {
                            listOf(accent.primary.copy(alpha = 0.45f), Color.Transparent)
                        } else {
                            listOf(accent.primary.copy(alpha = if (streaming) 0.50f else 0.28f), Color.Transparent)
                        }
                    ),
                    CircleShape,
                ),
        )

        // --- LAYER 2: Glass body — transparent tint so background bleeds through ---
        Canvas(modifier = Modifier.fillMaxSize()) {
            val w = size.toPx()
            val h = size.toPx()
            val radius = w / 2f
            val shiftX = -tiltX * 0.12f * w
            val shiftY = tiltY * 0.12f * h
            val lightCenter = Offset(w * 0.30f + shiftX, h * 0.25f + shiftY)

            // Base: very subtle theme tint (glass, not paint)
            drawCircle(
                brush = Brush.radialGradient(
                    colorStops = arrayOf(
                        0.0f to accent.primary.copy(alpha = if (isDark) 0.22f else 0.15f),
                        0.6f to accent.primaryDeep.copy(alpha = if (isDark) 0.18f else 0.10f),
                        1.0f to accent.primaryDeep.copy(alpha = if (isDark) 0.30f else 0.20f),
                    ),
                    center = lightCenter,
                    radius = radius * 1.1f,
                ),
            )

            // Top-left brightness (light source)
            drawCircle(
                brush = Brush.radialGradient(
                    colorStops = arrayOf(
                        0.0f to Color.White.copy(alpha = if (isDark) 0.25f else 0.40f),
                        0.5f to Color.White.copy(alpha = 0.05f),
                        1.0f to Color.Transparent,
                    ),
                    center = lightCenter,
                    radius = radius * 0.8f,
                ),
            )

            // Bottom-right accent bleed
            drawCircle(
                brush = Brush.radialGradient(
                    colorStops = arrayOf(
                        0.0f to accent.primary.copy(alpha = if (isDark) 0.45f else 0.35f),
                        0.6f to Color.Transparent,
                    ),
                    center = Offset(w * 0.72f, h * 0.78f),
                    radius = radius * 0.65f,
                ),
            )

            // Bottom shadow for volume (subtle, not harsh)
            drawCircle(
                brush = Brush.radialGradient(
                    colorStops = arrayOf(
                        0.0f to Color.Transparent,
                        0.55f to Color.Transparent,
                        0.85f to Color.Black.copy(alpha = if (isDark) 0.20f else 0.08f),
                        1.0f to Color.Black.copy(alpha = if (isDark) 0.35f else 0.15f),
                    ),
                    center = Offset(w * 0.45f, h * 0.40f),
                    radius = radius,
                ),
            )

            // Caustic conic layer (depth structure)
            val coreShiftX = tiltX * 0.05f * w
            val coreShiftY = -tiltY * 0.05f * h
            val coreCenter = Offset(w / 2f + coreShiftX, h / 2f + coreShiftY)
            drawCircle(
                brush = Brush.sweepGradient(
                    colorStops = arrayOf(
                        0.0f to Color.Transparent,
                        0.16f to accent.primary.copy(alpha = 0.30f),
                        0.33f to Color.White.copy(alpha = 0.20f),
                        0.50f to Color.Transparent,
                        0.66f to accent.primaryDeep.copy(alpha = 0.25f),
                        1.0f to Color.Transparent,
                    ),
                    center = coreCenter,
                ),
                radius = radius * 0.84f,
                blendMode = BlendMode.Overlay,
            )
        }

        // --- LAYER 3: Specular highlights + rim ---
        Canvas(modifier = Modifier.fillMaxSize()) {
            val w = size.toPx()
            val h = size.toPx()
            val radius = w / 2f
            val specShiftX = -tiltX * 0.08f * w
            val specShiftY = tiltY * 0.08f * h

            // Primary specular — elliptical for realism
            drawOval(
                brush = Brush.radialGradient(
                    colors = listOf(
                        Color.White.copy(alpha = if (isDark) 0.70f else 0.90f),
                        Color.Transparent,
                    ),
                    center = Offset(w * 0.30f + specShiftX, h * 0.24f + specShiftY),
                    radius = radius * 0.35f,
                ),
                topLeft = Offset(w * 0.12f + specShiftX, h * 0.10f + specShiftY),
                size = androidx.compose.ui.geometry.Size(radius * 0.7f, radius * 0.55f),
            )

            // Secondary bounce (bottom-right, warm)
            drawCircle(
                brush = Brush.radialGradient(
                    colors = listOf(
                        accent.primary.copy(alpha = if (isDark) 0.50f else 0.35f),
                        Color.Transparent,
                    ),
                    center = Offset(w * 0.72f + specShiftX, h * 0.80f + specShiftY),
                    radius = radius * 0.25f,
                ),
            )

            // Crisp rim hairline
            drawCircle(
                color = Color.White.copy(alpha = if (isDark) 0.10f else 0.30f),
                radius = radius - 0.5f,
                style = Stroke(width = 1f),
            )

            // Inner rim (inset edge for refraction feel)
            drawCircle(
                color = Color.White.copy(alpha = if (isDark) 0.05f else 0.12f),
                radius = radius - 2f,
                style = Stroke(width = 0.5f),
            )
        }
    }
}
