package theorycrafter.ui.settings

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Button
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.unit.dp
import compose.input.ClickCount
import compose.input.KeyShortcut
import compose.input.onKeyShortcut
import compose.input.onMousePress
import compose.utils.HSpacer
import compose.utils.VerticallyCenteredRow
import compose.utils.focusWhenClicked
import compose.widgets.*
import eve.data.EveItemType
import eve.data.asIsk
import theorycrafter.TheorycrafterContext
import theorycrafter.ui.Icons
import theorycrafter.ui.TheorycrafterTheme
import theorycrafter.ui.fiteditor.FitEditorKeyShortcuts
import theorycrafter.ui.tooltip
import theorycrafter.ui.widgets.CheckboxedRow
import theorycrafter.ui.widgets.CheckboxedText
import theorycrafter.ui.widgets.InnerDialog
import theorycrafter.ui.widgets.IskTextField
import theorycrafter.utils.ItemSelectionField
import theorycrafter.utils.ItemSelectionTextFieldProvider


/**
 * The pane for configuring price settings.
 */
@Composable
fun PriceSettingsPane() {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(TheorycrafterTheme.spacing.edgeMargins),
        verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xxxlarge)
    ) {
        Column(verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xsmall)) {
            Text(
                text = "Fit Editor",
                style = TheorycrafterTheme.textStyles.mediumHeading,
            )
            VerticallyCenteredRow {
                CheckboxedText(
                    text = "Show prices column in main view",
                    state =  TheorycrafterContext.settings.prices.showInFitEditorState
                )
                HSpacer(TheorycrafterTheme.spacing.xsmall)
                Text(
                    text = FitEditorKeyShortcuts.TogglePriceColumnKeyShortcut.displayString(),
                    color = LocalContentColor.current.copy(alpha = TheorycrafterTheme.textStyles.detailedText().alpha),
                )
            }
            CheckboxedText(
                text = "Show prices column in suggested items dropdown",
                state = TheorycrafterContext.settings.prices.showInFitEditorSuggestedItemsState
            )
            CheckboxedRow(
                state = TheorycrafterContext.settings.prices.colorizeState,
            ) {
                Column {
                    Text("Colorize prices")
                    Text(
                        text = "Cheap is blue, expensive is red",
                        style = TheorycrafterTheme.textStyles.detailedText(),
                    )
                }
            }
        }

        PriceOverridesEditor()
    }
}


/**
 * The widget for editing price overrides.
 */
@Composable
private fun PriceOverridesEditor() {
    Column(
        verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.small),
        modifier = Modifier.width(460.dp)
    ) {
        val eveData = TheorycrafterContext.eveData
        val eveItemPrices = TheorycrafterContext.eveItemPrices

        var showAddDialog by remember { mutableStateOf(false) }
        var editedItemType by remember { mutableStateOf<EveItemType?>(null) }

        Text(
            text = "Price Overrides",
            style = TheorycrafterTheme.textStyles.mediumHeading,
        )

        val overrides = eveItemPrices?.overrides
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(280.dp)
                .background(TheorycrafterTheme.colors.interactiveBackground()),
            contentAlignment = Alignment.Center,
        ) {
            if (overrides == null) {
                Text("Prices are still being loaded")
                return@Column
            } else if (overrides.isEmpty()) {
                Text("No overrides specified yet")
            } else {
                val overridesList = overrides.toList()

                val listState = rememberLazyListState()
                val selectionModel = rememberSingleItemSelectionModel(overridesList)

                LazyColumnExt(
                    modifier = Modifier
                        .fillMaxSize()
                        .focusWhenClicked()
                        .moveSelectionWithKeys(selectionModel)
                        .onKeyShortcut(KeyShortcut.DeleteItem) {
                            val itemId = selectionModel.selectedItem() ?: return@onKeyShortcut
                            val itemType = eveData.pricedItemType(itemId.first)
                            eveItemPrices.removeOverride(itemType)
                        },
                    state = listState,
                    selection = selectionModel
                ) {
                    val iconPadding = TheorycrafterTheme.spacing.xxsmall
                    items(overridesList, key = { it.first } ) { entry ->
                        val itemType = eveData.pricedItemType(entry.first)
                        val price = entry.second

                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(
                                    start = TheorycrafterTheme.spacing.horizontalEdgeMargin,
                                    end = TheorycrafterTheme.spacing.horizontalEdgeMargin - iconPadding
                                )
                                .padding(vertical = TheorycrafterTheme.spacing.xsmall)
                                .onMousePress(clickCount = ClickCount.DOUBLE) {
                                    editedItemType = itemType
                                },
                            horizontalArrangement = Arrangement.SpaceBetween,
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Text(itemType.name, modifier = Modifier.weight(1f))
                            Text(price.asIsk(withUnits = false))

                            HSpacer(TheorycrafterTheme.spacing.medium)
                            IconButton(
                                onClick = { editedItemType = itemType }
                            ) {
                                Icons.Edit(
                                    modifier = Modifier
                                        .tooltip("Edit ${itemType.name}")
                                        .padding(iconPadding)
                                        .size(16.dp)
                                )
                            }
                            HSpacer(TheorycrafterTheme.spacing.xxxsmall)
                            IconButton(
                                onClick = { eveItemPrices.removeOverride(itemType) }
                            ) {
                                Icons.Delete(
                                    modifier = Modifier
                                        .tooltip("Remove ${itemType.name}")
                                        .padding(iconPadding)
                                        .size(16.dp)
                                )
                            }
                        }
                    }
                }
            }
        }

        Button(
            onClick = { showAddDialog = true },
            modifier = Modifier
                .padding(top = TheorycrafterTheme.spacing.small)
                .align(Alignment.End)
        ) {
            Text("Add")
        }

        if (showAddDialog) {
            AddPriceOverrideDialog(
                onDismiss = { showAddDialog = false },
                onAdd = { itemType, price ->
                    eveItemPrices?.setOverride(itemType, price)
                }
            )
        }

        editedItemType?.let { itemType ->
            EditPriceOverrideDialog(
                itemType = itemType,
                initialPrice = eveItemPrices?.get(itemType),
                onChangePrice = { _, price ->
                    eveItemPrices?.setOverride(itemType, price)
                },
                onRemoveOverride = {
                    eveItemPrices?.removeOverride(itemType)
                },
                onDismiss = { editedItemType = null }
            )
        }
    }
}


/**
 * Dialog for adding a price override.
 */
@Composable
fun AddPriceOverrideDialog(
    onDismiss: () -> Unit,
    onAdd: (itemType: EveItemType, price: Double) -> Unit
) {
    PriceOverrideDialog(
        title = "Add Price Override",
        itemType = null,
        initialPrice = null,
        confirmText = "Add Override",
        onConfirm = onAdd,
        onDismiss = onDismiss,
        onRemove = null,
    )
}


/**
 * Dialog for editing a price override.
 */
@Composable
fun EditPriceOverrideDialog(
    itemType: EveItemType,
    initialPrice: Double?,
    onChangePrice: (itemType: EveItemType, price: Double) -> Unit,
    onRemoveOverride: (() -> Unit)?,
    onDismiss: () -> Unit,
) {
    val hasOverride = TheorycrafterContext.eveItemPrices?.isOverriden(itemType) == true
    PriceOverrideDialog(
        title = "Edit Price Override",
        itemType = itemType,
        initialPrice = initialPrice,
        confirmText = "Change Override",
        onConfirm = onChangePrice,
        onDismiss = onDismiss,
        onRemove = if (hasOverride) onRemoveOverride else null,
    )
}


/**
 * Generic dialog for editing a price override.
 */
@Composable
private fun PriceOverrideDialog(
    title: String,
    itemType: EveItemType?,
    initialPrice: Double?,
    confirmText: String,
    onConfirm: (itemType: EveItemType, price: Double) -> Unit,
    onRemove: (() -> Unit)?,
    onDismiss: () -> Unit,
) {
    var selectedItem by remember { mutableStateOf(itemType) }
    var price by remember { mutableStateOf(initialPrice) }
    val isValid = (selectedItem != null) && (price?.let { it >= 0 } == true)

    InnerDialog(
        title = title,
        confirmText = confirmText,
        dismissText = "Cancel",
        onConfirm = {
            if (isValid) {
                onConfirm(selectedItem!!, price!!)
            }
        },
        onDismiss = onDismiss,
        confirmEnabled = isValid,
        extraButtons = {
            if (onRemove != null) {
                FlatButtonWithText(
                    text = "Remove Override",
                    onClick = {
                        onRemove()
                        onDismiss()
                    }
                )
            }
        }
    ) {
        Column(
            verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.small),
            modifier = Modifier
                .width(460.dp)
                .padding(TheorycrafterTheme.spacing.edgeMargins)
        ) {
            val itemSelectionFieldFocusRequester = remember { FocusRequester() }
            val priceFieldFocusRequester = remember { FocusRequester() }
            ItemSelectionField(
                readOnly = itemType != null,
                initialItem = selectedItem,
                itemTypeByName = TheorycrafterContext.eveData.pricedItemTypeByName,
                autoSuggest = TheorycrafterContext.autoSuggest.pricedItemTypes,
                onItemSelected = { selectedItem = it },
                onSuggestedItemSelected = { priceFieldFocusRequester.requestFocus() },
                modifier = Modifier
                    .fillMaxWidth()
                    .focusRequester(itemSelectionFieldFocusRequester),
                textFieldProvider = ItemSelectionTextFieldProvider.TextField(
                    label = { Text("Item Name") },
                )
            )

            IskTextField(
                value = price,
                onValueChange = { price = it },
                constraint = { it >= 0 },
                label = { Text("Price") },
                modifier = Modifier
                    .fillMaxWidth()
                    .focusRequester(priceFieldFocusRequester)
                    .onKeyShortcut(KeyShortcut.anyEnter(), onPreview = true) {
                        if (isValid) {
                            onConfirm(selectedItem!!, price!!)
                            onDismiss()
                        }
                    }
            )

            LaunchedEffect(Unit) {
                if (itemType == null)
                    itemSelectionFieldFocusRequester.requestFocus()
                else
                    priceFieldFocusRequester.requestFocus()
            }
        }
    }
}