package com.pixelized.desktop.lwa.ui.composable.textfield

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.height
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.TextFieldColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.pixelized.desktop.lwa.ui.theme.color.component.LwaTextFieldColors
import com.pixelized.desktop.lwa.utils.extention.isElementVisible
import com.pixelized.desktop.lwa.utils.extention.thenIf
import com.pixelized.desktop.lwa.utils.rememberKeyboardActions
import kotlinx.coroutines.flow.StateFlow

@Stable
data class LwaTextFieldUio(
    val enable: Boolean = true,
    val errorFlow: StateFlow<Boolean>,
    val valueFlow: StateFlow<String>,
    val labelFlow: StateFlow<String?>,
    val placeHolder: String?,
    val onValueChange: (String) -> Unit,
)

@Composable
fun LwaTextField(
    modifier: Modifier = Modifier,
    colors: TextFieldColors = LwaTextFieldColors(),
    shape: Shape = MaterialTheme.shapes.small,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    singleLine: Boolean = true,
    field: LwaTextFieldUio,
) {
    val focus = LocalFocusManager.current

    val isFocused = interactionSource.collectIsFocusedAsState()
    val label = field.labelFlow.collectAsState()
    val value = field.valueFlow.collectAsState()
    val error = field.errorFlow.collectAsState()

    TextField(
        modifier = Modifier
            .thenIf(singleLine) { height(height = 56.dp) }
            .isElementVisible { visible ->
                if (visible.not() && isFocused.value) {
                    focus.clearFocus()
                }
            }
            .then(other = modifier),
        colors = colors,
        shape = shape,
        keyboardActions = rememberKeyboardActions {
            focus.moveFocus(FocusDirection.Next)
        },
        enabled = field.enable,
        singleLine = singleLine,
        placeholder = field.placeHolder?.let {
            {
                Text(
                    overflow = TextOverflow.Ellipsis,
                    maxLines = 1,
                    text = it
                )
            }
        },
        isError = error.value,
        label = label.value?.let {
            {
                Text(
                    overflow = TextOverflow.Ellipsis,
                    maxLines = 1,
                    text = it
                )
            }
        },
        interactionSource = interactionSource,
        leadingIcon = leadingIcon,
        trailingIcon = trailingIcon,
        onValueChange = { field.onValueChange(it) },
        value = value.value,
    )
}