package theorycrafter.ui.fiteditor

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.ComposeUiTest
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.runDesktopComposeUiTest
import androidx.compose.ui.unit.dp
import theorycrafter.TheorycrafterContext.eveData
import theorycrafter.TheorycrafterContext.fits
import theorycrafter.TheorycrafterTest
import theorycrafter.fitting.Fit
import theorycrafter.formats.fitFromEft
import theorycrafter.setApplicationContent
import theorycrafter.ui.fitstats.FitStats
import kotlin.test.Test
import kotlin.test.assertNotNull


/**
 * Tests creating and displaying various fits.
 */
@OptIn(ExperimentalTestApi::class)
class FitShipsTests: TheorycrafterTest() {


    /**
     * Sets the content to test displaying the given fit.
     */
    private fun ComposeUiTest.displayFit(fitState: State<Fit?>) {
        setApplicationContent {
            val fit = fitState.value ?: return@setApplicationContent
            Row {
                Box(Modifier.width(700.dp)) {
                    FitEditor(fit)
                }
                FitStats(fit)
            }
        }
    }


    /**
     * Displays the fit given in EFT format.
     */
    private suspend fun ComposeUiTest.displayEftFit(fitText: String) {
        val storedFit = with(eveData) { fitFromEft(fitText) }
        assertNotNull(storedFit, "Unable to parse fit from EFT format")

        val fitHandle = fits.add(storedFit)
        val fit = fits.engineFitOf(fitHandle)
        displayFit(mutableStateOf(fit))
    }


    /**
     * Creates and displays empty fits for all ship types.
     */
    @Test
    fun displayFitsOfAllShips() = runDesktopComposeUiTest {
        val fit = mutableStateOf<Fit?>(null)

        displayFit(fit)

        val shipTypes = eveData.shipTypes
        for (shipType in shipTypes) {
            val fitName = "${shipType.name} fit"
            val fitHandle = fits.addEmpty(name = fitName, shipType = shipType)
            fit.value = fits.engineFitOf(fitHandle)
            waitForIdle()
        }
        println("Opened fits of ${shipTypes.size} ships")
    }


    /**
     * Creates and displays a fit with an unloaded weapon.
     */
    @Test
    fun displayFitWithUnloadedWeapon() = runDesktopComposeUiTest {
        displayEftFit("""
            [Rifter, Rifter]

            [Empty Low slot]
            [Empty Low slot]
            [Empty Low slot]
            [Empty Low slot]

            [Empty Med slot]
            [Empty Med slot]
            [Empty Med slot]

            125mm Gatling AutoCannon II
            [Empty High slot]
            [Empty High slot]

            [Empty Rig slot]
            [Empty Rig slot]
            [Empty Rig slot]
        """.trimIndent()
        )
    }


}