package com.harshmallow.pilottoolkit.data

import kotlin.math.ceil

/* ─── Weight Limits (nullable fields for partial data) ─── */
data class WeightLimits(
    val minBew: Int? = null,
    val mtow: Int? = null,
    val maxRamp: Int
)

data class LinearFormula(val slope: Double, val intercept: Double)
data class EswlConfig(val weightFactor: Double, val wheelFactor: Double)

data class EswlThresholdEntry(val label: String, val value: Int, val unit: String = "lbs")
data class EswlThresholds(
    val singleWheel: EswlThresholdEntry,
    val dualWheel: EswlThresholdEntry,
    val note: String
)

data class SubgradeFormulas(
    val a: LinearFormula, val b: LinearFormula,
    val c: LinearFormula, val d: LinearFormula
) {
    fun forCategory(cat: SubgradeCategory): LinearFormula = when (cat) {
        SubgradeCategory.A -> a; SubgradeCategory.B -> b
        SubgradeCategory.C -> c; SubgradeCategory.D -> d
    }
}

data class PavementFormulas(val rigid: SubgradeFormulas, val flexible: SubgradeFormulas) {
    fun forType(type: PavementType): SubgradeFormulas = when (type) {
        PavementType.RIGID -> rigid; PavementType.FLEXIBLE -> flexible
    }
}

data class FuelBucket(val stageLength: Double, val fuelBurn: Double)

data class Aircraft(
    val id: String, val label: String, val available: Boolean,
    val weightLimits: WeightLimits? = null,
    val eswl: EswlConfig? = null,
    val eswlThresholds: EswlThresholds? = null,
    val pcn: PavementFormulas? = null, val pcr: PavementFormulas? = null,
    val pcnError: String? = null, val pcrError: String? = null,
    val fuelBuckets: List<FuelBucket>? = null
)

enum class PavementSystem(val label: String) { PCN("PCN"), PCR("PCR") }
enum class PavementType(val label: String) { RIGID("Rigid"), FLEXIBLE("Flexible") }
enum class SubgradeCategory(val label: String, val shortLabel: String) {
    A("A – High", "A High"), B("B – Medium", "B Med"),
    C("C – Low", "C Low"), D("D – Ultra Low", "D Ultra")
}

object Calculations {
    const val LB_PER_GAL_PER_KGL = 8.34540 // 1 kg/L = 8.34540 lb/US gal
    // ASTM D1250 Table 6B — Generalized Products density correction
    fun astmDensityLbGal(sg15: Double, tempC: Double): Double {
        val rho15 = sg15 * 1000.0 // kg/m³
        val K0 = 346.4228; val K1 = 0.4388
        val alpha15 = K0 / (rho15 * rho15) + K1 / rho15
        val deltaT = tempC - 15.0
        val VCF = kotlin.math.exp(-alpha15 * deltaT * (1.0 + 0.8 * alpha15 * deltaT))
        return (rho15 * VCF / 1000.0) * LB_PER_GAL_PER_KGL
    }
    fun roundUpToTen(value: Double) = (ceil(value / 10.0) * 10.0).toInt()
    fun fahrenheitToCelsius(f: Double) = (f - 32.0) / 1.8
    fun calculateESWL(weightLbs: Double, config: EswlConfig) = (weightLbs * config.weightFactor) / config.wheelFactor
    fun evaluateFormula(formula: LinearFormula, weightLbs: Double) = formula.slope * weightLbs + formula.intercept
}

enum class WarningLevel { WARNING, DANGER }
data class WeightWarning(val level: WarningLevel, val message: String, val blocksCalculation: Boolean = false)

fun checkWeightLimits(weight: Double, aircraft: Aircraft): WeightWarning? {
    val limits = aircraft.weightLimits ?: return null
    return when {
        weight > limits.maxRamp -> WeightWarning(WarningLevel.DANGER,
            "Exceeds ${aircraft.label} max ramp weight (${"%,d".format(limits.maxRamp)} lbs) — calculation blocked", true)
        limits.mtow != null && weight > limits.mtow -> WeightWarning(WarningLevel.WARNING,
            "Exceeds ${aircraft.label} MTOW (${"%,d".format(limits.mtow)} lbs)")
        limits.minBew != null && weight <= limits.minBew -> WeightWarning(WarningLevel.WARNING,
            "Weight is at or below typical BEW (${"%,d".format(limits.minBew)} lbs) — verify input")
        else -> null
    }
}

val aircraftRegistry: List<Aircraft> get() = DataLoader.aircraftRegistry

fun getAircraftById(id: String): Aircraft = aircraftRegistry.first { it.id == id }
