package theorycrafter.ui.widgets

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import compose.utils.VerticallyCenteredRow
import compose.widgets.SingleLineText
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.hostOs
import theorycrafter.ui.TheorycrafterTheme
import theorycrafter.utils.rememberLocalFontMetrics


/**
 * A key displayed in the key shortcuts' tooltip.
 */
data class DisplayedKeyShortcut(


    /**
     * The text to display on each key.
     */
    val keys: List<String>,


    /**
     * The vertical shift (upwards) to apply to the key text, in order to make it look vertically centered.
     * The value is multiplied by the font's x-height.
     * A value of `null` will cause the default centering algorithm to be used.
     */
    val verticalShiftMultiplier: Float? = null


) {


    constructor(key: String, verticalShiftMultiplier: Float? = null): this(listOf(key), verticalShiftMultiplier)

}


/**
 * A line in the key shortcuts tooltip.
 */
data class KeyShortcutDescription(


    /**
     * The description of what the shortcut does.
     */
    val description: String,


    /**
     * The keys activating the shortcut.
     */
    val keys: List<DisplayedKeyShortcut>


) {

    constructor(description: String, vararg keys: DisplayedKeyShortcut): this(description, keys.toList())

    constructor(description: String, vararg keys: String):
            this(description, keys.map { DisplayedKeyShortcut(it) }.toList())

}


/**
 * The vertical shift multiplier for the left/right arrows tooltip.
 */
val ArrowsVerticalShiftMultiplier = when (hostOs) {
    OS.MacOS -> 0.05f
    OS.Windows -> 0.2f
    else -> null
}


/**
 * The vertical shift multiplier for lowercase text in the tooltip.
 */
val LowercaseTextShiftMultiplier = when (hostOs) {
    OS.MacOS -> 0.1f
    OS.Windows -> 0.2f
    else -> null
}


/**
 * The tooltip displaying the fit editor key shortcuts.
 */
@Composable
fun KeyShortcutsTooltip(items: List<KeyShortcutDescription>) {
    Column(
        // We want extra padding for this tooltip because it's large
        modifier = Modifier.padding(
            horizontal = TheorycrafterTheme.spacing.small,
            vertical = TheorycrafterTheme.spacing.small
        ),
        verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xsmall)
    ) {
        val keyTextStyle = TheorycrafterTheme.textStyles.tooltipRegular.copy(
            textAlign = TextAlign.Center,
        )
        val keyFontMetrics = rememberLocalFontMetrics(keyTextStyle)
        for ((desc, displayedShortcuts) in items){
            VerticallyCenteredRow(
                modifier = Modifier.width(360.dp),
            ) {
                SingleLineText(
                    text = desc,
                    style = TheorycrafterTheme.textStyles.tooltipRegular,
                    modifier = Modifier.weight(1f)
                )
                for ((index, displayedShortcut) in displayedShortcuts.withIndex()){
                    val (keys, verticalShift) = displayedShortcut
                    for ((keyIndex, key) in keys.withIndex()) {
                        SingleLineText(
                            text = key,
                            style = keyTextStyle,
                            modifier = Modifier
                                .clip(RoundedCornerShape(4.dp))
                                .widthIn(min = 40.dp)
                                .background(TheorycrafterTheme.colors.fitEditorKeyShortcutsTooltipKeysBackground())
                                .border(
                                    width = if (hostOs == OS.Windows) 0.5.dp else 1.dp,  // Font on win is thinner
                                    color = LocalContentColor.current,
                                    shape = RoundedCornerShape(4.dp)
                                )
                                .padding(horizontal = 10.dp, vertical = 4.dp)
                                .absoluteOffset {
                                    val verticalOffset =
                                        if (verticalShift != null)
                                            -verticalShift * keyFontMetrics.xHeight
                                        else 0
                                    IntOffset(x = 0, y = verticalOffset.toInt())
                                },
                        )

                        if (keyIndex < keys.lastIndex) {
                            Text("+", modifier = Modifier.padding(horizontal = 4.dp))
                        }
                    }

                    if (index < displayedShortcuts.lastIndex){
                        Text("or", modifier = Modifier.padding(horizontal = 8.dp))
                    }
                }
            }
        }
    }
}
