package com.isidroid.compose_components

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.sp

@Composable
fun AutoSizeText(
    text: String,
    modifier: Modifier = Modifier,
    minFontSize: Float = 10f,
    textOverflow: TextOverflow = TextOverflow.Ellipsis,
    textAlign: TextAlign = TextAlign.Center,
    textStyle: TextStyle = TextStyle(fontSize = 16.sp)
) {
    var fontSize by remember { mutableFloatStateOf(textStyle.fontSize.value) }
    var widgetWidth by remember { mutableIntStateOf(0) }

    val textWidth = measureTextWidth(text = text, style = textStyle)
    val isMinFont = minFontSize >= fontSize
    val needDecrease = widgetWidth < textWidth && !isMinFont

    LaunchedEffect(fontSize) {
        if (needDecrease)
            fontSize -= 1f
    }

    Text(
        text = text.takeIf { !needDecrease }.orEmpty(),
        maxLines = 1,
        fontSize = fontSize.sp,
        overflow = if (isMinFont) textOverflow else TextOverflow.Visible,
        textAlign = textAlign,
        modifier = modifier
            .fillMaxWidth()
            .onGloballyPositioned { layoutCoordinates ->
                widgetWidth = layoutCoordinates.size.width
            },
    )
}

@Composable
private fun measureTextWidth(text: String, style: TextStyle): Int {
    val textMeasurer = rememberTextMeasurer()
    return textMeasurer.measure(text, style).size.width
}