/**
 * The UI showing a fit's targeting stats.
 */

package theorycrafter.ui.fitstats

import androidx.compose.runtime.Composable
import eve.data.*
import theorycrafter.fitting.Fit
import theorycrafter.fitting.jamChance
import theorycrafter.fitting.lockTime
import theorycrafter.ui.fiteditor.ValueWithDescription


/**
 * UI showing the targeting stats (range, scan resolution etc.)
 */
@Composable
fun TargetingStats(fit: Fit) {
    with(fit.targeting) {
        val range = targetingRange.value
        val maxTargets = maxLockedTargets
        val sensorStrength = sensors.strength.value
        val sensorType = sensors.type
        val jamChance = fit.jammedChance()
        val scanRes = scanResolution.value
        val sensorDampeningResonance = fit.electronicWarfare.sensorDampenerResistance.value
        val ecmResonance = fit.electronicWarfare.ecmResistance.value

        val resistanceToDampeningTooltip = if (sensorDampeningResonance != 1.0) {
            ValueWithDescription(
                value = sensorDampeningResonance.resonanceAsResistancePercentageWithPrecisionAtMost(0),
                description = "resistance to sensor dampening"
            )
        } else null

        val resistanceToEcmTooltip = if (ecmResonance != 1.0) {
            ValueWithDescription(
                value = ecmResonance.resonanceAsResistancePercentageWithPrecisionAtMost(0),
                description = "resistance to ECM"
            )
        } else null

        val targetingTimes = buildList {
            add(ValueWithDescription("Lock", "Times"))
            for ((name, sigRadius, mwdFactor) in TargetingTimeTooltipExamples) {
                add(ValueWithDescription(
                    value = lockTime(scanRes, sigRadius).millisAsTimeSec(units = "s"),
                    description = "$name (${sigRadius.asSignatureRadius()})"
                ))
                if (mwdFactor != null) {
                    val sigRadiusWithMwd = sigRadius * mwdFactor
                    add(ValueWithDescription(
                        value = lockTime(scanRes, sigRadiusWithMwd).millisAsTimeSec(units = "s"),
                        description = "$name with MWD (${sigRadiusWithMwd.asSignatureRadius()})"
                    ))
                }
            }
        }

        StatsTable(
            columns = 3,
            Stat(
                label = "Targeting Range",
                value = range.asDistance(withUnits = true),
                tooltipValues = listOfNotNull(
                    ValueWithDescription(
                        value = range.asDistance(withUnits = true, kmThreshold = Int.MAX_VALUE),
                        description = "targeting range"
                    ),
                    ValueWithDescription(
                        value = maxTargets.toString(),
                        description = "max. locked targets"
                    ),
                    resistanceToDampeningTooltip
                )
            ),
            Stat(
                label = "${sensorType.shortDisplayName} Sensors",
                value = sensorStrength.asSensorStrength(withUnits = true) +
                    if (jamChance > 0.0) " (${jamChance.fractionAsPercentage(0)})" else "",
                tooltipValues = listOfNotNull(
                    ValueWithDescription(
                        value = jamChance.fractionAsPercentageWithPrecisionAtMost(1),
                        description = "chance of being jammed"
                    ),
                    resistanceToEcmTooltip
                )
            ),
            Stat(
                label = "Scan Resolution",
                value = scanRes.asScanResolution(withUnits = true),
                tooltipValues = listOfNotNull(
                    resistanceToDampeningTooltip
                ) + targetingTimes
            ),
        )
    }
}


/**
 * Returns the chance of a successful jam by all remote ECM modules/drones on this fit.
 */
private fun Fit.jammedChance(): Double {
    val activeEffects = remoteEffects.hostile.activeIncludingAuxiliary
    val ecmModules = activeEffects.flatMap { effect ->
        effect.affectingModules.filter { it.active }
    }
    val ecmDrones = activeEffects.flatMap { effect ->
        effect.affectingDrones.filter { it.active }
    }
    return jamChance(
        sensorType = targeting.sensors.type,
        sensorStrength = targeting.sensors.strength.value,
        ecmResistance = electronicWarfare.ecmResistance.value,
        ecmModules = ecmModules,
        ecmDrones = ecmDrones
    )
}


/**
 * The data of the examples whose lock time to show in the scan resolution tooltip.
 */
private val TargetingTimeTooltipExamples = listOf(
    // Name, signature radius, mwd signature radius factor
    Triple("Pod", 25.0, null),
    Triple("Interceptor", 35.0, 2.25),
    Triple("Frigate", 40.0, 6.0),
    Triple("Destroyer", 80.0, 6.0),
    Triple("Cruiser", 130.0, 6.0),
    Triple("Battlecruiser", 300.0, 6.0),
    Triple("Battleship", 400.0, 6.0),
)
