package com.harshmallow.pilottoolkit.ui.modules

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.harshmallow.pilottoolkit.data.*
import com.harshmallow.pilottoolkit.ui.components.*
import com.harshmallow.pilottoolkit.ui.theme.ToolkitTheme
import kotlin.math.ceil
import kotlin.math.floor

@Composable
fun PavementModule(aircraft: Aircraft) {
    val colors = ToolkitTheme.colors
    var weightInput by remember { mutableStateOf("") }
    var system by remember { mutableStateOf(PavementSystem.PCR) }
    var pavementType by remember { mutableStateOf(PavementType.RIGID) }
    var subgrade by remember { mutableStateOf(SubgradeCategory.A) }
    var airportInput by remember { mutableStateOf("") }

    // Reset on aircraft change
    LaunchedEffect(aircraft.id) {
        weightInput = ""; airportInput = ""
    }

    val hasFormulas = when (system) {
        PavementSystem.PCN -> aircraft.pcn != null
        PavementSystem.PCR -> aircraft.pcr != null
    }
    val hasEswl = aircraft.eswl != null

    // Aircraft rating labels: PCN→ACN, PCR→ACR
    val acrLabel = if (system == PavementSystem.PCN) "ACN" else "ACR"
    val systemLabel = system.label

    // Not available at all
    if (!aircraft.available) {
        if (aircraft.eswlThresholds != null) {
            // Show thresholds card
            Box(modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                .background(colors.surfaceAlt).border(1.dp, colors.border, RoundedCornerShape(8.dp)).padding(16.dp)) {
                Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
                    Text("ESWL Thresholds", fontSize = 13.sp, fontWeight = FontWeight.Bold, color = colors.text)
                    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        Text(aircraft.eswlThresholds.singleWheel.label, fontSize = 13.sp, color = colors.textSecondary)
                        Text("${"%,d".format(aircraft.eswlThresholds.singleWheel.value)} lbs",
                            fontSize = 15.sp, fontWeight = FontWeight.Bold, color = colors.accent)
                    }
                    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        Text(aircraft.eswlThresholds.dualWheel.label, fontSize = 13.sp, color = colors.textSecondary)
                        Text("${"%,d".format(aircraft.eswlThresholds.dualWheel.value)} lbs",
                            fontSize = 15.sp, fontWeight = FontWeight.Bold, color = colors.accent)
                    }
                    Text(aircraft.eswlThresholds.note, fontSize = 11.sp, color = colors.textMuted,
                        fontFamily = FontFamily.Monospace)
                }
            }
            Spacer(Modifier.height(12.dp))
            UnavailableMessage("${aircraft.label} $acrLabel/$acrLabel formulas are not yet available.")
        } else {
            UnavailableMessage("${aircraft.label} pavement data is not yet available.")
        }
        return
    }

    Column(verticalArrangement = Arrangement.spacedBy(18.dp)) {
        ToolkitTextField(value = weightInput, onValueChange = { weightInput = it },
            label = "Aircraft Weight (lbs)", placeholder = "e.g. 73600", keyboardType = KeyboardType.Number)

        // Weight warning
        val weight = weightInput.toDoubleOrNull()
        val warning = if (weight != null) checkWeightLimits(weight, aircraft) else null
        if (warning != null) {
            WarningBanner(warning)
        }

        if (hasFormulas) {
            // System selector + airport input side by side
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                Column(Modifier.weight(1f)) {
                    FieldLabel("System")
                    SegmentedSelector(
                        options = PavementSystem.entries.map { it.label },
                        selected = system.ordinal,
                        onSelect = { system = PavementSystem.entries[it] }
                    )
                }
                Column(Modifier.weight(1f)) {
                    ToolkitTextField(value = airportInput, onValueChange = { airportInput = it },
                        label = "Airport $systemLabel", placeholder = "e.g. 55", keyboardType = KeyboardType.Number)
                }
            }

            FieldLabel("Pavement Type")
            SegmentedSelector(
                options = PavementType.entries.map { it.label },
                selected = pavementType.ordinal,
                onSelect = { pavementType = PavementType.entries[it] }
            )

            FieldLabel("Subgrade Strength")
            SegmentedSelector(
                options = SubgradeCategory.entries.map { it.shortLabel },
                selected = subgrade.ordinal,
                onSelect = { subgrade = SubgradeCategory.entries[it] }
            )
        } else {
            UnavailableMessage("${aircraft.label} $acrLabel formulas are not yet available.\nESWL calculation is available below.")
        }

        ClearButton(onClick = { weightInput = ""; airportInput = "" })

        // Calculate results
        if (weight != null && weight > 0 && (warning == null || !warning.blocksCalculation)) {
            val eswl = if (hasEswl) Calculations.calculateESWL(weight, aircraft.eswl!!) else null
            val hasAcrAcn = hasFormulas

            var acrAcnValue: Int? = null
            var activeFormula: LinearFormula? = null
            if (hasAcrAcn) {
                val formulas = if (system == PavementSystem.PCN) aircraft.pcn!! else aircraft.pcr!!
                val subFormulas = formulas.forType(pavementType)
                val formula = subFormulas.forCategory(subgrade)
                activeFormula = formula
                val raw = Calculations.evaluateFormula(formula, weight)
                acrAcnValue = ceil(raw).toInt()
            }

            val errorNote = if (system == PavementSystem.PCN) aircraft.pcnError else aircraft.pcrError

            ResultCard {
                if (acrAcnValue != null) {
                    ResultRow(
                        label = "$acrLabel (${pavementType.label}, ${subgrade.label})",
                        value = acrAcnValue.toString()
                    )
                }

                if (eswl != null) {
                    if (acrAcnValue != null) ResultDivider()
                    ResultRow(label = "ESWL", value = "%,.0f".format(eswl), unit = "lbs")
                } else if (aircraft.eswlThresholds != null && acrAcnValue != null) {
                    ResultDivider()
                    ResultRow(label = "ESWL Single (${aircraft.eswlThresholds.singleWheel.label})",
                        value = "%,d".format(aircraft.eswlThresholds.singleWheel.value), unit = "lbs")
                    ResultRow(label = "ESWL Dual (${aircraft.eswlThresholds.dualWheel.label})",
                        value = "%,d".format(aircraft.eswlThresholds.dualWheel.value), unit = "lbs")
                }

                // Airport comparison
                val airportVal = airportInput.toDoubleOrNull()
                if (acrAcnValue != null && airportVal != null && airportVal > 0) {
                    Spacer(Modifier.height(12.dp))
                    val ok = acrAcnValue <= airportVal
                    val bg = if (ok) colors.accent.copy(alpha = 0.1f) else colors.dangerBg
                    val border = if (ok) colors.accent.copy(alpha = 0.25f) else colors.dangerBorder
                    val fg = if (ok) colors.accent else colors.danger
                    val icon = if (ok) "✅" else "⛔"
                    val msg = if (ok) {
                        "$icon $acrLabel $acrAcnValue ≤ $systemLabel ${airportVal.toInt()} — Pavement is suitable."
                    } else {
                        val pct = ((acrAcnValue - airportVal) / airportVal * 100).toInt()
                        val f = activeFormula!!
                        val maxWeightRaw = (airportVal - f.intercept) / f.slope
                        val maxWeight = (floor(maxWeightRaw / 500) * 500).toInt()
                        val minBew = aircraft.weightLimits?.minBew ?: 0
                        val weightMsg = if (maxWeight <= minBew) {
                            "Pavement cannot support this aircraft at any operational weight."
                        } else {
                            "Maximum weight for this pavement: %,d lbs.".format(maxWeight)
                        }
                        "$icon $acrLabel $acrAcnValue > $systemLabel ${airportVal.toInt()} — Pavement strength exceeded by $pct%. $weightMsg"
                    }
                    Box(modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(8.dp))
                        .background(bg).border(1.dp, border, RoundedCornerShape(8.dp)).padding(12.dp)) {
                        Text(msg, fontSize = 13.sp, fontWeight = FontWeight.Medium, color = fg, lineHeight = 20.sp)
                    }
                }

                // Footer notes
                Spacer(Modifier.height(12.dp))
                if (eswl != null) {
                    Text("ESWL = ${"%,.0f".format(weight)} × ${aircraft.eswl!!.weightFactor} ÷ ${aircraft.eswl.wheelFactor}",
                        fontSize = 12.sp, color = colors.textMuted, fontFamily = FontFamily.Monospace)
                }
                if (aircraft.eswlThresholds != null && eswl == null) {
                    Text(aircraft.eswlThresholds.note, fontSize = 12.sp, color = colors.textMuted,
                        fontFamily = FontFamily.Monospace)
                }
                if (hasAcrAcn && errorNote != null) {
                    Text("$acrLabel est. error: $errorNote", fontSize = 12.sp, color = colors.textMuted,
                        fontFamily = FontFamily.Monospace)
                }
            }
        }
    }
}
