package com.birdsounds.identify.presentation

import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.sp
import androidx.wear.compose.material.Text
import kotlinx.coroutines.delay


@Composable
fun FlashingText(
    text: String,
    color: Color,
    textDecor: TextDecoration = TextDecoration.None,
    modifier: Modifier = Modifier,
    key: Long,
    fontStyle: FontStyle = FontStyle.Normal
) {
    // Set up the flashing state
    var isFlashing by remember { mutableStateOf(false) }

    // Create animation for the background color
    val backgroundColor by animateColorAsState(
        targetValue = if (isFlashing) Color.DarkGray else Color.Transparent,
        animationSpec = tween(durationMillis = 1000)
    )

    // Trigger the flash effect once
    LaunchedEffect(key1 = key) {
        isFlashing = true
        delay(1500)
        isFlashing = false
    }

    // Display the text with animated background
    AutoSizedText(
        text = text,
        color = color,
        textAlign = TextAlign.Center,
        modifier = modifier
            .background(color = backgroundColor),
        textDecor = textDecor,
        fontStyle = fontStyle,
        key = key
    )
}

@Composable
fun AutoSizedText(
    text: String,
    color: Color = Color.White,
    textAlign: TextAlign = TextAlign.Center,
    modifier: Modifier = Modifier,
    textDecor: TextDecoration = TextDecoration.None,
    key: Long = 0,
    minFontSize: TextUnit = 5.sp,
    targetFontSize: TextUnit = 24.sp,
    fontWeight: FontWeight = FontWeight.Normal,
    fontStyle: FontStyle = FontStyle.Normal,
) {
    var display_text = text;
    val textMeasurer = rememberTextMeasurer()
    BoxWithConstraints(modifier) {
        val density = LocalDensity.current
//        val minFontSizePx = with(density) { minFontSize.toPx() }
//        val maxFontSizePx = with(density) { targetFontSize.toPx() }
        val availableWidthPx = with(density) { maxWidth.toPx() }

        // Binary search to find the appropriate font size that fits the available width
        var lowPx: TextUnit = minFontSize
        var highPx: TextUnit = targetFontSize
        var bestFontSizePx = targetFontSize;
        val textStyle = TextStyle(fontWeight = fontWeight, color = color, fontSize=bestFontSizePx)
        while (lowPx <= highPx) {
            val midPx: TextUnit = TextUnit(value=lowPx.value/2 + highPx.value/2 , type= TextUnitType.Sp)
            val style = textStyle.copy(fontSize = midPx)

            val textLayoutResult = textMeasurer.measure(
                text = display_text,
                style = style,
                maxLines = 1,
                softWrap = false,
                density = density,
            )

            if (textLayoutResult.size.width <= availableWidthPx) {
//                // This font size fits, try a larger oneb
                bestFontSizePx = midPx;
                break;
            } else {
//                // This font size is too large, try a smaller one
//                highPx = (midPx - 1).toFloat()
                highPx = TextUnit(value=midPx.value - 1, type=TextUnitType.Sp)
            }
        }

        // Convert the best font size back to sp and use it
//        val bestFontSize = with(density) { bestFontSizePx.toSp() }
        LaunchedEffect(key1 = key) {

        }

        Text(
            text = display_text,
            color = color,
            fontSize = bestFontSizePx,
            fontStyle = fontStyle,
            fontWeight = fontWeight,
            maxLines = 1,
            textDecoration = textDecor,
            overflow = TextOverflow.Clip,
            modifier = Modifier.fillMaxWidth(),
            textAlign = textAlign
        )
    }
}