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.junit4.ComposeContentTestRule
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.runBlockingTest
import theorycrafter.setApplicationContent
import theorycrafter.ui.fitstats.FitStats
import kotlin.test.Test
import kotlin.test.assertNotNull


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


    /**
     * Sets the content to test displaying the given fit.
     */
    private fun ComposeContentTestRule.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 ComposeContentTestRule.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() = runBlockingTest {
        val fit = mutableStateOf<Fit?>(null)

        rule.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)
            rule.waitForIdle()
        }
        println("Opened fits of ${shipTypes.size} ships")
    }


    /**
     * Creates and displays a fit with an unloaded weapon.
     */
    @Test
    fun displayFitWithUnloadedWeapon() = runBlockingTest {
        rule.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()
        )
    }


}