/**
 * Defines the subsystems to use when creating a new strategic cruiser fit.
 */

package theorycrafter.ui.fiteditor

import eve.data.ShipType
import eve.data.SubsystemType
import eve.data.typeid.isLegion
import eve.data.typeid.isLoki
import eve.data.typeid.isProteus
import eve.data.typeid.isTengu
import eve.data.utils.ValueByEnum
import eve.data.utils.mapValues
import theorycrafter.TheorycrafterContext
import theorycrafter.fitting.Fit
import theorycrafter.fitting.Subsystem


/**
 * Returns the initial subsystems that should be set on the given ship that uses subsystems.
 */
fun ShipType.defaultInitialSubsystems(): ValueByEnum<SubsystemType.Kind, SubsystemType> {
    val subsystemsByKind = TheorycrafterContext.eveData.subsystemTypes(this)
    return when {
        isTengu() -> subsystemsByKind.selectNamed(TENGU_INITIAL_SUBSYSTEM_NAMES)
        isLoki() -> subsystemsByKind.selectNamed(LOKI_INITIAL_SUBSYSTEM_NAMES)
        isLegion() -> subsystemsByKind.selectNamed(LEGION_INITIAL_SUBSYSTEM_NAMES)
        isProteus() -> subsystemsByKind.selectNamed(PROTEUS_INITIAL_SUBSYSTEM_NAMES)
        else -> subsystemsByKind.mapValues { it.minByOrNull(SubsystemType::itemId)!! }  // Must pick something
    }
}


/**
 * Returns the initial subsystems that should be set on the given ship; `null` if the ship does not use subsystems.
 */
fun ShipType.defaultInitialSubsystemsOrNull(): ValueByEnum<SubsystemType.Kind, SubsystemType>? {
    return if (usesSubsystems) defaultInitialSubsystems() else null
}


/**
 * The names of Tengu subsystems to fit initially.
 */
private val TENGU_INITIAL_SUBSYSTEM_NAMES = setOf(
    "Tengu Core - Augmented Graviton Reactor",
    "Tengu Defensive - Amplification Node",
    "Tengu Offensive - Accelerated Ejection Bay",
    "Tengu Propulsion - Fuel Catalyst"
)


/**
 * The names of Loki subsystems to fit initially.
 */
private val LOKI_INITIAL_SUBSYSTEM_NAMES = setOf(
    "Loki Core - Immobility Drivers",
    "Loki Defensive - Adaptive Defense Node",
    "Loki Offensive - Launcher Efficiency Configuration",
    "Loki Propulsion - Wake Limiter"
)


/**
 * The names of Legion subsystems to fit initially.
 */
private val LEGION_INITIAL_SUBSYSTEM_NAMES = setOf(
    "Legion Core - Augmented Antimatter Reactor",
    "Legion Defensive - Nanobot Injector",
    "Legion Offensive - Liquid Crystal Magnifiers",
    "Legion Propulsion - Wake Limiter"
)

/**
 * The names of Proteus subsystems to fit initially.
 */
private val PROTEUS_INITIAL_SUBSYSTEM_NAMES = setOf(
    "Proteus Core - Friction Extension Processor",
    "Proteus Defensive - Nanobot Injector",
    "Proteus Offensive - Hybrid Encoding Platform",
    "Proteus Propulsion - Hyperspatial Optimization"
)


/**
 * Selects the subsystems with the given names.
 */
private fun ValueByEnum<SubsystemType.Kind, List<SubsystemType>>.selectNamed(names: Set<String>) =
    mapValues { subsystems ->
        subsystems.find { it.name in names }!!
    }


/**
 * Because we always fit all subsystems, we can provide this extension, where the subsystems are never `null`.
 */
@Suppress("UNCHECKED_CAST")
val Fit.requiredSubsystemByKind: ValueByEnum<SubsystemType.Kind, Subsystem>?
    get() = subsystemByKind as ValueByEnum<SubsystemType.Kind, Subsystem>?