/**
 * Importing fits from Pyfa's SQLite database.
 */

package theorycrafter.formats

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import compose.widgets.FlatButtonWithText
import compose.widgets.SingleLineText
import eve.data.*
import eve.data.utils.ValueByEnum
import eve.data.utils.valueByEnum
import org.sqlite.SQLiteConfig
import theorycrafter.fitting.Module
import theorycrafter.storage.StoredFit
import theorycrafter.ui.TheorycrafterTheme
import theorycrafter.fits.defaultSubsystems
import theorycrafter.ui.widgets.DialogInitiallyFocusedButton
import theorycrafter.ui.widgets.InnerDialog
import theorycrafter.utils.NativeReadFilePickerDialog
import theorycrafter.utils.extensionFilenameFilter
import theorycrafter.utils.timeAction
import java.io.File
import java.sql.Connection
import java.sql.DriverManager
import java.sql.ResultSet


/**
 * Loads fits from a Pyfa database file.
 */
fun loadFitsFromPyfa(eveData: EveData, dbFile: File): FitsImportResult {
    if (!dbFile.exists() || !dbFile.isFile) {
        throw IllegalArgumentException("Pyfa database file not found: $dbFile")
    }

    val config = SQLiteConfig().apply {
        setReadOnly(true)
    }
    return DriverManager.getConnection("jdbc:sqlite:${dbFile.absoluteFile}", config.toProperties()).use { conn ->
        timeAction("Reading fits from Pyfa") {
            loadFromPyfa(eveData, conn)
        }
    }
}


/**
 * Loads fits from the given connection to a Pyfa database.
 */
private fun loadFromPyfa(eveData: EveData, connection: Connection): FitsImportResult {
    val pyfaFits = loadPyfaFits(connection)
    val moduleMutators = loadModuleMutatorsByModuleId(connection)
    val droneMutators = loadDroneMutatorsByDroneGroupId(connection)

    // Load fits
    val fits = mutableListOf<StoredFit>()
    val fitByPyfaId = mutableMapOf<Int, StoredFit>()
    val unsuccessful = mutableListOf<UnloadedFit>()
    for (pyfaFit in pyfaFits) {
        try {
            val storedFit = with(eveData) {
                loadFullFit(
                    connection = connection,
                    mutatorsByModuleId = moduleMutators,
                    mutatorsByDroneGroupId = droneMutators,
                    pyfaFit = pyfaFit
                )
            }
            if (storedFit != null) {
                fits.add(storedFit)
                fitByPyfaId[pyfaFit.id] = storedFit
                continue
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        unsuccessful.add(
            UnloadedFit(
                name = pyfaFit.name,
                shipTypeName = eveData.shipTypeOrNull(pyfaFit.shipTypeId)?.name ?: "Unknown Ship"
            )
        )
    }

    // Load command fits
    val commandFits = loadCommandFits(connection, fitByPyfaId)


    // Load projected fits and split them into friendly and hostile (some are both).
    fun StoredFit.anyModules(predicate: (StoredFit.StoredModule) -> Boolean): Boolean {
        return lowSlotRack.any { it != null && predicate(it) } ||
                medSlotRack.any { it != null && predicate(it) } ||
                highSlotRack.any { it != null && predicate(it) }
    }
    fun StoredFit.anyEffects(predicate: (Effect) -> Boolean): Boolean {
        return anyModules { module ->
            eveData.moduleType(module.itemId).effectReferences.any {
                predicate(eveData.effects[it])
            }
        } || droneGroups.any { droneGroup ->
            eveData.droneType(droneGroup.itemId).effectReferences.any {
                predicate(eveData.effects[it])
            }
        }
    }
    val projectedFitEffects = loadProjectedFits(connection, fitByPyfaId)
    val friendlyFitEffects = mutableListOf<ImportedRemoteFitEffect>()
    val hostileFitEffects = mutableListOf<ImportedRemoteFitEffect>()
    for (effect in projectedFitEffects) {
        val fit = effect.affectingFit
        if (fit.anyEffects { it.isProjected && it.isAssistive })
            friendlyFitEffects.add(effect)
        if (fit.anyEffects { it.isProjected && it.isOffensive })
            hostileFitEffects.add(effect)
    }

    return FitsImportResult(
        totalFitsCount = pyfaFits.size,
        fits = fits,
        commandFitEffects = commandFits,
        friendlyFitEffects = friendlyFitEffects,
        hostileFitEffects = hostileFitEffects,
        unsuccessful = unsuccessful
    )
}


/**
 * Executes the given SQL query and calls [block] with the result set.
 */
private inline fun <T> Connection.useResultRows(query: String, block: (ResultSet) -> T): T {
    return createStatement().use { statement ->
        statement.executeQuery(query).use { rs ->
            block(rs)
        }
    }
}


/**
 * Data class representing a Pyfa fit with its basic information.
 */
private data class PyfaFit(
    val id: Int,
    val name: String,
    val shipTypeId: Int
)


/**
 * Parses the current row in the [ResultSet] into a [PyfaFit].
 */
private fun ResultSet.getPyfaFit() = PyfaFit(
    id = getInt("ID"),
    name = getString("name"),
    shipTypeId = getInt("shipID")
)


/**
 * Retrieves all fits from the Pyfa database.
 */
private fun loadPyfaFits(connection: Connection): List<PyfaFit> {
    val query = "SELECT ID, name, shipID FROM fits"

    return buildList {
        connection.useResultRows(query) { rs ->
            while (rs.next()) {
                add(rs.getPyfaFit())
            }
        }
    }
}


/**
 * Encapsules the columns of a Pyfa mutator.
 */
private data class PyfaMutator(
    val attrId: Int,
    val value: Double,
)


/**
 * Parses the current row in the [ResultSet] into a [PyfaMutator].
 */
private fun ResultSet.getPyfaMutator() = PyfaMutator(
    attrId = getInt("attrID"),
    value = getDouble("value")
)


/**
 * Loads all the module mutators, mapping them by the module ID.
 */
private fun loadModuleMutatorsByModuleId(connection: Connection): Map<Int, List<PyfaMutator>> {
    return loadMutatorsByItemId(
        connection = connection,
        tableName = "mutators",
        itemIdColumnName = "moduleID"
    )
}


/**
 * Loads all the drone mutators, mapping them by the drone group ID.
 */
private fun loadDroneMutatorsByDroneGroupId(connection: Connection): Map<Int, List<PyfaMutator>> {
    return loadMutatorsByItemId(
        connection = connection,
        tableName = "mutatorsDrones",
        itemIdColumnName = "groupID"
    )
}


/**
 * Loads all the mutators, mapping them by the item ID.
 */
private fun loadMutatorsByItemId(
    connection: Connection,
    tableName: String,
    itemIdColumnName: String,
): Map<Int, List<PyfaMutator>> {
    val query = """
        SELECT $itemIdColumnName, attrID, value
        FROM $tableName 
    """

    return buildMap<Int, MutableList<PyfaMutator>> {
        connection.useResultRows(query) { rs ->
            while (rs.next()) {
                val mutators = getOrPut(rs.getInt(itemIdColumnName)) { mutableListOf() }
                mutators.add(rs.getPyfaMutator())
            }
        }
    }
}


/**
 * Loads the data needed to create a [StoredFit] for the given [PyfaFit].
 */
context(EveData)
private fun loadFullFit(
    connection: Connection,
    mutatorsByModuleId: Map<Int, List<PyfaMutator>>,
    mutatorsByDroneGroupId: Map<Int, List<PyfaMutator>>,
    pyfaFit: PyfaFit
): StoredFit? {
    val shipType = shipTypeOrNull(pyfaFit.shipTypeId) ?: return null

    val modulesBySlotType = loadFitModules(connection, mutatorsByModuleId, pyfaFit)
    val droneGroups = loadFitDrones(connection, mutatorsByDroneGroupId, pyfaFit)
    val cargoItems = loadFitCargo(connection, pyfaFit)
    val implants = loadFitImplants(connection, pyfaFit)
    val boosters = loadFitBoosters(connection, pyfaFit)
    val subsystems = if (shipType.usesSubsystems) {
        loadFitSubsystems(connection, pyfaFit, shipType)
    } else null
    val tacticalMode = if (shipType.hasTacticalModes) {
        loadFitTacticalMode(connection, pyfaFit)
    } else null

    // Load projected modules and drones
    val projectedModules = loadFitProjectedModules(connection, mutatorsByModuleId, pyfaFit)
    val projectedDrones = loadFitProjectedDrones(connection, mutatorsByDroneGroupId, pyfaFit)

    return StoredFit(
        id = null,
        creationTime = System.currentTimeMillis(),
        lastModifiedTime = System.currentTimeMillis(),
        name = pyfaFit.name,
        tags = emptyList(),
        skillSetId = null,
        shipTypeId = shipType.itemId,
        securityStatus = null,
        isFlagship = false,
        tacticalMode = tacticalMode,
        subsystems = subsystems,
        highSlotRack = modulesBySlotType[ModuleSlotType.HIGH] ?: emptyList(),
        medSlotRack = modulesBySlotType[ModuleSlotType.MEDIUM] ?: emptyList(),
        lowSlotRack = modulesBySlotType[ModuleSlotType.LOW] ?: emptyList(),
        rigs = modulesBySlotType[ModuleSlotType.RIG] ?: emptyList(),
        droneGroups = droneGroups,
        cargoItems = cargoItems,
        implants = implants,
        boosters = boosters,
        environments = emptyList(),
        commandEffects = emptyList(),
        hostileEffects = emptyList(),
        friendlyEffects = emptyList(),
        moduleEffects = projectedModules,
        droneEffects = projectedDrones,
        incomingDamageEffects = emptyList()
    )
}


/**
 * Maps Pyfa `dummySlot` numbers to [ModuleSlotType]s.
 */
private val ModuleSlotTypeByPyfaDummySlot = mapOf(
    1 to ModuleSlotType.LOW,
    2 to ModuleSlotType.MEDIUM,
    3 to ModuleSlotType.HIGH,
    4 to ModuleSlotType.RIG,
)


/**
 * Encapsulates the columns of a Pyfa module.
 */
private data class PyfaModule(
    val dummySlot: Int,
    val position: Int,
    val itemId: Int,
    val baseItemId: Int,
    val state: Int,
    val chargeId: Int,
    val mutaplasmidId: Int,
    val mutators: List<PyfaMutator>
) {


    /**
     * The id of the base module type.
     */
    val baseModuleTypeId: Int
        get() = if (baseItemId == 0) itemId else baseItemId


    /**
     * Returns a corresponding [StoredFit.StoredModule].
     */
    context(EveData)
    fun toStoredModule(): StoredFit.StoredModule? {
        val baseModuleTypeId = baseModuleTypeId
        if (baseModuleTypeId == 0)
            return null

        if (moduleTypeOrNull(baseModuleTypeId) == null)
            return null
        val mutaplasmid = if (mutaplasmidId != 0) mutaplasmid(mutaplasmidId) else null
        val mutation = if (mutaplasmid != null) {
            StoredFit.StoredMutation(
                mutaplasmidId = mutaplasmidId,
                attributeIdsAndValues = mutators.map { it.attrId to it.value }
            )
        } else null

        return StoredFit.StoredModule(
            itemId = baseModuleTypeId,
            enabled = true,
            state = when (state) {
                -1 -> Module.State.OFFLINE
                0 -> Module.State.ONLINE
                1 -> Module.State.ACTIVE
                2 -> Module.State.OVERLOADED
                else -> Module.State.ONLINE
            },
            chargeId = chargeId.takeIf { it > 0 },
            mutation = mutation,
            extraAttributes = emptyList()
        )
    }


}


/**
 * Parses the current row in the [ResultSet] into a [PyfaModule].
 */
context(EveData)
private fun ResultSet.getPyfaModule(mutatorsByModuleId: Map<Int, List<PyfaMutator>>): PyfaModule {
    val moduleId = getInt("ID")
    return PyfaModule(
        dummySlot = getInt("dummySlot"),
        position = getInt("position"),
        itemId = getInt("itemID"),
        baseItemId = getInt("baseItemID"),
        state = getInt("state"),
        chargeId = getInt("chargeID"),
        mutaplasmidId = getInt("mutaplasmidID"),
        mutators = mutatorsByModuleId[moduleId] ?: emptyList()
    )
}


/**
 * Gets modules for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitModules(
    connection: Connection,
    mutatorsByModuleId: Map<Int, List<PyfaMutator>>,
    pyfaFit: PyfaFit
): Map<ModuleSlotType, List<StoredFit.StoredModule?>> {
    val query = """
        SELECT ID, itemID, baseItemID, chargeID, state, position, dummySlot, mutaplasmidID
        FROM modules
        WHERE fitID = ? AND projected = 0
    """

    val pyfaModulesBySlotType =
        buildList {
            connection.prepareStatement(query).use { stmt ->
                stmt.setInt(1, pyfaFit.id)
                stmt.executeQuery().use { rs ->
                    while (rs.next()) {
                        add(rs.getPyfaModule(mutatorsByModuleId))
                    }
                }
            }
        }.groupBy {
            // Group by actual or dummy slot type
            val baseModuleTypeId = it.baseModuleTypeId
            if (baseModuleTypeId == 0) {
                ModuleSlotTypeByPyfaDummySlot[it.dummySlot]
            } else {
                moduleTypeOrNull(baseModuleTypeId)?.slotType
            }
        }

    val result = mutableMapOf<ModuleSlotType, List<StoredFit.StoredModule?>>()
    if (null !in pyfaModulesBySlotType.keys) {
        // Good case; all the slot types are known
        for ((slotType, pyfaModules) in pyfaModulesBySlotType.entries) {
            result[slotType!!] = pyfaModules
                .sortedBy { it.position }
                .map { it.toStoredModule() }
        }
    } else {
        // Some modules have an unknown slot type (because the module itself is unknown).
        // In this case we give up on placing modules in correct slots, and just put all
        // non-null modules in their racks
        for ((slotType, pyfaModules) in pyfaModulesBySlotType.entries) {
            if (slotType == null) continue
            result[slotType] = pyfaModules.mapNotNull { it.toStoredModule() }
        }
    }
    return result
}


/**
 * Gets projected modules for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitProjectedModules(
    connection: Connection,
    mutatorsByModuleId: Map<Int, List<PyfaMutator>>,
    pyfaFit: PyfaFit
): List<StoredFit.StoredModule> {
    val query = """
        SELECT ID, itemID, baseItemID, chargeID, state, position, dummySlot, mutaplasmidID
        FROM modules
        WHERE fitID = ? AND projected = 1
    """
    return buildList {
        connection.prepareStatement(query).use { stmt ->
            stmt.setInt(1, pyfaFit.id)
            stmt.executeQuery().use { rs ->
                while (rs.next()) {
                    val module = rs.getPyfaModule(mutatorsByModuleId).toStoredModule()
                    if (module != null) {
                        add(module)
                    }
                }
            }
        }
    }
}


/**
 * Loads drones from the Pyfa database.
 */
context(EveData)
private fun loadFitDrones(
    connection: Connection,
    mutatorsByDroneGroupId: Map<Int, List<PyfaMutator>>,
    pyfaFit: PyfaFit,
    projected: Boolean
): List<StoredFit.StoredDroneGroup> {
    val query = """
        SELECT groupID, itemID, baseItemID, amount, amountActive, mutaplasmidID 
        FROM drones 
        WHERE fitID = ? AND projected = ${if (projected) "1" else "0"}
    """
    return buildList {
        connection.prepareStatement(query).use { stmt ->
            stmt.setInt(1, pyfaFit.id)
            val rs = stmt.executeQuery()

            while (rs.next()) {
                val groupId = rs.getInt("groupID")
                val itemId = rs.getInt("itemID")
                val baseItemId = rs.getInt("baseItemID")
                val amount = rs.getInt("amount")
                val amountActive = rs.getInt("amountActive")
                val mutaplasmidId = rs.getInt("mutaplasmidID")

                val droneTypeId = if (baseItemId == 0) itemId else baseItemId
                if (droneTypeOrNull(droneTypeId) == null)
                    continue
                val mutaplasmid = if (mutaplasmidId != 0) mutaplasmid(mutaplasmidId) else null
                val mutation = if (mutaplasmid != null) {
                    val mutators = mutatorsByDroneGroupId[groupId] ?: emptyList()
                    StoredFit.StoredMutation(
                        mutaplasmidId = mutaplasmidId,
                        attributeIdsAndValues = mutators.map { it.attrId to it.value }
                    )
                } else null

                add(
                    StoredFit.StoredDroneGroup(
                        itemId = droneTypeId,
                        size = amount,
                        active = amountActive > 0,
                        mutation = mutation
                    )
                )
            }
        }
    }
}


/**
 * Gets drones for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitDrones(
    connection: Connection,
    mutatorsByDroneGroupId: Map<Int, List<PyfaMutator>>,
    pyfaFit: PyfaFit,
): List<StoredFit.StoredDroneGroup> {
    return loadFitDrones(
        connection = connection,
        mutatorsByDroneGroupId = mutatorsByDroneGroupId,
        pyfaFit = pyfaFit,
        projected = false
    )
}


/**
 * Gets projected drones for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitProjectedDrones(
    connection: Connection,
    mutatorsByDroneGroupId: Map<Int, List<PyfaMutator>>,
    pyfaFit: PyfaFit,
): List<StoredFit.StoredDroneGroup> {
    return loadFitDrones(
        connection = connection,
        mutatorsByDroneGroupId = mutatorsByDroneGroupId,
        pyfaFit = pyfaFit,
        projected = true
    )
}


/**
 * Gets cargo items for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitCargo(connection: Connection, pyfaFit: PyfaFit): List<StoredFit.StoredCargoItem> {
    val query = "SELECT itemID, amount FROM cargo WHERE fitID = ?"

    return buildList {
        connection.prepareStatement(query).use { stmt ->
            stmt.setInt(1, pyfaFit.id)
            stmt.executeQuery().use { rs ->
                while (rs.next()) {
                    val itemId = rs.getInt("itemID")
                    val amount = rs.getInt("amount")

                    cargoItemTypeOrNull(itemId) ?: continue

                    add(
                        StoredFit.StoredCargoItem(
                            itemId = itemId,
                            amount = amount
                        )
                    )
                }
            }
        }
    }
}


/**
 * Gets implants for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitImplants(connection: Connection, pyfaFit: PyfaFit): List<StoredFit.StoredImplant> {
    val query = """
        SELECT i.itemID, i.active 
        FROM implants i 
        JOIN fitImplants fi ON i.ID = fi.implantID 
        WHERE fi.fitID = ?
    """
    return buildList {
        connection.prepareStatement(query).use { stmt ->
            stmt.setInt(1, pyfaFit.id)
            stmt.executeQuery().use { rs ->
                while (rs.next()) {
                    val itemId = rs.getInt("itemID")
                    val active = rs.getBoolean("active")

                    implantTypes.getOrNull(itemId) ?: continue

                    add(
                        StoredFit.StoredImplant(
                            itemId = itemId,
                            enabled = active
                        )
                    )
                }
            }
        }
    }
}


/**
 * Gets boosters for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitBoosters(connection: Connection, pyfaFit: PyfaFit): List<StoredFit.StoredBooster> {
    val boostersQuery = """
        SELECT ID, itemID, active
        FROM boosters
        WHERE fitID = ?
    """
    val sideEffectsQuery = """
        SELECT effectID
        from boosterSideEffects
        where boosterID = ? AND active = 1
    """
    return buildList {
        connection.prepareStatement(sideEffectsQuery).use { sideEffectsStatement ->
            connection.prepareStatement(boostersQuery).use { boosterStatement ->
                boosterStatement.setInt(1, pyfaFit.id)
                boosterStatement.executeQuery().use { rs ->
                    while (rs.next()) {
                        val itemId = rs.getInt("itemID")
                        val active = rs.getBoolean("active")

                        val boosterType = boosterTypeOrNull(itemId) ?: continue
                        val sideEffectByEffectId = boosterType.sideEffects.associateBy { it.effectId }

                        sideEffectsStatement.setInt(1, rs.getInt("ID"))
                        val activeSideEffects = sideEffectsStatement.executeQuery().use { sideEffectsResultSet ->
                            buildList {
                                while (sideEffectsResultSet.next()) {
                                    val effectId = sideEffectsResultSet.getInt("effectID")
                                    val sideEffect = sideEffectByEffectId[effectId] ?: continue
                                    add(sideEffect)
                                }
                            }
                        }

                        add(
                            StoredFit.StoredBooster(
                                itemId = itemId,
                                enabled = active,
                                activeSideEffectPenalizedAttributeIds = activeSideEffects.map { it.penalizedAttribute.id },
                            )
                        )
                    }
                }
            }
        }
    }
}


/**
 * Gets subsystems for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitSubsystems(
    connection: Connection,
    pyfaFit: PyfaFit,
    shipType: ShipType,
): ValueByEnum<SubsystemType.Kind, StoredFit.StoredSubsystem> {
    val query = """
        SELECT m.itemID 
        FROM modules m 
        WHERE m.fitID = ? AND m.projected = 0 
    """
    val subsystemIds = buildList {
        connection.prepareStatement(query).use { stmt ->
            stmt.setInt(1, pyfaFit.id)
            stmt.executeQuery().use { rs ->
                while (rs.next()) {
                    add(rs.getInt("itemID"))
                }
            }

        }
    }

    val subsystemByKind = buildMap {
        for (subsystemId in subsystemIds) {
            val subsystemType = subsystemTypeOrNull(subsystemId) ?: continue
            put(subsystemType.kind, subsystemType)
        }
    }

    val defaultSubsystemByKind by lazy { shipType.defaultSubsystems() }
    return valueByEnum<SubsystemType.Kind, StoredFit.StoredSubsystem> { kind ->
        StoredFit.StoredSubsystem(subsystemByKind[kind] ?: defaultSubsystemByKind[kind])
    }
}


/**
 * Gets tactical mode for a fit from the Pyfa database.
 */
context(EveData)
private fun loadFitTacticalMode(connection: Connection, pyfaFit: PyfaFit): StoredFit.StoredTacticalMode? {
    val query = "SELECT modeID FROM fits WHERE ID = ?"
    connection.prepareStatement(query).use { stmt ->
        stmt.setInt(1, pyfaFit.id)
        stmt.executeQuery().use { rs ->
            if (rs.next()) {
                val modeId = rs.getInt("modeID")
                val tacticalModeType = tacticalModeTypeOrNull(modeId)
                if (tacticalModeType != null) {
                    return StoredFit.StoredTacticalMode(tacticalModeType)
                }
            }
        }
    }

    return null
}


/**
 * Gets all command fits from the Pyfa database.
 */
private fun loadCommandFits(
    connection: Connection,
    fitByPyfaId: Map<Int, StoredFit>
): List<ImportedRemoteFitEffect> {
    val query = "SELECT boostedID, boosterID, active FROM commandFits"
    return buildList {
        connection.useResultRows(query) { rs ->
            while (rs.next()) {
                val affectingFit = fitByPyfaId[rs.getInt("boosterID")] ?: continue
                val affectedFit = fitByPyfaId[rs.getInt("boostedID")] ?: continue
                val active = rs.getBoolean("active")
                add(
                    ImportedRemoteFitEffect(
                        affectingFit = affectingFit,
                        affectedFit = affectedFit,
                        amount = 1,
                        enabled = active
                    )
                )
            }
        }
    }
}


/**
 * Gets all projected fits from the Pyfa database.
 */
private fun loadProjectedFits(
    connection: Connection,
    fitByPyfaId: Map<Int, StoredFit>
): List<ImportedRemoteFitEffect> {
    val query = "SELECT sourceID, victimID, amount, active FROM projectedFits"
    return buildList {
        connection.useResultRows(query) { rs ->
            while (rs.next()) {
                val affectingFit = fitByPyfaId[rs.getInt("sourceID")] ?: continue
                val affectedFitId = fitByPyfaId[rs.getInt("victimID")] ?: continue
                val amount = rs.getInt("amount")
                val active = rs.getBoolean("active")
                add(
                    ImportedRemoteFitEffect(
                        affectingFit = affectingFit,
                        affectedFit = affectedFitId,
                        amount = amount,
                        enabled = active
                    )
                )
            }
        }
    }
}


/**
 * A dialog for selecting the Pyfa database file.
 */
@Composable
fun PyfaDbSelectionDialog(
    onConfirm: (dbFile: File) -> Unit,
    onDismiss: () -> Unit
) {
    var currentFile by remember {
        mutableStateOf(
            File("${System.getProperty("user.home")}/.pyfa/saveddata.db")
        )
    }
    val currentPathExists = currentFile.isFile
    var showFilePicker by remember { mutableStateOf(false) }

    InnerDialog(
        title = "Select Pyfa Database File",
        confirmText = "Use This File",
        dismissText = "Cancel",
        onDismiss = onDismiss,
        onConfirm = { onConfirm(currentFile) },
        confirmEnabled = currentPathExists,
        initiallyFocusedButton = DialogInitiallyFocusedButton.Confirm,
        extraButtons = {
            FlatButtonWithText(
                text = "Choose File…",
                onClick = { showFilePicker = true }
            )
        }
    ) {
        Column(verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xsmall)) {
            if (!currentPathExists) {
                SingleLineText(
                    text = "Could not locate Pyfa database at:",
                    color = TheorycrafterTheme.colors.base().errorContent,
                )
            } else {
                SingleLineText("Found Pyfa database at:")
            }
            SelectionContainer {
                Text(
                    text = currentFile.absolutePath,
                    modifier = Modifier.fillMaxWidth()
                )
            }
        }
    }

    if (showFilePicker) {
        NativeReadFilePickerDialog(
            title = "Select Pyfa Database File",
            filenameFilter = extensionFilenameFilter(ignoreCase = true, "db"),
            onCompletedSelecting = { file ->
                showFilePicker = false
                if (file != null) {
                    currentFile = file
                }
            }
        )
    }
}
