package theorycrafter.ui.fiteditor

import androidx.compose.ui.input.key.Key
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.runDesktopComposeUiTest
import eve.data.ModuleSlotType
import org.junit.Test
import theorycrafter.*
import theorycrafter.TheorycrafterContext.eveData
import theorycrafter.TheorycrafterContext.fits
import kotlin.test.assertEquals

/**
 * Tests related to the selection in the fit editor.
 */
@OptIn(ExperimentalTestApi::class)
class FitEditorSelectionTest: TheorycrafterTest() {


    /**
     * Tests that when a module is removed from an "illegal" slot, the selection remains at a valid position.
     */
    @Test
    fun selectionRemainsValidWhenInvalidModuleIsRemoved() = runDesktopComposeUiTest {
        val fit = newFit(shipName = "Legion")
        val core = eveData.subsystemType("Legion Core - Energy Parasitic Complex")
        val defensive = eveData.subsystemType("Legion Defensive - Covert Reconfiguration")
        val offensive = eveData.subsystemType("Legion Offensive - Assault Optimization")
        val propulsion = eveData.subsystemType("Legion Propulsion - Intercalated Nanofibers")
        val propulsionWithLessLowSlots = eveData.subsystemType("Legion Propulsion - Interdiction Nullifier")
        val lowSlotModule = eveData.moduleType("Multispectrum Coating I")

        fits.modifyAndSave {
            fit.setSubsystem(core)
            fit.setSubsystem(defensive)
            fit.setSubsystem(offensive)
            fit.setSubsystem(propulsion)
        }

        setApplicationContent {
            FitEditor(fit)
        }

        val lowSlotCount = fit.fitting.slots.low.value
        fits.modifyAndSave {
            // Fill the low slots
            for (slotIndex in 0 until lowSlotCount)
                fit.fitModule(lowSlotModule, slotIndex)

            // Set a subsystem with one less low slot
            fit.setSubsystem(propulsionWithLessLowSlots)
        }

        assertEquals(expected = lowSlotCount - 1, fit.fitting.slots.low.value)

        // Remove the invalid module
        onNode(Nodes.FitEditor.moduleRow(ModuleSlotType.LOW, lowSlotCount-1)).apply {
            scrollToAndClick()
            press(Key.Delete)
        }
        assertEquals(expected = lowSlotCount - 1, fit.modules.low.size)

        // Press Delete again and verify that another module has been removed.
        // If the selection is at an illegal place, this will not happen
        onNode(Nodes.FitEditor.KeyEventsReceiver).apply {
            press(Key.Delete)
        }
        assertEquals(expected = lowSlotCount - 2, fit.modules.low.size)
    }

}