package com.rosetta.messenger.ui.onboarding

import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.*
import androidx.compose.foundation.Canvas
import androidx.compose.runtime.rememberCoroutineScope
import kotlinx.coroutines.launch
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerDefaults
import androidx.compose.foundation.pager.PagerSnapDistance
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import compose.icons.TablerIcons
import compose.icons.tablericons.Sun
import compose.icons.tablericons.Moon
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.scale
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat
import com.airbnb.lottie.compose.*
import com.rosetta.messenger.R
import com.rosetta.messenger.ui.theme.*
import com.rosetta.messenger.ui.utils.NavigationModeUtils
import kotlin.math.PI
import kotlin.math.abs
import kotlin.math.acos
import kotlin.math.absoluteValue
import kotlin.math.atan2
import kotlin.math.ceil
import kotlin.math.cos
import kotlin.math.floor
import kotlin.math.hypot
import kotlin.math.min
import kotlin.math.sin
import kotlinx.coroutines.delay

// App colors (matching React Native)
val PrimaryBlue = Color(0xFF248AE6) // primary light theme
val PrimaryBlueDark = Color(0xFF1A72C2) // primary dark theme
val LightBlue = Color(0xFF74C0FC) // lightBlue
val OnboardingBackground = Color(0xFF1E1E1E) // dark background
val OnboardingBackgroundLight = Color(0xFFFFFFFF)

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun OnboardingScreen(
        isDarkTheme: Boolean,
        onThemeToggle: () -> Unit,
        onStartMessaging: () -> Unit
) {
        val pagerState = rememberPagerState(pageCount = { onboardingPages.size })

        // Preload Lottie animations
        val ideaComposition by
                rememberLottieComposition(LottieCompositionSpec.Asset("lottie/Idea.json"))
        val moneyComposition by
                rememberLottieComposition(LottieCompositionSpec.Asset("lottie/Money.json"))
        val lockComposition by
                rememberLottieComposition(LottieCompositionSpec.Asset("lottie/lock.json"))
        val bookComposition by
                rememberLottieComposition(LottieCompositionSpec.Asset("lottie/Book.json"))

        // Theme transition animation
        var isTransitioning by remember { mutableStateOf(false) }
        val transitionRadius = remember { androidx.compose.animation.core.Animatable(0f) }
        var clickPosition by remember { mutableStateOf(androidx.compose.ui.geometry.Offset.Zero) }
        var hasInitialized by remember { mutableStateOf(false) }
        var previousTheme by remember { mutableStateOf(isDarkTheme) }
        var targetTheme by remember { mutableStateOf(isDarkTheme) }
        var rootSize by remember { mutableStateOf(androidx.compose.ui.unit.IntSize.Zero) }
        val scope = rememberCoroutineScope()

        LaunchedEffect(Unit) { hasInitialized = true }

        val view = LocalView.current

        // Set initial navigation bar color only on first launch
        LaunchedEffect(Unit) {
                if (!view.isInEditMode) {
                        val window = (view.context as android.app.Activity).window
                        val insetsController = WindowCompat.getInsetsController(window, view)
                        NavigationModeUtils.applyNavigationBarVisibility(
                                window = window,
                                insetsController = insetsController,
                                context = view.context,
                                isDarkTheme = isDarkTheme
                        )
                }
        }

        val backgroundColor by
                animateColorAsState(
                        targetValue =
                                if (isDarkTheme) OnboardingBackground
                                else OnboardingBackgroundLight,
                        animationSpec =
                                if (!hasInitialized) snap()
                                else tween(800, easing = FastOutSlowInEasing),
                        label = "backgroundColor"
                )
        val textColor by
                animateColorAsState(
                        targetValue = if (isDarkTheme) Color.White else Color.Black,
                        animationSpec =
                                if (!hasInitialized) snap()
                                else tween(800, easing = FastOutSlowInEasing),
                        label = "textColor"
                )
        val secondaryTextColor by
                animateColorAsState(
                        targetValue = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666),
                        animationSpec =
                                if (!hasInitialized) snap()
                                else tween(800, easing = FastOutSlowInEasing),
                        label = "secondaryTextColor"
                )
        val indicatorColor by
                animateColorAsState(
                        targetValue = if (isDarkTheme) Color(0xFF4A4A4A) else Color(0xFFD0D0D0),
                        animationSpec =
                                if (!hasInitialized) snap()
                                else tween(800, easing = FastOutSlowInEasing),
                        label = "indicatorColor"
                )

        Box(modifier = Modifier.fillMaxSize().navigationBarsPadding()
                .onGloballyPositioned { rootSize = it.size }
        ) {
                // Base background - shows the OLD theme color during transition
                Box(
                        modifier =
                                Modifier.fillMaxSize()
                                        .background(
                                                if (isTransitioning) {
                                                        if (previousTheme) OnboardingBackground
                                                        else OnboardingBackgroundLight
                                                } else backgroundColor
                                        )
                )

                // Circular reveal overlay - draws the NEW theme color expanding
                if (isTransitioning) {
                        Canvas(modifier = Modifier.fillMaxSize()) {
                                drawCircle(
                                        color =
                                                if (targetTheme) OnboardingBackground
                                                else OnboardingBackgroundLight,
                                        radius = transitionRadius.value,
                                        center = clickPosition
                                )
                        }
                }
                // Theme toggle button in top right
                ThemeToggleButton(
                        isDarkTheme = isDarkTheme,
                        onToggle = { position ->
                                if (!isTransitioning) {
                                        previousTheme = isDarkTheme
                                        targetTheme = !isDarkTheme
                                        clickPosition = position
                                        isTransitioning = true
                                        onThemeToggle()
                                        scope.launch {
                                            try {
                                                val maxR = hypot(
                                                    rootSize.width.toFloat(),
                                                    rootSize.height.toFloat()
                                                ).coerceAtLeast(1f)
                                                transitionRadius.snapTo(0f)
                                                transitionRadius.animateTo(
                                                    targetValue = maxR,
                                                    animationSpec = tween(400, easing = CubicBezierEasing(0.45f, 0.05f, 0.55f, 0.95f))
                                                )
                                            } finally {
                                                isTransitioning = false
                                                previousTheme = targetTheme
                                            }
                                        }
                                }
                        },
                        modifier =
                                Modifier.align(Alignment.TopEnd).padding(16.dp).statusBarsPadding()
                )

                Column(
                        modifier = Modifier.fillMaxSize().padding(horizontal = 24.dp),
                        horizontalAlignment = Alignment.CenterHorizontally
                ) {
                        Spacer(modifier = Modifier.weight(0.15f))

                        // Animated Logo
                        AnimatedRosettaLogo(
                                pagerState = pagerState,
                                ideaComposition = ideaComposition,
                                moneyComposition = moneyComposition,
                                lockComposition = lockComposition,
                                bookComposition = bookComposition,
                                modifier = Modifier.size(150.dp)
                        )

                        Spacer(modifier = Modifier.height(32.dp))

                        // Pager for text content with easier swipes
                        HorizontalPager(
                                state = pagerState,
                                modifier =
                                        Modifier.fillMaxWidth().height(150.dp).graphicsLayer {
                                                // Hardware acceleration for entire pager
                                                compositingStrategy =
                                                        androidx.compose.ui.graphics
                                                                .CompositingStrategy.Offscreen
                                        },
                                // Pre-load adjacent pages for smooth swiping
                                beyondBoundsPageCount = 2,
                                flingBehavior =
                                        PagerDefaults.flingBehavior(
                                                state = pagerState,
                                                pagerSnapDistance =
                                                        PagerSnapDistance.atMost(
                                                                1
                                                        ), // Нужен более значительный свайп
                                                lowVelocityAnimationSpec =
                                                        tween(
                                                                durationMillis = 400,
                                                                easing = FastOutSlowInEasing
                                                        ),
                                                snapAnimationSpec =
                                                        spring(
                                                                dampingRatio = 0.8f,
                                                                stiffness = 380f
                                                        )
                                        )
                        ) { page ->
                                OnboardingPageContent(
                                        page = onboardingPages[page],
                                        textColor = textColor,
                                        secondaryTextColor = secondaryTextColor,
                                        highlightColor = PrimaryBlue,
                                        pageOffset =
                                                ((pagerState.currentPage - page) +
                                                                pagerState
                                                                        .currentPageOffsetFraction)
                                                        .absoluteValue
                                )
                        }

                        Spacer(modifier = Modifier.height(24.dp))

                        // Page indicators
                        GooeyPagerIndicator(
                                pageCount = onboardingPages.size,
                                pagerState = pagerState,
                                selectedColor = PrimaryBlue,
                                unselectedColor = indicatorColor
                        )

                        Spacer(modifier = Modifier.weight(0.3f))

                        // Start messaging button
                        StartMessagingButton(
                                onClick = onStartMessaging,
                                modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp)
                        )

                        Spacer(modifier = Modifier.height(48.dp))
                }
        }
}

@Composable
fun ThemeToggleButton(
        isDarkTheme: Boolean,
        onToggle: (androidx.compose.ui.geometry.Offset) -> Unit,
        modifier: Modifier = Modifier
) {
        val rotation by
                animateFloatAsState(
                        targetValue = if (isDarkTheme) 360f else 0f,
                        animationSpec =
                                spring(dampingRatio = 0.6f, stiffness = Spring.StiffnessLow),
                        label = "rotation"
                )

        val scale by
                animateFloatAsState(
                        targetValue = 1f,
                        animationSpec =
                                spring(dampingRatio = 0.4f, stiffness = Spring.StiffnessMedium),
                        label = "scale"
                )

        val iconColor by
                animateColorAsState(
                        targetValue = if (isDarkTheme) Color.White else Color(0xFF2A2A2A),
                        animationSpec = tween(800, easing = FastOutSlowInEasing),
                        label = "iconColor"
                )

        var buttonPosition by remember { mutableStateOf(androidx.compose.ui.geometry.Offset.Zero) }
        var isClickable by remember { mutableStateOf(true) }

        LaunchedEffect(isDarkTheme) {
                isClickable = false
                delay(800)
                isClickable = true
        }

        IconButton(
                onClick = { if (isClickable) onToggle(buttonPosition) },
                enabled = isClickable,
                modifier =
                        modifier.size(48.dp).onGloballyPositioned { coordinates ->
                                val bounds = coordinates.boundsInWindow()
                                buttonPosition =
                                        androidx.compose.ui.geometry.Offset(
                                                x = bounds.center.x,
                                                y = bounds.center.y
                                        )
                        }
        ) {
                Box(
                        modifier = Modifier.size(24.dp).scale(scale).rotate(rotation),
                        contentAlignment = Alignment.Center
                ) {
                        Icon(
                                imageVector =
                                        if (isDarkTheme) TablerIcons.Sun
                                        else TablerIcons.Moon,
                                contentDescription =
                                        if (isDarkTheme) "Switch to Light Mode"
                                        else "Switch to Dark Mode",
                                tint = iconColor,
                                modifier = Modifier.size(24.dp)
                        )
                }
        }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun AnimatedRosettaLogo(
        pagerState: PagerState,
        ideaComposition: Any?,
        moneyComposition: Any?,
        lockComposition: Any?,
        bookComposition: Any?,
        modifier: Modifier = Modifier
) {
        // Use derivedStateOf for optimized reads - prevents unnecessary recompositions
        val currentPage by remember { derivedStateOf { pagerState.currentPage } }

        // Pre-calculate all animation progress states ONCE (they stay in memory)
        val ideaLottieComp = ideaComposition as? com.airbnb.lottie.LottieComposition
        val moneyLottieComp = moneyComposition as? com.airbnb.lottie.LottieComposition
        val lockLottieComp = lockComposition as? com.airbnb.lottie.LottieComposition
        val bookLottieComp = bookComposition as? com.airbnb.lottie.LottieComposition

        // All animations are always "playing" but only visible one shows
        val ideaProgress by
                animateLottieCompositionAsState(
                        composition = ideaLottieComp,
                        iterations = 1,
                        isPlaying = currentPage == 1,
                        speed = 1.5f,
                        restartOnPlay = true
                )
        val moneyProgress by
                animateLottieCompositionAsState(
                        composition = moneyLottieComp,
                        iterations = 1,
                        isPlaying = currentPage == 2,
                        speed = 1.5f,
                        restartOnPlay = true
                )
        val lockProgress by
                animateLottieCompositionAsState(
                        composition = lockLottieComp,
                        iterations = 1,
                        isPlaying = currentPage == 3,
                        speed = 1.5f,
                        restartOnPlay = true
                )
        val bookProgress by
                animateLottieCompositionAsState(
                        composition = bookLottieComp,
                        iterations = 1,
                        isPlaying = currentPage == 4,
                        speed = 1.5f,
                        restartOnPlay = true
                )

        // Pulse animation for logo (always running, cheap)
        val pulseScale by
                rememberInfiniteTransition(label = "pulse")
                        .animateFloat(
                                initialValue = 1f,
                                targetValue = 1.1f,
                                animationSpec =
                                        infiniteRepeatable(
                                                animation =
                                                        tween(800, easing = FastOutSlowInEasing),
                                                repeatMode = RepeatMode.Reverse
                                        ),
                                label = "pulseScale"
                        )

        Box(modifier = modifier, contentAlignment = Alignment.Center) {
                // === PRE-RENDERED LAYERS - All always exist, just alpha changes ===

                // Page 0: Rosetta Logo
                Box(
                        modifier =
                                Modifier.fillMaxSize().graphicsLayer {
                                        alpha = if (currentPage == 0) 1f else 0f
                                },
                        contentAlignment = Alignment.Center
                ) {
                        // Glow effect
                        Box(
                                modifier =
                                        Modifier.size(180.dp)
                                                .scale(if (currentPage == 0) pulseScale else 1f)
                                                .background(
                                                        color =
                                                                Color(0xFF54A9EB)
                                                                        .copy(alpha = 0.2f),
                                                        shape = CircleShape
                                                )
                        )
                        // Main logo
                        Image(
                                painter = painterResource(id = R.drawable.rosetta_icon),
                                contentDescription = "Rosetta Logo",
                                modifier = Modifier.size(150.dp).clip(CircleShape)
                        )
                }

                // Page 1: Idea animation (always in memory!)
                if (ideaLottieComp != null) {
                        LottieAnimation(
                                composition = ideaLottieComp,
                                progress = { ideaProgress },
                                modifier =
                                        Modifier.fillMaxSize().graphicsLayer {
                                                alpha = if (currentPage == 1) 1f else 0f
                                                // Hardware layer optimization
                                                compositingStrategy =
                                                        androidx.compose.ui.graphics
                                                                .CompositingStrategy.Offscreen
                                                // Disable clipping for performance
                                                clip = false
                                        },
                                maintainOriginalImageBounds = true,
                                // Disable dynamic properties for max performance
                                enableMergePaths = false
                        )
                }

                // Page 2: Money animation
                if (moneyLottieComp != null) {
                        LottieAnimation(
                                composition = moneyLottieComp,
                                progress = { moneyProgress },
                                modifier =
                                        Modifier.fillMaxSize().graphicsLayer {
                                                alpha = if (currentPage == 2) 1f else 0f
                                                compositingStrategy =
                                                        androidx.compose.ui.graphics
                                                                .CompositingStrategy.Offscreen
                                                clip = false
                                        },
                                maintainOriginalImageBounds = true,
                                enableMergePaths = false
                        )
                }

                // Page 3: Lock animation
                if (lockLottieComp != null) {
                        LottieAnimation(
                                composition = lockLottieComp,
                                progress = { lockProgress },
                                modifier =
                                        Modifier.fillMaxSize().graphicsLayer {
                                                alpha = if (currentPage == 3) 1f else 0f
                                                compositingStrategy =
                                                        androidx.compose.ui.graphics
                                                                .CompositingStrategy.Offscreen
                                                clip = false
                                        },
                                maintainOriginalImageBounds = true,
                                enableMergePaths = false
                        )
                }

                // Page 4: Book animation
                if (bookLottieComp != null) {
                        LottieAnimation(
                                composition = bookLottieComp,
                                progress = { bookProgress },
                                modifier =
                                        Modifier.fillMaxSize().graphicsLayer {
                                                alpha = if (currentPage == 4) 1f else 0f
                                                compositingStrategy =
                                                        androidx.compose.ui.graphics
                                                                .CompositingStrategy.Offscreen
                                                clip = false
                                        },
                                maintainOriginalImageBounds = true,
                                enableMergePaths = false
                        )
                }
        }
}

@Composable
fun OnboardingPageContent(
        page: OnboardingPage,
        textColor: Color,
        secondaryTextColor: Color,
        highlightColor: Color,
        pageOffset: Float
) {
        val alpha by
                animateFloatAsState(
                        targetValue = 1f - (pageOffset * 0.7f).coerceIn(0f, 1f),
                        animationSpec = tween(400, easing = FastOutSlowInEasing),
                        label = "alpha"
                )
        val scale by
                animateFloatAsState(
                        targetValue = 1f - (pageOffset * 0.1f).coerceIn(0f, 1f),
                        animationSpec = tween(400, easing = FastOutSlowInEasing),
                        label = "scale"
                )

        Column(
                modifier =
                        Modifier.fillMaxWidth().graphicsLayer {
                                this.alpha = alpha
                                scaleX = scale
                                scaleY = scale
                        },
                horizontalAlignment = Alignment.CenterHorizontally
        ) {
                // Title
                Text(
                        text = page.title,
                        fontSize = 32.sp,
                        fontWeight = FontWeight.Bold,
                        color = textColor,
                        textAlign = TextAlign.Center
                )

                Spacer(modifier = Modifier.height(12.dp))

                // Description with highlighted words
                val annotatedDescription = buildAnnotatedString {
                        var currentIndex = 0
                        val description = page.description

                        // Find and highlight words
                        page.highlightWords.forEach { word ->
                                val startIndex =
                                        description.indexOf(word, currentIndex, ignoreCase = true)
                                if (startIndex >= 0) {
                                        // Add text before the word
                                        if (startIndex > currentIndex) {
                                                withStyle(SpanStyle(color = secondaryTextColor)) {
                                                        append(
                                                                description.substring(
                                                                        currentIndex,
                                                                        startIndex
                                                                )
                                                        )
                                                }
                                        }
                                        // Add highlighted word
                                        withStyle(
                                                SpanStyle(
                                                        color = highlightColor,
                                                        fontWeight = FontWeight.SemiBold
                                                )
                                        ) {
                                                append(
                                                        description.substring(
                                                                startIndex,
                                                                startIndex + word.length
                                                        )
                                                )
                                        }
                                        currentIndex = startIndex + word.length
                                }
                        }

                        // Add remaining text
                        if (currentIndex < description.length) {
                                withStyle(SpanStyle(color = secondaryTextColor)) {
                                        append(description.substring(currentIndex))
                                }
                        }
                }

                Text(
                        text = annotatedDescription,
                        fontSize = 17.sp,
                        textAlign = TextAlign.Center,
                        lineHeight = 24.sp
                )
        }
}

@Composable
@OptIn(ExperimentalFoundationApi::class)
fun GooeyPagerIndicator(
        pageCount: Int,
        pagerState: PagerState,
        selectedColor: Color,
        unselectedColor: Color,
        modifier: Modifier = Modifier,
        dotRadius: Dp = 2.8.dp,
        dotSpacing: Dp = 12.dp,
        indicatorHeight: Dp = 18.dp,
) {
        if (pageCount <= 0) return

        val indicatorWidth =
                if (pageCount > 1) dotSpacing * (pageCount - 1) + dotRadius * 8 else dotRadius * 8

        Canvas(modifier = modifier.width(indicatorWidth).height(indicatorHeight)) {
                val baseRadius = dotRadius.toPx()
                val spacing = dotSpacing.toPx()
                val centerY = size.height / 2f
                val trackWidth = if (pageCount > 1) spacing * (pageCount - 1) else 0f
                val startX = (size.width - trackWidth) / 2f

                if (pageCount > 1) {
                        val trackInset = baseRadius * 0.75f
                        val trackHeight = baseRadius * 0.45f
                        drawRoundRect(
                                color = unselectedColor.copy(alpha = 0.14f),
                                topLeft = Offset(startX - trackInset, centerY - trackHeight / 2f),
                                size = Size(trackWidth + trackInset * 2f, trackHeight),
                                cornerRadius = CornerRadius(trackHeight, trackHeight)
                        )
                }

                val rawPosition =
                        (pagerState.currentPage + pagerState.currentPageOffsetFraction)
                                .coerceIn(0f, (pageCount - 1).toFloat())
                val activeCenter = Offset(startX + rawPosition * spacing, centerY)

                repeat(pageCount) { index ->
                        val center = Offset(startX + index * spacing, centerY)
                        val distanceToActive = abs(rawPosition - index)
                        val influence = (1f - distanceToActive / 1.25f).coerceIn(0f, 1f)
                        val dotScale = 0.88f + influence * 0.16f
                        val dotAlpha = 0.35f + influence * 0.35f
                        drawCircle(
                                color = unselectedColor.copy(alpha = unselectedColor.alpha * dotAlpha),
                                radius = baseRadius * dotScale,
                                center = center
                        )
                }

                val from = floor(rawPosition.toDouble()).toInt().coerceIn(0, pageCount - 1)
                val to = ceil(rawPosition.toDouble()).toInt().coerceIn(0, pageCount - 1)
                val transition = rawPosition - from
                val stretch = (1f - abs(transition - 0.5f) * 2f).coerceIn(0f, 1f)
                val activeRadius = baseRadius * (1.05f + stretch * 0.3f)

                var metaballPath: Path? = null
                var anchorCenter: Offset? = null
                var anchorRadius = 0f

                if (from != to) {
                        val anchorIndex = if (transition < 0.5f) from else to
                        anchorCenter = Offset(startX + anchorIndex * spacing, centerY)
                        anchorRadius = baseRadius * (0.86f + (1f - stretch) * 0.2f)

                        metaballPath =
                                createMetaballPath(
                                        c1 = activeCenter,
                                        r1 = activeRadius,
                                        c2 = anchorCenter,
                                        r2 = anchorRadius,
                                        maxDistance = spacing * 1.36f,
                                        viscosity = 0.36f + stretch * 0.12f,
                                        handleSize = 2.45f
                                )
                }

                drawCircle(
                        color = selectedColor.copy(alpha = 0.18f),
                        radius = activeRadius * 2.2f,
                        center = activeCenter
                )
                if (anchorCenter != null) {
                        drawCircle(
                                color = selectedColor.copy(alpha = 0.1f + stretch * 0.1f),
                                radius = anchorRadius * 1.9f,
                                center = anchorCenter
                        )
                }
                metaballPath?.let { path ->
                        drawPath(path = path, color = selectedColor.copy(alpha = 0.2f + stretch * 0.12f))
                }
                if (anchorCenter != null) {
                        drawCircle(
                                color = selectedColor.copy(alpha = 0.78f),
                                radius = anchorRadius,
                                center = anchorCenter
                        )
                }
                metaballPath?.let { path -> drawPath(path = path, color = selectedColor.copy(alpha = 0.92f)) }
                drawCircle(color = selectedColor, radius = activeRadius, center = activeCenter)
                drawCircle(
                        color = Color.White.copy(alpha = 0.28f),
                        radius = activeRadius * 0.38f,
                        center =
                                Offset(
                                        x = activeCenter.x - activeRadius * 0.28f,
                                        y = activeCenter.y - activeRadius * 0.32f
                                )
                )
        }
}

private fun createMetaballPath(
        c1: Offset,
        r1: Float,
        c2: Offset,
        r2: Float,
        maxDistance: Float,
        viscosity: Float,
        handleSize: Float
): Path? {
        val dx = c2.x - c1.x
        val dy = c2.y - c1.y
        val d = hypot(dx, dy)
        if (d <= 0.001f || d > maxDistance) return null

        val radiusDelta = abs(r1 - r2)
        if (d <= radiusDelta) return null

        val u1: Double
        val u2: Double
        if (d < r1 + r2) {
                val acos1Arg = ((r1 * r1 + d * d - r2 * r2) / (2f * r1 * d)).coerceIn(-1f, 1f)
                val acos2Arg = ((r2 * r2 + d * d - r1 * r1) / (2f * r2 * d)).coerceIn(-1f, 1f)
                u1 = acos(acos1Arg.toDouble())
                u2 = acos(acos2Arg.toDouble())
        } else {
                u1 = 0.0
                u2 = 0.0
        }

        val angleBetweenCenters = atan2(dy, dx).toDouble()
        val maxSpreadArg = ((r1 - r2) / d).coerceIn(-1f, 1f)
        val maxSpread = acos(maxSpreadArg.toDouble())
        val v = viscosity.coerceIn(0f, 1f).toDouble()

        val angle1 = angleBetweenCenters + u1 + (maxSpread - u1) * v
        val angle2 = angleBetweenCenters - u1 - (maxSpread - u1) * v
        val angle3 = angleBetweenCenters + PI - u2 - (PI - u2 - maxSpread) * v
        val angle4 = angleBetweenCenters - PI + u2 + (PI - u2 - maxSpread) * v

        val p1 = pointOnCircle(c1, angle1, r1)
        val p2 = pointOnCircle(c1, angle2, r1)
        val p3 = pointOnCircle(c2, angle3, r2)
        val p4 = pointOnCircle(c2, angle4, r2)

        val totalRadius = r1 + r2
        val d2Base = min(viscosity * handleSize, distance(p1, p3) / totalRadius)
        val d2 = d2Base * min(1f, (d * 2f) / totalRadius)

        val r1h = r1 * d2
        val r2h = r2 * d2

        val h1 = pointOnCircle(p1, angle1 - PI / 2.0, r1h)
        val h2 = pointOnCircle(p2, angle2 + PI / 2.0, r1h)
        val h3 = pointOnCircle(p3, angle3 + PI / 2.0, r2h)
        val h4 = pointOnCircle(p4, angle4 - PI / 2.0, r2h)

        return Path().apply {
                moveTo(p1.x, p1.y)
                cubicTo(h1.x, h1.y, h3.x, h3.y, p3.x, p3.y)
                lineTo(p4.x, p4.y)
                cubicTo(h4.x, h4.y, h2.x, h2.y, p2.x, p2.y)
                close()
        }
}

private fun pointOnCircle(center: Offset, angle: Double, radius: Float): Offset {
        return Offset(
                x = (center.x + cos(angle) * radius).toFloat(),
                y = (center.y + sin(angle) * radius).toFloat()
        )
}

private fun distance(a: Offset, b: Offset): Float = hypot(a.x - b.x, a.y - b.y)

@Composable
fun StartMessagingButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
        // Shining effect animation
        val infiniteTransition = rememberInfiniteTransition(label = "shine")
        val shimmerTranslate by
                infiniteTransition.animateFloat(
                        initialValue = -0.5f,
                        targetValue = 1.5f,
                        animationSpec =
                                infiniteRepeatable(
                                        animation = tween(2000, easing = LinearEasing),
                                        repeatMode = RepeatMode.Restart
                                ),
                        label = "shimmerTranslate"
                )

        Surface(
                onClick = onClick,
                modifier = modifier.fillMaxWidth().height(54.dp),
                shape = RoundedCornerShape(12.dp),
                color = PrimaryBlue
        ) {
                Box(
                        modifier =
                                Modifier.fillMaxSize().drawWithContent {
                                        drawContent()
                                        // Draw shimmer on top
                                        val shimmerWidth = size.width * 0.6f
                                        val shimmerStart = shimmerTranslate * size.width
                                        drawRect(
                                                brush =
                                                        Brush.linearGradient(
                                                                colors =
                                                                        listOf(
                                                                                Color.White.copy(
                                                                                        alpha = 0f
                                                                                ),
                                                                                Color.White.copy(
                                                                                        alpha = 0.3f
                                                                                ),
                                                                                Color.White.copy(
                                                                                        alpha = 0f
                                                                                )
                                                                        ),
                                                                start = Offset(shimmerStart, 0f),
                                                                end =
                                                                        Offset(
                                                                                shimmerStart +
                                                                                        shimmerWidth,
                                                                                size.height
                                                                        )
                                                        )
                                        )
                                },
                        contentAlignment = Alignment.Center
                ) {
                        Text(
                                text = "Start Messaging",
                                fontSize = 17.sp,
                                fontWeight = FontWeight.SemiBold,
                                color = Color.White
                        )
                }
        }
}
