package theorycrafter.ui.widgets

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import compose.utils.VerticallyCenteredRow
import compose.utils.focusWhenClicked
import compose.utils.highlightOnHover
import compose.widgets.LazyColumnExt
import compose.widgets.unmodifiableSelectionModel
import theorycrafter.ui.TheorycrafterTheme


/**
 * UI where the left part is a list of pane names where only one can be selected at a time, and the right part displays
 * the pane corresponding to the one selected on the left.
 */
@Composable
fun <P: PaneDescriptor> Panes(
    paneDescriptors: List<P>,
    paneDescriptorsListModifier: Modifier,
    paneContent: @Composable (P) -> Unit,
    selectedPane: P,
    setSelectedPane: (P) -> Unit,
    modifier: Modifier = Modifier
) {
    val selection = remember(selectedPane) {
        unmodifiableSelectionModel(
            selectedIndex = paneDescriptors.indexOf(selectedPane),
            onSelectRequest = {
                setSelectedPane(paneDescriptors[it])
                true
            },
            selectableRange = paneDescriptors.indices
        )
    }
    val paneStateHolder = rememberSaveableStateHolder()
    ThreePanelScaffold(
        modifier = modifier,
        left = {
            LazyColumnExt(
                modifier = paneDescriptorsListModifier
                    .focusWhenClicked(),
                selection = selection
            ) {
                items(items = paneDescriptors) {
                    PaneDescriptorsListItem(it)
                }
            }
        },
        middle = {
            paneStateHolder.SaveableStateProvider(selectedPane) {
                paneContent(selectedPane)
            }
        }
    )

}


/**
 * An item in the list of pane descriptors.
 */
@Composable
private fun PaneDescriptorsListItem(descriptor: PaneDescriptor) {
    VerticallyCenteredRow(
        modifier = Modifier
            .highlightOnHover()
            .fillMaxWidth()
            .padding(TheorycrafterTheme.spacing.edgeMargins),
        horizontalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xxsmall)
    ) {
        descriptor.icon?.invoke(Modifier.size(20.dp))
        Text(descriptor.title)
    }
}


/**
 * The interface for a pane descriptor.
 */
interface PaneDescriptor {


    /**
     * The title/name of the pane.
     */
    val title: String


    /**
     * The icon of the pane.
     */
    val icon: (@Composable (Modifier) -> Unit)?


}