package theorycrafter.fitting

import androidx.compose.runtime.Stable
import androidx.compose.runtime.toMutableStateMap
import eve.data.Attribute
import eve.data.Attributes
import eve.data.BoosterType


/**
 * An instance of a booster.
 */
@Stable
class Booster internal constructor(


    /**
     * The fit this booster is part of.
     */
    override val fit: Fit,


    /**
     * The context [Attributes].
     */
    attributes: Attributes,


    /**
     * The booster type.
     */
    type: BoosterType,


): EveItem<BoosterType>(attributes, type), FitItemWithEnabledState {


    override val enabledState = EnabledState()


    /**
     * Specifies which side effects are active for this booster.
     */
    internal val sideEffectActiveStateByPenalizedAttribute: MutableMap<Attribute<*>, Boolean> =
        type.sideEffects.map { it.penalizedAttribute to false }.toMutableStateMap()


    /**
     * Returns whether the given side effect is active.
     */
    fun isSideEffectActive(sideEffect: BoosterType.SideEffect): Boolean {
        return sideEffectActiveStateByPenalizedAttribute[sideEffect.penalizedAttribute]!!
    }


    /**
     * Returns the value of the modifying attribute of the given side effect.
     *
     * This should always be a percentage.
     */
    fun sideEffectMagnitude(sideEffect: BoosterType.SideEffect): Double {
        return properties.get(sideEffect.penalizingAttribute).doubleValue
    }


    /**
     * The duration of the booster, in milliseconds.
     */
    val duration: AttributeProperty<Double>
        get() = property(attributes.boosterDuration)


    /**
     * The time since epoch, in days, when this booster can be injected; `null` if this booster doesn't expire.
     */
    val lastInjectionDateTime: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.boosterLastInjectionDatetime)


    /**
     * The chance of side effects, a fraction.
     *
     * There are actually 5 of these attributes, but they all have the same value, and there's nothing to tie each of
     * them to the side effect whose chance they specify.
     */
    val sideEffectChance: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.boosterSideEffectChance.first())


}
