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

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.selected
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.composeunstyled.UnstyledIcon
import dev.ulfrx.recipe.navigation.DockDestination
import dev.ulfrx.recipe.ui.theme.RecipeTheme
import org.jetbrains.compose.resources.stringResource
import kotlin.math.roundToInt

private val DockTabIconSize = 18.dp
private val DockTabIconLabelGap = 2.dp
private const val DOCK_TAB_LABEL_FONT_SIZE_SP = 11
private const val DOCK_TAB_LABEL_LINE_HEIGHT_SP = 13

@Composable
internal fun DockTabRow(
    destinations: List<DockDestination>,
    activeIndex: Int,
    tabBounds: Map<Int, TabBounds>,
    dockWidthPx: Float,
    onTabSelectFromA11y: (DockDestination) -> Unit,
    onTabBoundsChange: (Int, TabBounds) -> Unit,
) {
    val density = LocalDensity.current
    Row(
        modifier = Modifier.fillMaxSize(),
        horizontalArrangement = Arrangement.spacedBy(2.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        destinations.forEachIndexed { index, destination ->
            val cellBounds = tabBounds[index]
            val contentOffsetPx =
                if (cellBounds != null && dockWidthPx > 0f) {
                    val bbox = activeIndicatorBboxFor(cellBounds, dockWidthPx, density)
                    val cellCenterX = cellBounds.offsetXPx + cellBounds.widthPx / 2f
                    bbox.centerPx - cellCenterX
                } else {
                    0f
                }
            DockTabItem(
                destination = destination,
                isActive = index == activeIndex,
                contentOffsetPx = contentOffsetPx,
                onSelect = { onTabSelectFromA11y(destination) },
                modifier =
                    Modifier
                        .weight(1f)
                        .fillMaxHeight()
                        .onGloballyPositioned { coords ->
                            onTabBoundsChange(
                                index,
                                TabBounds(
                                    offsetXPx = coords.positionInParent().x,
                                    widthPx = coords.size.width.toFloat(),
                                ),
                            )
                        },
            )
        }
    }
}

@Composable
private fun DockTabItem(
    destination: DockDestination,
    isActive: Boolean,
    contentOffsetPx: Float,
    onSelect: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val label = stringResource(destination.labelRes)
    val a11yLabel = if (isActive) "$label, aktywna" else label
    val tint = if(isActive) RecipeTheme.colors.accent else RecipeTheme.colors.content
    Box(
        modifier =
            modifier.semantics {
                role = Role.Tab
                selected = isActive
                contentDescription = a11yLabel
                onClick {
                    onSelect()
                    true
                }
            },
        contentAlignment = Alignment.Center,
    ) {
        Column(
            modifier = Modifier.offset { IntOffset(contentOffsetPx.roundToInt(), 0) },
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
        ) {
            UnstyledIcon(
                imageVector = destination.icon,
                contentDescription = null,
                tint = tint,
                modifier = Modifier.size(DockTabIconSize),
            )
            Spacer(modifier = Modifier.size(DockTabIconLabelGap))
            BasicText(
                text = label,
                style =
                    RecipeTheme.typography.label.copy(
                        color = tint,
                        fontSize = DOCK_TAB_LABEL_FONT_SIZE_SP.sp,
                        lineHeight = DOCK_TAB_LABEL_LINE_HEIGHT_SP.sp,
                    ),
            )
        }
    }
}
