package theorycrafter.fitting

import androidx.compose.runtime.Stable
import eve.data.Attributes
import eve.data.DamageType
import eve.data.SensorType
import eve.data.TacticalModeType
import eve.data.utils.ValueByEnum
import eve.data.utils.valueByEnum


/**
 * An instance of a tactical mode.
 *
 * Note that all the bonus attribute values here are the values by which the corresponding property is _divided_.
 * For example, a bonus value of 0.8 means a 25% increase in the affected property.
 */
@Stable
class TacticalMode internal constructor(


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


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


    /**
     * The mode type.
     */
    type: TacticalModeType


): EveItem<TacticalModeType>(attributes, type), FitItem {


    /**
     * The bonus to resistance.
     */
    val resonanceBonusDiv: ValueByEnum<DamageType, AttributeProperty<Double>?> by lazy {
        valueByEnum { damageType ->
            propertyOrNull(attributes.tacticalMode.resonanceBonusDiv[damageType])
        }
    }


    /**
     * The bonus to sensor strength.
     */
    val sensorStrengthBonusDiv: ValueByEnum<SensorType, AttributeProperty<Double>?> by lazy {
        valueByEnum { sensorType ->
            propertyOrNull(attributes.tacticalMode.sensorStrengthBonusDiv[sensorType])
        }
    }


    /**
     * The bonus to signature radius.
     */
    val signatureRadiusBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.signatureRadiusBonusDiv)


    /**
     * The bonus to agility.
     */
    val agilityBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.agilityBonusDiv)


    /**
     * The bonus to velocity, either ship velocity or MWD and/or AB speed boost.
     */
    val velocityBonusDiv: AttributeProperty<Double>? = run {
        propertyOrNull(attributes.tacticalMode.velocityBonusDiv) ?:
        propertyOrNull(attributes.tacticalMode.mwdVelocityPostDiv)  // Hecate for some reason gets its own
    }


    /**
     * The bonus to weapon optimal range.
     */
    val maxRangeBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.maxRangeBonusDiv)


    /**
     * The bonus to weapon tracking speed.
     */
    val trackingBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.trackingBonusDiv)


    /**
     * The bonus to targeting range.
     */
    val targetingRangeBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.targetRangeBonusDiv)


    /**
     * The bonus to weapon damage.
     */
    val damageBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.damageBonusDiv)


    /**
     * The bonus to EWAR resistance.
     */
    val ewarResistanceBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.ewarResistanceBonusDiv)


    /**
     * The bonus to MWD signature radius bloom.
     */
    val microwarpdriveSignaturePenaltyBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.mwdSigPenaltyBonusDiv)


    /**
     * The bonus to MWD capacitor use.
     */
    val microwarpdriveCapacitorBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.mwdCapBonusDiv)


    /**
     * The bonus to armor repairer duration.
     */
    val armorRepairerDurationBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.armorRepDurationBonusDiv)


    /**
     * The bonus to remote shield booster or armor repairer capacitor need.
     */
    val remoteRepairCapacitorCostDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.remoteRepairCapacitorCostPostDiv)


    /**
     * The bonus to remote shield booster or armor repairer repair amount.
     */
    val remoteRepairAmountDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.remoteRepairBonusPostDiv)


    /**
     * The bonus to shield recharge time.
     */
    val shieldRechargeBonusDiv: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.shieldRechargePostDiv)


    /**
     * The Skua bonus to light missile velocity.
     */
    val skuaLightMissileVelocityBonus: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.rookieLightMissileVelocity)


    /**
     * The Skua bonus to rocket velocity.
     */
    val skuaRocketVelocityBonus: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.rookieRocketVelocity)


    /**
     * The Anhinga bonus to missile RoF.
     */
    val anhingaMissileRoFBonus: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.shipBonus2CB)


    /**
     * The Anhinga bonus to missile velocity.
     */
    val anhingaMissileVelocityBonus: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.shipBonusCB3)


    /**
     * The Anhinga penalty to missile velocity.
     */
    val anhingaMissileVelocityReduction: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.shipBonusRole7)


    /**
     * The Anhinga bonus to missile flight time.
     */
    val anhingaMissileFlightTimeBonus: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.shipBonusRole8)


    /**
     * The Anhinga bonus to MJD reactivation delay.
     */
    val anhingaMjdReactivationDelayBonus: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.roleBonusMarauder)


    /**
     * The Anhinga bonus to ship inertia.
     */
    val anhingaShipInertiaBonus: AttributeProperty<Double>?
        get() = propertyOrNull(attributes.tacticalMode.shipBonusCI2)


}
