package theorycrafter.ui.widgets

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material.Icon
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme
import androidx.compose.material.icons.outlined.Check
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.AnnotatedString
import compose.utils.ProvideEnabledLocalContentAlpha
import compose.utils.VerticallyCenteredRow
import compose.widgets.SingleLineText
import theorycrafter.ui.Checkbox
import theorycrafter.ui.TheorycrafterTheme


/**
 * Checkmark with text to the right.
 */
@Composable
fun CheckmarkedText(
    text: String,
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    enabled: Boolean = true,
    modifier: Modifier = Modifier
) {
    CheckmarkedRow(
        checked = checked,
        onCheckedChange = onCheckedChange,
        enabled = enabled,
        modifier = modifier
    ) {
        TextNearCheck(text)
    }
}


/**
 * Checkmark with text to the right that takes and modifies the state via a [MutableState].
 */
@Composable
fun CheckmarkedText(
    text: String,
    state: MutableState<Boolean>,
    enabled: Boolean = true,
    modifier: Modifier = Modifier
) {
    CheckmarkedRow(
        checked = state.value,
        onCheckedChange = state.component2(),
        enabled = enabled,
        modifier = modifier
    ) {
        TextNearCheck(text)
    }
}


/**
 * Checkbox with text to the right.
 */
@Composable
fun CheckboxedText(
    text: String,
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    enabled: Boolean = true,
    modifier: Modifier = Modifier,
) {
    CheckboxedRow(
        checked = checked,
        onCheckedChange = onCheckedChange,
        enabled = enabled,
        modifier = modifier
    ) {
        TextNearCheck(text)
    }
}


/**
 * Checkbox with text to the right that takes and modifies the state via a [MutableState].
 */
@Composable
fun CheckboxedText(
    text: String,
    state: MutableState<Boolean>,
    enabled: Boolean = true,
    modifier: Modifier = Modifier,
) {
    CheckboxedRow(
        checked = state.value,
        onCheckedChange = state.component2(),
        enabled = enabled,
        modifier = modifier
    ) {
        TextNearCheck(text)
    }
}


/**
 * The text to the right of a checkmark or checkbox.
 */
@Composable
fun TextNearCheck(text: String) {
    SingleLineText(
        text = text,
        modifier = Modifier
            .padding(vertical = TheorycrafterTheme.spacing.xxsmall)
    )
}


/**
 * The text to the right of a checkmark or checkbox.
 */
@Composable
fun TextNearCheck(text: AnnotatedString) {
    SingleLineText(
        text = text,
        modifier = Modifier
            .padding(vertical = TheorycrafterTheme.spacing.xxsmall)
    )
}


/**
 * Checkmark and custom content to the right.
 */
@Composable
fun CheckmarkedRow(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    enabled: Boolean = true,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    CheckedRow(
        checked = checked,
        onCheckedChange = onCheckedChange,
        enabled = enabled,
        modifier = modifier,
        check = { Checkmark(it) },
        content = content
    )
}


/**
 * Checkbox and custom content to the right.
 */
@Composable
fun CheckboxedRow(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    enabled: Boolean = true,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    CheckedRow(
        checked = checked,
        onCheckedChange = onCheckedChange,
        enabled = enabled,
        modifier = modifier,
        check = {
            TheorycrafterTheme.Checkbox(
                checked = it,
                onCheckedChange = null,
                enabled = enabled,
            )
        },
        content = content
    )
}


/**
 * Checkbox and custom content to the right.
 */
@Composable
fun CheckboxedRow(
    state: MutableState<Boolean>,
    enabled: Boolean = true,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    CheckboxedRow(
        checked = state.value,
        onCheckedChange = state.component2(),
        enabled = enabled,
        modifier = modifier,
        content = content
    )
}


/**
 * A checkmark.
 */
@Composable
fun Checkmark(checked: Boolean) {
    val textSize = with(LocalDensity.current) {
        LocalTextStyle.current.fontSize.toDp()
    }
    Box(
        modifier = Modifier
            .padding(TheorycrafterTheme.spacing.xxxsmall)
            .size(textSize)
    ) {
        if (checked) {
            Icon(
                imageVector = TheorycrafterTheme.iconStyle.Check,
                contentDescription = "Check mark",
                modifier = Modifier.fillMaxSize()
            )
        }
    }
}


/**
 * A row that holds a "check" and some additional content.
 */
@Composable
private fun CheckedRow(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    enabled: Boolean = true,
    modifier: Modifier,
    check: @Composable RowScope.(Boolean) -> Unit,
    content: @Composable RowScope.() -> Unit
) {
    ProvideEnabledLocalContentAlpha(enabled) {
        VerticallyCenteredRow(
            modifier = modifier
                .clip(MaterialTheme.shapes.small)
                .toggleable(
                    value = checked,
                    onValueChange = onCheckedChange,
                    enabled = enabled
                )
                .padding(
                    start = TheorycrafterTheme.spacing.xxxsmall,
                    end = TheorycrafterTheme.spacing.xsmall  // The icon typically has some padding already
                ),
        ) {
            check(checked)
            content()
        }
    }
}


/**
 * A row that holds a "check" and some additional content.
 */
@Composable
private fun CheckedRow(
    state: MutableState<Boolean>,
    enabled: Boolean = true,
    modifier: Modifier,
    check: @Composable RowScope.(Boolean) -> Unit,
    content: @Composable RowScope.() -> Unit
) {
    CheckedRow(
        checked = state.value,
        onCheckedChange = state.component2(),
        modifier = modifier,
        check = check,
        content = content
    )
}
