package theorycrafter.utils

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import compose.input.KeyShortcut
import compose.utils.HSpacer
import compose.widgets.AutoSuggestTextField
import compose.widgets.SingleLineText
import eve.data.EveItemType
import eve.data.ShipType
import theorycrafter.TheorycrafterContext
import theorycrafter.ui.Icons
import theorycrafter.ui.OutlinedTextField
import theorycrafter.ui.TextField
import theorycrafter.ui.TheorycrafterTheme
import theorycrafter.ui.fiteditor.isShipLegal


/**
 * A field for selecting an eve item.
 */
@Composable
fun <T: EveItemType> ItemSelectionField(
    readOnly: Boolean = false,
    itemTypeByName: Map<String, T>,
    initialItem: T? = null,
    autoSuggest: AutoSuggest<T>,
    onItemSelected: (T?) -> Unit,
    onSuggestedItemSelected: () -> Unit,
    isLegalItem: (T) -> Boolean = { true },
    modifier: Modifier = Modifier,
    textFieldProvider: ItemSelectionTextFieldProvider
) {
    if (readOnly) {
        textFieldProvider.provide(
            value = TextFieldValue(initialItem?.name ?: ""),
            readOnly = true,
            onValueChange = { },
            modifier = modifier,
        )
        return
    }

    AutoSuggestTextField(
        initialValue = initialItem,
        autoSuggest = autoSuggest,
        itemToString = EveItemType::name,
        onValueChange = {
            val itemType = itemTypeByName[it]
            onItemSelected(itemType)
        },
        onSuggestionChosen = { _, _ ->
            onSuggestedItemSelected()
        },
        chooseSuggestedValueKeyShortcuts = KeyShortcut.anyEnter() + KeyShortcut(Key.Tab),
        modifier = modifier,
        dropdownMenuDecorator = { matches, dropdownMenu ->
            if ((matches != null) && matches.isEmpty())
                NoMatches()
            else
                dropdownMenu(Modifier.heightIn(max = 250.dp))
        },
        menuItemModifier = { itemType ->
            Modifier
                .fillMaxWidth()
                .thenIf(!isLegalItem(itemType)) {
                    background(TheorycrafterTheme.colors.base().errorBackground)
                }
        },
        suggestedItemContent = { itemType, text ->
            Icons.EveItemType(
                itemType = itemType,
                modifier = Modifier.size(TheorycrafterTheme.sizes.eveTypeIconSmall)
            )
            HSpacer(TheorycrafterTheme.spacing.xsmall)
            SingleLineText(text)
        }
    ) { value, onValueChange, textFieldModifier ->
        textFieldProvider.provide(
            value = value,
            onValueChange = onValueChange,
            modifier = textFieldModifier,
            readOnly = false
        )
    }
}


/**
 * Provides the actual text field for [ItemSelectionField].
 */
fun interface ItemSelectionTextFieldProvider {


    @Composable
    fun provide(
        value: TextFieldValue,
        onValueChange: (TextFieldValue) -> Unit,
        modifier: Modifier,
        readOnly: Boolean,
    )


    companion object {


        /**
         * A filled textfield provider.
         */
        fun TextField(
            label: (@Composable () -> Unit)? = null,
            placeholder: (@Composable () -> Unit)? = null,
        ) = ItemSelectionTextFieldProvider { value, onValueChange, modifier, readOnly ->
            TheorycrafterTheme.TextField(
                value = value,
                onValueChange = onValueChange,
                modifier = modifier,
                readOnly = readOnly,
                singleLine = true,
                label = label,
                placeholder = placeholder
            )
        }


        /**
         * An outlined textfield provider.
         */
        fun OutlinedTextField(
            label: (@Composable () -> Unit)? = null,
            placeholder: (@Composable () -> Unit)? = null,
        ) = ItemSelectionTextFieldProvider { value, onValueChange, modifier, readOnly ->
            TheorycrafterTheme.OutlinedTextField(
                value = value,
                onValueChange = onValueChange,
                modifier = modifier,
                readOnly = readOnly,
                singleLine = true,
                label = label,
                placeholder = placeholder
            )
        }


    }
}


/**
 * A field for selecting a ship type.
 */
@Composable
fun ShipSelectionField(
    readOnly: Boolean,
    initialShipType: ShipType?,
    onShipSelected: (ShipType?) -> Unit,
    onSuggestedShipSelected: () -> Unit,
    modifier: Modifier = Modifier,
    textFieldProvider: ItemSelectionTextFieldProvider
){
    ItemSelectionField(
        readOnly = readOnly,
        itemTypeByName = TheorycrafterContext.eveData.shipTypeByName,
        initialItem = initialShipType,
        autoSuggest = TheorycrafterContext.autoSuggest.shipTypes,
        onItemSelected = { onShipSelected(it) },
        onSuggestedItemSelected = onSuggestedShipSelected,
        isLegalItem = { TheorycrafterContext.tournaments.activeRules.isShipLegal(it) },
        modifier = modifier,
        textFieldProvider = textFieldProvider,
    )
}
