package dev.ulfrx.recipe.ui.screens.shell.dock

import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp

private val ActiveIndicatorBleed = 4.dp
private val ActiveIndicatorEdgeInset = 5.dp

internal data class TabBounds(
    val offsetXPx: Float,
    val widthPx: Float,
)

internal sealed interface DockPressState {
    data object Idle : DockPressState

    data class Pressing(
        val xPx: Float,
    ) : DockPressState
}

internal sealed interface DockPressEvent {
    data class Pressing(
        val xPx: Float,
    ) : DockPressEvent

    data class Released(
        val xPx: Float,
    ) : DockPressEvent

    data object Cancelled : DockPressEvent
}

internal data class ActiveIndicatorBbox(
    val leftPx: Float,
    val rightPx: Float,
) {
    val widthPx: Float get() = (rightPx - leftPx).coerceAtLeast(0f)
    val centerPx: Float get() = (leftPx + rightPx) / 2f
}

internal fun activeIndicatorBboxFor(
    cell: TabBounds,
    dockWidthPx: Float,
    density: Density,
): ActiveIndicatorBbox {
    val bleedPx = with(density) { ActiveIndicatorBleed.toPx() }
    val edgeInsetPx = with(density) { ActiveIndicatorEdgeInset.toPx() }
    val left = (cell.offsetXPx - bleedPx).coerceAtLeast(edgeInsetPx)
    val right = (cell.offsetXPx + cell.widthPx + bleedPx).coerceAtMost(dockWidthPx - edgeInsetPx)
    return ActiveIndicatorBbox(left, right)
}

internal fun tabIndexAt(
    x: Float,
    bounds: Map<Int, TabBounds>,
): Int? {
    if (bounds.isEmpty()) return null
    val sorted = bounds.entries.sortedBy { it.value.offsetXPx }
    var result = sorted.first().key
    for (entry in sorted) {
        if (entry.value.offsetXPx <= x) {
            result = entry.key
        } else {
            break
        }
    }
    return result
}
