import { useRef, useState, useEffect } from 'react'
import { createPortal } from 'react-dom'
import { useEngineDesign } from '../hooks/useEngineDesign.js'
import { PropellantModal } from '../components/PropellantModal.jsx'
import {
  exportEngineJSON,
  exportEngineOdt,
  parseEngineImport,
  downloadBlob,
} from '../engine/engineExportImport.js'
import DesignSection from '../components/engine/DesignSection.jsx'
import EngineModel3D from '../components/engine/EngineModel3D.jsx'
import NozzleDiagram from '../components/engine/NozzleDiagram.jsx'
import PerformanceCharts from '../components/engine/PerformanceCharts.jsx'
import ErrorBoundary from '../components/ErrorBoundary.jsx'
import { formatValue } from '../engine/format.js'
import { getUnitsForFamily } from '../engine/units.js'
import { ENGINE_FIELD_INFO } from '../engine/engineFieldInfo.js'
import { ABLATIVE_MATERIALS, STRUCTURAL_MATERIALS } from '../engine/knowledgebaseData.js'

/* ── Info popup ───────────────────────────────────────────────────── */

function InfoPopup({ infoKey, anchorRef, onClose }) {
  const popupRef = useRef(null)
  const info = ENGINE_FIELD_INFO[infoKey]
  const [pos, setPos] = useState({ top: 0, left: 0 })

  useEffect(() => {
    if (anchorRef.current) {
      const r = anchorRef.current.getBoundingClientRect()
      setPos({
        top: r.bottom + 6,
        left: Math.min(r.left, window.innerWidth - 230),
      })
    }
  }, [anchorRef])

  useEffect(() => {
    function onKey(e) { if (e.key === 'Escape') onClose() }
    function onDown(e) {
      if (!popupRef.current?.contains(e.target) && !anchorRef.current?.contains(e.target)) {
        onClose()
      }
    }
    document.addEventListener('keydown', onKey)
    document.addEventListener('mousedown', onDown)
    return () => {
      document.removeEventListener('keydown', onKey)
      document.removeEventListener('mousedown', onDown)
    }
  }, [onClose, anchorRef])

  if (!info) return null

  return createPortal(
    <div
      ref={popupRef}
      style={{ position: 'fixed', top: pos.top, left: pos.left, zIndex: 9999 }}
      className="bg-slate-800 border border-slate-600 rounded-lg p-3 shadow-2xl w-56 text-xs"
    >
      <p className="font-semibold text-slate-100 mb-1">{info.name}</p>
      <p className="text-slate-300 mb-2 leading-relaxed">{info.description}</p>
      {info.higher && <p className="text-emerald-400 mb-0.5">↑ {info.higher}</p>}
      {info.lower  && <p className="text-amber-400">↓ {info.lower}</p>}
    </div>,
    document.body,
  )
}

/* ── Small reusable input components ──────────────────────────────── */

function NumInput({ label, value, onChange, units, step, placeholder, unitFamily, defaultUnitId, infoKey }) {
  const unitList = unitFamily ? getUnitsForFamily(unitFamily) : null
  const [selectedUnitId, setSelectedUnitId] = useState(
    () => defaultUnitId ?? unitList?.[0]?.id ?? null,
  )
  const [popupOpen, setPopupOpen] = useState(false)
  const infoRef = useRef(null)

  const selectedUnit = unitList?.find(u => u.id === selectedUnitId) ?? unitList?.[0] ?? null

  const displayValue = value == null
    ? ''
    : selectedUnit ? selectedUnit.fromSI(value) : value

  function handleChange(str) {
    if (str === '') { onChange(null); return }
    const typed = parseFloat(str)
    if (isNaN(typed)) return
    onChange(selectedUnit ? selectedUnit.toSI(typed) : typed)
  }

  return (
    <div className="flex items-center gap-2">
      <label className="text-xs text-slate-400 w-44 shrink-0">{label}</label>
      <input
        type="number"
        value={displayValue}
        step={step}
        placeholder={placeholder ?? ''}
        onChange={e => handleChange(e.target.value)}
        className="flex-1 min-w-0 w-24 px-2 py-1 bg-slate-800 border border-slate-600 rounded text-sm text-slate-100
                   focus:border-blue-500 focus:outline-none placeholder-slate-600"
      />
      {unitList && unitList.length > 1 ? (
        <select
          value={selectedUnit?.id ?? ''}
          onChange={e => setSelectedUnitId(e.target.value)}
          className="px-1 py-0.5 bg-slate-700 border border-slate-600 rounded text-xs text-slate-300
                     focus:outline-none cursor-pointer shrink-0"
        >
          {unitList.map(u => <option key={u.id} value={u.id}>{u.label}</option>)}
        </select>
      ) : unitList?.[0] ? (
        <span className="text-xs text-slate-500 shrink-0">{unitList[0].label}</span>
      ) : units ? (
        <span className="text-xs text-slate-500 shrink-0 whitespace-nowrap">{units}</span>
      ) : null}
      {infoKey && (
        <>
          <button
            ref={infoRef}
            onClick={() => setPopupOpen(v => !v)}
            className="text-slate-500 hover:text-slate-300 text-xs shrink-0 leading-none"
            title="Info"
          >ⓘ</button>
          {popupOpen && (
            <InfoPopup infoKey={infoKey} anchorRef={infoRef} onClose={() => setPopupOpen(false)} />
          )}
        </>
      )}
    </div>
  )
}

function SelectInput({ label, value, onChange, options, infoKey }) {
  const [popupOpen, setPopupOpen] = useState(false)
  const infoRef = useRef(null)

  return (
    <div className="flex items-center gap-2">
      <label className="text-xs text-slate-400 w-44 shrink-0">{label}</label>
      <select
        value={value}
        onChange={e => onChange(e.target.value)}
        className="px-2 py-1 bg-slate-800 border border-slate-600 rounded text-sm text-slate-100
                   focus:border-blue-500 focus:outline-none"
      >
        {options.map(o => (
          <option key={o.value} value={o.value}>{o.label}</option>
        ))}
      </select>
      {infoKey && (
        <>
          <button
            ref={infoRef}
            onClick={() => setPopupOpen(v => !v)}
            className="text-slate-500 hover:text-slate-300 text-xs shrink-0 leading-none"
            title="Info"
          >ⓘ</button>
          {popupOpen && (
            <InfoPopup infoKey={infoKey} anchorRef={infoRef} onClose={() => setPopupOpen(false)} />
          )}
        </>
      )}
    </div>
  )
}

/* ── Result display helpers ───────────────────────────────────────── */

function ResultRow({ label, value, unit, unitFamily, defaultUnitId, infoKey }) {
  const unitList = unitFamily ? getUnitsForFamily(unitFamily) : null
  const [selectedUnitId, setSelectedUnitId] = useState(
    () => defaultUnitId ?? unitList?.[0]?.id ?? null,
  )
  const [popupOpen, setPopupOpen] = useState(false)
  const infoRef = useRef(null)

  const selectedUnit = unitList?.find(u => u.id === selectedUnitId) ?? unitList?.[0] ?? null

  const rawDisplay = value !== null && value !== undefined && isFinite(value)
    ? (selectedUnit ? selectedUnit.fromSI(value) : value)
    : null
  const display = rawDisplay !== null ? formatValue(rawDisplay) : '—'
  const unitLabel = selectedUnit?.label ?? unit

  return (
    <div className="flex items-center gap-2 text-sm">
      <span className="text-slate-400 w-48 shrink-0">{label}</span>
      <span className={`font-mono ${display === '—' ? 'text-slate-600' : 'text-green-400'}`}>
        {display}
      </span>
      {unitList && unitList.length > 1 ? (
        <select
          value={selectedUnit?.id ?? ''}
          onChange={e => setSelectedUnitId(e.target.value)}
          className="px-1 py-0 bg-slate-700 border border-slate-600 rounded text-xs text-slate-400
                     focus:outline-none cursor-pointer"
        >
          {unitList.map(u => <option key={u.id} value={u.id}>{u.label}</option>)}
        </select>
      ) : (
        unitLabel && <span className="text-slate-500 text-xs">{unitLabel}</span>
      )}
      {infoKey && (
        <>
          <button
            ref={infoRef}
            onClick={() => setPopupOpen(v => !v)}
            className="text-slate-500 hover:text-slate-300 text-xs leading-none shrink-0"
            title="Info"
          >ⓘ</button>
          {popupOpen && (
            <InfoPopup infoKey={infoKey} anchorRef={infoRef} onClose={() => setPopupOpen(false)} />
          )}
        </>
      )}
    </div>
  )
}

function ResultSection({ title, children }) {
  return (
    <div className="mb-5">
      <h3 className="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2 pb-1 border-b border-slate-800">
        {title}
      </h3>
      <div className="space-y-1">{children}</div>
    </div>
  )
}

/* ── Main page ────────────────────────────────────────────────────── */

export default function EnginePage() {
  const importRef = useRef(null)
  const [showPropellants, setShowPropellants] = useState(false)
  const [showNozzleModal, setShowNozzleModal] = useState(false)
  const [showChartsModal, setShowChartsModal] = useState(false)
  const {
    thermoInputs, setThermoInput,
    chamber, setChamber,
    nozzle, setNozzle,
    injector, setInjector,
    cooling, setCooling,
    feedSystem, setFeedSystem,
    burnTime, setBurnTime,
    structure, setStructure,
    allThermo,
    chamberGeometry: cg,
    nozzleGeometry: ng,
    injectorGeometry: ig,
    coolingResults: cr,
    feedResults: fr,
    structureResults: sr,
    loadDesign,
    applyPropellant,
  } = useEngineDesign()

  function handleExportJSON() {
    const blob = exportEngineJSON({
      thermoInputs, chamber, nozzle, injector, cooling, feedSystem, burnTime, structure,
      allThermo, chamberGeometry: cg, nozzleGeometry: ng,
      injectorGeometry: ig, coolingResults: cr, feedResults: fr, structureResults: sr,
    })
    downloadBlob(blob, 'engine-design.json')
  }

  async function handleExportODT() {
    const blob = await exportEngineOdt({
      allThermo, chamberGeometry: cg, nozzleGeometry: ng,
      injectorGeometry: ig, coolingResults: cr, feedResults: fr,
    })
    downloadBlob(blob, 'engine-design.odt')
  }

  function handleImport(e) {
    const file = e.target.files[0]
    if (!file) return
    const reader = new FileReader()
    reader.onload = ev => {
      try {
        const inputs = parseEngineImport(ev.target.result)
        loadDesign(inputs)
      } catch (err) {
        alert('Import failed: ' + err.message)
      }
    }
    reader.readAsText(file)
    e.target.value = ''
  }

  return (
    <div className="flex flex-col flex-1 overflow-hidden">
      {/* Sub-header */}
      <div className="flex items-center justify-between px-5 py-2 bg-slate-900 border-b border-slate-700 shrink-0">
        <h1 className="text-sm font-semibold text-slate-200">Engine Design</h1>
        <div className="flex gap-2">
          <button
            onClick={handleExportJSON}
            className="px-3 py-1 text-xs bg-slate-700 hover:bg-slate-600 rounded text-slate-200 transition-colors"
          >
            ↓ JSON
          </button>
          <button
            onClick={handleExportODT}
            className="px-3 py-1 text-xs bg-slate-700 hover:bg-slate-600 rounded text-slate-200 transition-colors"
          >
            ↓ ODT
          </button>
          <button
            onClick={() => importRef.current?.click()}
            className="px-3 py-1 text-xs bg-slate-700 hover:bg-slate-600 rounded text-slate-200 transition-colors"
          >
            ↑ Import
          </button>
          <input
            ref={importRef}
            type="file"
            accept=".json"
            className="hidden"
            onChange={handleImport}
          />
        </div>
      </div>

      {/* Three-column layout */}
      <div className="flex flex-1 overflow-hidden">
        {/* ── Left: Inputs ── */}
        <div className="w-[420px] shrink-0 overflow-y-auto p-4 border-r border-slate-700">

          <DesignSection
            title="Thermodynamic Inputs"
            headerAction={
              <button
                onClick={() => setShowPropellants(true)}
                className="px-2 py-1 text-xs bg-blue-700 hover:bg-blue-600 text-white rounded transition-colors whitespace-nowrap"
              >
                ⛽ Load Propellant
              </button>
            }
          >
            <NumInput
              label="Chamber Pressure (p₀)"
              value={thermoInputs.p0}
              onChange={v => setThermoInput('p0', v)}
              unitFamily="pressure"
              defaultUnitId="MPa"
              infoKey="p0"
              placeholder="3"
            />
            <NumInput
              label="Chamber Temp (T₀)"
              value={thermoInputs.T0}
              onChange={v => setThermoInput('T0', v)}
              unitFamily="temperature"
              defaultUnitId="K"
              infoKey="T0"
              placeholder="3500"
            />
            <NumInput
              label="Ratio of Specific Heats (γ)"
              value={thermoInputs.gamma}
              onChange={v => setThermoInput('gamma', v)}
              infoKey="gamma"
              placeholder="1.2"
              step="0.01"
            />
            <NumInput
              label="Specific Gas Constant (R)"
              value={thermoInputs.R}
              onChange={v => setThermoInput('R', v)}
              units="J/(kg·K)"
              infoKey="R_gas"
              placeholder="360"
            />
            <NumInput
              label="Mass Flow Rate (ṁ)"
              value={thermoInputs.mdot}
              onChange={v => setThermoInput('mdot', v)}
              unitFamily="massflow"
              defaultUnitId="kg/s"
              infoKey="mdot"
              placeholder="5"
            />
            <NumInput
              label="Thrust (F)"
              value={thermoInputs.F}
              onChange={v => setThermoInput('F', v)}
              unitFamily="force"
              defaultUnitId="kN"
              infoKey="F_input"
              placeholder="or enter ṁ"
            />
            <NumInput
              label="O/F Ratio"
              value={thermoInputs.OF}
              onChange={v => setThermoInput('OF', v)}
              infoKey="OF"
              placeholder="2.2"
              step="0.1"
            />
            <NumInput
              label="Throat Area (Aₜ)"
              value={thermoInputs.At}
              onChange={v => setThermoInput('At', v)}
              unitFamily="area"
              defaultUnitId="cm²"
              infoKey="At_input"
              placeholder="auto-solved"
            />
            <NumInput
              label="Expansion Ratio (ε)"
              value={thermoInputs.eps}
              onChange={v => setThermoInput('eps', v)}
              infoKey="eps_input"
              placeholder="auto-solved"
              step="0.5"
            />
            <NumInput
              label="Ambient Pressure (pₐ)"
              value={thermoInputs.pa}
              onChange={v => setThermoInput('pa', v)}
              unitFamily="pressure"
              defaultUnitId="kPa"
              infoKey="pa"
              placeholder="101.325"
            />
          </DesignSection>

          <DesignSection title="Combustion Chamber">
            <NumInput
              label="Characteristic Length (L*)"
              value={chamber.Lstar}
              onChange={v => setChamber(c => ({ ...c, Lstar: v }))}
              unitFamily="length"
              defaultUnitId="m"
              infoKey="Lstar"
              step="0.05"
            />
            <NumInput
              label="Contraction Ratio"
              value={chamber.contractionRatio}
              onChange={v => setChamber(c => ({ ...c, contractionRatio: v }))}
              infoKey="contractionRatio"
              step="0.5"
            />
            <NumInput
              label="Convergent Half-Angle"
              value={chamber.convAngleDeg}
              onChange={v => setChamber(c => ({ ...c, convAngleDeg: v }))}
              units="°"
              infoKey="convAngleDeg"
              step="1"
            />
          </DesignSection>

          <DesignSection title="Nozzle">
            <SelectInput
              label="Nozzle Type"
              value={nozzle.type}
              onChange={v => setNozzle(n => ({ ...n, type: v }))}
              options={[
                { value: 'conical', label: 'Conical' },
                { value: 'bell',    label: 'Bell (80% length)' },
              ]}
              infoKey="nozzleType"
            />
            {nozzle.type === 'conical' && (
              <NumInput
                label="Divergence Half-Angle"
                value={nozzle.divAngleDeg}
                onChange={v => setNozzle(n => ({ ...n, divAngleDeg: v }))}
                units="°"
                infoKey="divAngleDeg"
                step="1"
              />
            )}
          </DesignSection>

          <DesignSection title="Injector">
            <SelectInput
              label="Injector Type"
              value={injector.type}
              onChange={v => setInjector(i => ({ ...i, type: v }))}
              options={[
                { value: 'doublet', label: 'Impinging Doublet' },
                { value: 'triplet', label: 'Impinging Triplet' },
                { value: 'coaxial', label: 'Coaxial' },
                { value: 'pintle',  label: 'Pintle' },
              ]}
              infoKey="injectorType"
            />
            <NumInput
              label="Number of Elements (N)"
              value={injector.N}
              onChange={v => setInjector(i => ({ ...i, N: Math.max(1, Math.round(v)) }))}
              infoKey="injectorN"
              step="1"
            />
            <NumInput
              label="ΔP/p₀ Fraction"
              value={injector.dpFraction}
              onChange={v => setInjector(i => ({ ...i, dpFraction: v }))}
              infoKey="dpFraction"
              step="0.01"
            />
            <NumInput
              label="Discharge Coefficient (Cd)"
              value={injector.Cd}
              onChange={v => setInjector(i => ({ ...i, Cd: v }))}
              infoKey="Cd"
              step="0.01"
            />
            <NumInput
              label="Fuel Density (ρ_f)"
              value={injector.rhoFuel}
              onChange={v => setInjector(i => ({ ...i, rhoFuel: v }))}
              unitFamily="density"
              defaultUnitId="kg/m³"
              infoKey="rhoFuel_inj"
            />
            <NumInput
              label="Oxidiser Density (ρ_ox)"
              value={injector.rhoOx}
              onChange={v => setInjector(i => ({ ...i, rhoOx: v }))}
              unitFamily="density"
              defaultUnitId="kg/m³"
              infoKey="rhoOx_inj"
            />
          </DesignSection>

          <DesignSection title="Cooling">
            <SelectInput
              label="Cooling Method"
              value={cooling.method}
              onChange={v => setCooling(c => ({ ...c, method: v }))}
              options={[
                { value: 'regenerative', label: 'Regenerative' },
                { value: 'film',         label: 'Film Cooling' },
                { value: 'ablative',     label: 'Ablative' },
                { value: 'uncooled',     label: 'Uncooled' },
              ]}
              infoKey="coolingMethod"
            />
            {cooling.method === 'regenerative' && (
              <>
                <NumInput
                  label="Channel Count"
                  value={cooling.channelCount}
                  onChange={v => setCooling(c => ({ ...c, channelCount: Math.max(1, Math.round(v)) }))}
                  infoKey="channelCount"
                  step="1"
                />
                <NumInput
                  label="Dynamic Viscosity (μ)"
                  value={cooling.mu}
                  onChange={v => setCooling(c => ({ ...c, mu: v }))}
                  units="Pa·s"
                  step="1e-5"
                  placeholder="6e-5"
                />
                <NumInput
                  label="Specific Heat (cₚ)"
                  value={cooling.cp}
                  onChange={v => setCooling(c => ({ ...c, cp: v }))}
                  units="J/(kg·K)"
                  step="100"
                  placeholder="2000"
                />
                <NumInput
                  label="Prandtl Number (Pr)"
                  value={cooling.Pr}
                  onChange={v => setCooling(c => ({ ...c, Pr: v }))}
                  units="—"
                  step="0.05"
                  placeholder="0.7"
                />
                <NumInput
                  label="Wall Temperature (T_wall)"
                  value={cooling.T_wall}
                  onChange={v => setCooling(c => ({ ...c, T_wall: v }))}
                  unitFamily="temperature"
                  defaultUnitId="K"
                  step="50"
                  placeholder="800"
                />
              </>
            )}
            {cooling.method === 'film' && (
              <NumInput
                label="Film Mass Fraction"
                value={cooling.filmFraction}
                onChange={v => setCooling(c => ({ ...c, filmFraction: v }))}
                infoKey="filmFraction"
                step="0.01"
              />
            )}
            {cooling.method === 'ablative' && (
              <>
                <SelectInput
                  label="Liner Material"
                  value={cooling.ablativeMaterial}
                  onChange={v => setCooling(c => ({ ...c, ablativeMaterial: v }))}
                  options={ABLATIVE_MATERIALS.map(m => ({ value: m.id, label: m.name }))}
                />
                <NumInput
                  label="Initial Thickness"
                  value={cooling.ablativeThickness}
                  onChange={v => setCooling(c => ({ ...c, ablativeThickness: v }))}
                  units="mm"
                  step="1"
                  placeholder="10"
                />
              </>
            )}
          </DesignSection>

          <DesignSection title="Feed System">
            <SelectInput
              label="Feed System"
              value={feedSystem.type}
              onChange={v => setFeedSystem(f => ({ ...f, type: v }))}
              options={[
                { value: 'pressure_fed', label: 'Pressure-Fed' },
                { value: 'pump_fed',     label: 'Pump-Fed' },
              ]}
              infoKey="feedType"
            />
            {feedSystem.type === 'pressure_fed' && (
              <NumInput
                label="Feed Pressure Factor"
                value={feedSystem.feedFactor}
                onChange={v => setFeedSystem(f => ({ ...f, feedFactor: v }))}
                infoKey="feedFactor"
                step="0.05"
              />
            )}
            <NumInput
              label="Fuel Density (ρ_f)"
              value={feedSystem.rhoFuel}
              onChange={v => setFeedSystem(f => ({ ...f, rhoFuel: v }))}
              unitFamily="density"
              defaultUnitId="kg/m³"
              infoKey="rhoFuel_feed"
            />
            <NumInput
              label="Oxidiser Density (ρ_ox)"
              value={feedSystem.rhoOx}
              onChange={v => setFeedSystem(f => ({ ...f, rhoOx: v }))}
              unitFamily="density"
              defaultUnitId="kg/m³"
              infoKey="rhoOx_feed"
            />
            <NumInput
              label="Burn Time"
              value={burnTime}
              onChange={v => setBurnTime(v ?? 30)}
              unitFamily="time"
              defaultUnitId="s"
              infoKey="burnTime"
              step="1"
            />
          </DesignSection>

          <DesignSection title="Structural">
            <SelectInput
              label="Material"
              value={structure.materialId}
              onChange={v => setStructure(s => ({ ...s, materialId: v }))}
              options={STRUCTURAL_MATERIALS.map(m => ({ value: m.id, label: m.name }))}
              infoKey="structuralMaterial"
            />
            <NumInput
              label="Safety Factor"
              value={structure.safetyFactor}
              onChange={v => setStructure(s => ({ ...s, safetyFactor: v }))}
              infoKey="safetyFactor"
              step="0.1"
              placeholder="2.0"
            />
          </DesignSection>
        </div>

        {/* ── Centre: 3D Model + Visualization Buttons ── */}
        <div className="flex-1 border-r border-slate-700 bg-slate-950/50 flex flex-col overflow-hidden">
          {/* 3D Model */}
          <div className="flex-1 relative flex flex-col">
            <ErrorBoundary>
              <EngineModel3D chamberGeometry={cg} nozzleGeometry={ng} />
            </ErrorBoundary>

            {/* Quick access buttons overlay */}
            <div className="absolute bottom-4 left-4 right-4 flex gap-2 pointer-events-auto">
              {cg && ng && (
                <button
                  onClick={() => setShowNozzleModal(true)}
                  className="px-3 py-2 text-xs bg-blue-700 hover:bg-blue-600 text-white rounded transition-colors whitespace-nowrap"
                >
                  📐 Nozzle Cross-Section
                </button>
              )}
              {allThermo?.gamma && allThermo?.R && allThermo?.T0 && allThermo?.p0 && (
                <button
                  onClick={() => setShowChartsModal(true)}
                  className="px-3 py-2 text-xs bg-indigo-700 hover:bg-indigo-600 text-white rounded transition-colors whitespace-nowrap"
                >
                  📊 Performance Charts
                </button>
              )}
            </div>
          </div>
        </div>

        {/* ── Right: Results ── */}
        <div className="w-[380px] shrink-0 overflow-y-auto p-4">

          <ResultSection title="Thermodynamic Performance">
            <ResultRow label="Throat Area (Aₜ)"       value={allThermo.At}      unitFamily="area"        defaultUnitId="cm²"  infoKey="At_result"      />
            <ResultRow label="Exit Area (Aₑ)"          value={allThermo.Ae}      unitFamily="area"        defaultUnitId="cm²"  infoKey="Ae_result"      />
            <ResultRow label="Expansion Ratio (ε)"     value={allThermo.eps}     unit="—"                                      infoKey="eps_result"     />
            <ResultRow label="Exit Mach (Mₑ)"          value={allThermo.Me}      unit="—"                                      infoKey="Me_result"      />
            <ResultRow label="Exit Temp (Tₑ)"          value={allThermo.Te}      unitFamily="temperature" defaultUnitId="K"    infoKey="Te_result"      />
            <ResultRow label="Exit Pressure (pₑ)"      value={allThermo.pe}      unitFamily="pressure"    defaultUnitId="kPa"  infoKey="pe_result"      />
            <ResultRow label="Exhaust Velocity (Vₑ)"   value={allThermo.Ve}      unitFamily="velocity"    defaultUnitId="m/s"  infoKey="Ve_result"      />
            <ResultRow label="Thrust (F)"               value={allThermo.F}       unitFamily="force"       defaultUnitId="kN"   infoKey="F_result"       />
            <ResultRow label="Specific Impulse (Isp)"  value={allThermo.Isp}     unit="s"                                      infoKey="Isp_result"     />
            <ResultRow label="c*"                       value={allThermo.cstar}   unitFamily="velocity"    defaultUnitId="m/s"  infoKey="cstar_result"   />
            <ResultRow label="Thrust Coefficient (CF)" value={allThermo.CF}      unit="—"                                      infoKey="CF_result"      />
            <ResultRow label="Fuel Flow (ṁ_f)"         value={allThermo.mdot_f}  unitFamily="massflow"    defaultUnitId="kg/s" infoKey="mdot_f_result"  />
            <ResultRow label="Ox Flow (ṁ_ox)"          value={allThermo.mdot_ox} unitFamily="massflow"    defaultUnitId="kg/s" infoKey="mdot_ox_result" />
          </ResultSection>

          <ResultSection title="Chamber Geometry">
            <ResultRow label="Chamber Diameter (Dc)"   value={cg?.Dc}               unitFamily="length" defaultUnitId="mm" infoKey="Dc_result"               />
            <ResultRow label="Throat Diameter (Dt)"    value={cg?.Dt}               unitFamily="length" defaultUnitId="mm" infoKey="Dt_result"               />
            <ResultRow label="Contraction Ratio"       value={cg?.contractionRatio} unit="—"                               infoKey="contractionRatio_result" />
            <ResultRow label="Total Length (Lc)"       value={cg?.Lc}               unitFamily="length" defaultUnitId="mm" infoKey="Lc_result"               />
            <ResultRow label="Cylindrical Length"      value={cg?.L_cyl}            unitFamily="length" defaultUnitId="mm" infoKey="L_cyl_result"            />
            <ResultRow label="Convergent Length"       value={cg?.L_conv}           unitFamily="length" defaultUnitId="mm" infoKey="L_conv_result"           />
            <ResultRow label="Chamber Volume"          value={cg?.Vc}               unitFamily="volume" defaultUnitId="cm³" infoKey="Vc_result"              />
          </ResultSection>

          <ResultSection title="Nozzle Geometry">
            <ResultRow label="Throat Diameter (Dt)"   value={ng?.Dt} unitFamily="length" defaultUnitId="mm" infoKey="Dt_result"  />
            <ResultRow label="Exit Diameter (De)"      value={ng?.De} unitFamily="length" defaultUnitId="mm" infoKey="De_result"  />
            <ResultRow label="Nozzle Length (Ln)"      value={ng?.Ln} unitFamily="length" defaultUnitId="mm" infoKey="Ln_result"  />
          </ResultSection>

          <ResultSection title="Injector">
            <ResultRow label="Pressure Drop (ΔP)"       value={ig?.deltaP} unitFamily="pressure" defaultUnitId="kPa"  infoKey="deltaP_result" />
            <ResultRow label="Fuel Jet Velocity"         value={ig?.v_f}    unitFamily="velocity" defaultUnitId="m/s"  infoKey="v_f_result"    />
            <ResultRow label="Oxidiser Jet Velocity"     value={ig?.v_ox}   unitFamily="velocity" defaultUnitId="m/s"  infoKey="v_ox_result"   />
            <ResultRow label="Fuel Orifice Diameter"     value={ig?.d_f}    unitFamily="length"   defaultUnitId="mm"   infoKey="d_f_result"    />
            <ResultRow label="Oxidiser Orifice Diameter" value={ig?.d_ox}   unitFamily="length"   defaultUnitId="mm"   infoKey="d_ox_result"   />
          </ResultSection>

          <ResultSection title="Cooling">
            {cr ? (
              <>
                {cr.method === 'regenerative' && (
                  <>
                    <ResultRow label="Est. Heat Flux"      value={cr.q_est}        unit="W/m²" infoKey="q_est_result"        />
                    <ResultRow label="Total Heat Load"     value={cr.q_total}      unit="W"    infoKey="q_total_result"      />
                    <ResultRow label="Channel Count"       value={cr.channelCount} unit="—"    infoKey="channelCount_result" />
                    <ResultRow label="Heat load / channel" value={cr.q_perChannel}  unit="W" infoKey="q_perChannel_result" />
                  </>
                )}
                {cr.method === 'film' && (
                  <>
                    <ResultRow label="Film Mass Flow"   value={cr.mdot_film}  unitFamily="massflow" defaultUnitId="g/s" infoKey="mdot_film_result"  />
                    <ResultRow label="Est. Isp Penalty" value={cr.ispPenalty} unit="%"                                  infoKey="ispPenalty_result" />
                  </>
                )}
                {cr.method === 'ablative' && cr.material && (
                  <>
                    <div className="text-sm mb-2">
                      <span className="text-slate-400">Material: </span>
                      <span className="text-slate-100 font-semibold">{cr.material.name}</span>
                    </div>
                    {cr.pressureFactor && Math.abs(cr.pressureFactor - 1.0) > 0.01 && (
                      <ResultRow label="Pressure Correction" value={cr.pressureFactor} unit="×" />
                    )}
                    <ResultRow label="Erosion Rate"      value={cr.effectiveRate} unit="mm/s" />
                    <ResultRow label="Initial Thickness" value={cr.ablativeThickness}     unit="mm" />
                    <div className="flex items-center gap-2 text-sm py-1.5">
                      <span className="text-slate-400 w-48 shrink-0">Eroded</span>
                      <span className="font-mono text-green-400">
                        {formatValue(cr.erosionMm)} mm
                      </span>
                      <span className="text-xs text-slate-500">
                        ({formatValue(cr.erosionMmMin)}–{formatValue(cr.erosionMmMax)} mm)
                      </span>
                    </div>
                    <div className="flex items-center gap-2 text-sm py-1.5">
                      <span className="text-slate-400 w-48 shrink-0">Remaining Thickness</span>
                      <span className={`font-mono font-semibold ${
                        cr.status === 'critical' ? 'text-red-400' :
                        cr.status === 'warning' ? 'text-amber-400' :
                        'text-green-400'
                      }`}>
                        {formatValue(cr.remainingMm)} mm
                      </span>
                      <span className="text-xs text-slate-500">
                        (worst: {formatValue(cr.remainingMmWorst)} mm)
                      </span>
                    </div>
                    {(cr.status === 'warning' || cr.status === 'critical') && (
                      <div className={`text-xs px-3 py-2 rounded mt-2 ${
                        cr.status === 'critical'
                          ? 'bg-red-900/30 border border-red-700 text-red-200'
                          : 'bg-amber-900/30 border border-amber-700 text-amber-200'
                      }`}>
                        {cr.status === 'critical'
                          ? '🚨 CRITICAL: Liner thickness below safe minimum!'
                          : '⚠️ WARNING: Liner thickness approaching minimum!'}
                      </div>
                    )}
                  </>
                )}
                {cr.note && (
                  <p className="text-xs text-slate-400 italic mt-1">{cr.note}</p>
                )}
              </>
            ) : (
              <p className="text-xs text-slate-600">—</p>
            )}
          </ResultSection>

          <ResultSection title="Feed System">
            {fr ? (
              <>
                <ResultRow label="Tank Pressure"            value={fr.p_tank}  unitFamily="pressure" defaultUnitId="MPa" infoKey="p_tank_result"   />
                <ResultRow label="Fuel Volume"               value={fr.V_fuel}  unitFamily="volume"   defaultUnitId="L"   infoKey="V_fuel_result"   />
                <ResultRow label="Oxidiser Volume"           value={fr.V_ox}    unitFamily="volume"   defaultUnitId="L"   infoKey="V_ox_result"     />
                <ResultRow label="Total Propellant Volume"   value={fr.V_prop}  unitFamily="volume"   defaultUnitId="L"   infoKey="V_prop_result"   />
                {fr.m_press   != null && <ResultRow label="Pressurant Mass"    value={fr.m_press}           unitFamily="mass"     defaultUnitId="kg"  infoKey="m_press_result"   />}
                {fr.dP_pump   != null && <ResultRow label="Pump ΔP"            value={fr.dP_pump}           unitFamily="pressure" defaultUnitId="MPa" infoKey="dP_pump_result"   />}
                {fr.P_turbine != null && <ResultRow label="Est. Turbine Power" value={fr.P_turbine / 1000} unit="kW"                                  infoKey="P_turbine_result" />}
              </>
            ) : (
              <p className="text-xs text-slate-600">—</p>
            )}
          </ResultSection>

          <ResultSection title="Structural Sizing">
            {sr ? (
              <>
                <div className="text-sm mb-2">
                  <span className="text-slate-400">Material: </span>
                  <span className="text-slate-100 font-semibold">{sr.material.name}</span>
                </div>
                <ResultRow label="Safety Factor" value={sr.safetyFactor} unit="—" />
                <ResultRow label="Allowable Stress" value={sr.allowableStress / 1e6} unit="MPa" />
                <div className="border-t border-slate-700 my-2 pt-2">
                  <ResultRow label="Chamber Wall Thickness" value={sr.t_chamber * 1000} unit="mm" />
                  <ResultRow label="Throat Wall Thickness" value={sr.t_throat * 1000} unit="mm" />
                  <ResultRow label="Nozzle Exit Wall Thickness" value={sr.t_nozzle_exit * 1000} unit="mm" />
                </div>
                <div className="border-t border-slate-700 my-2 pt-2">
                  <ResultRow label="Chamber Mass" value={sr.m_chamber_cyl + sr.m_convergent} unitFamily="mass" defaultUnitId="kg" />
                  <ResultRow label="Nozzle Mass" value={sr.m_nozzle} unitFamily="mass" defaultUnitId="kg" />
                  <ResultRow label="Injector Plate Mass" value={sr.m_injector} unitFamily="mass" defaultUnitId="kg" />
                </div>
                <div className="border-t border-slate-700 mt-2 pt-2">
                  <div className="flex items-center gap-2 text-sm bg-blue-900/30 border border-blue-700 rounded px-3 py-2">
                    <span className="text-slate-400">Engine Dry Mass</span>
                    <span className="font-mono font-semibold text-blue-300">
                      {formatValue(sr.m_total)} kg
                    </span>
                  </div>
                </div>
              </>
            ) : (
              <p className="text-xs text-slate-600">—</p>
            )}
          </ResultSection>
        </div>
      </div>

      {showPropellants && (
        <PropellantModal
          onClose={() => setShowPropellants(false)}
          onApply={applyPropellant}
          description="Select a propellant to pre-fill γ, R, T₀, O/F, and densities."
        />
      )}

      {/* Nozzle Diagram Modal */}
      {showNozzleModal && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
          <div className="bg-slate-900 rounded-lg shadow-2xl border border-slate-700 w-full max-w-4xl max-h-[90vh] flex flex-col">
            <div className="flex items-center justify-between p-4 border-b border-slate-700 shrink-0">
              <h2 className="text-lg font-semibold text-slate-100">Nozzle Cross-Section</h2>
              <button
                onClick={() => setShowNozzleModal(false)}
                className="text-slate-400 hover:text-slate-200 text-xl"
              >
                ✕
              </button>
            </div>
            <div className="flex-1 overflow-auto p-6 bg-slate-800">
              <ErrorBoundary>
                <NozzleDiagram chamberGeometry={cg} nozzleGeometry={ng} nozzleType={nozzle.type} />
              </ErrorBoundary>
            </div>
          </div>
        </div>
      )}

      {/* Performance Charts Modal */}
      {showChartsModal && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
          <div className="bg-slate-900 rounded-lg shadow-2xl border border-slate-700 w-full max-w-5xl max-h-[90vh] flex flex-col">
            <div className="flex items-center justify-between p-4 border-b border-slate-700 shrink-0">
              <h2 className="text-lg font-semibold text-slate-100">Performance Analysis</h2>
              <button
                onClick={() => setShowChartsModal(false)}
                className="text-slate-400 hover:text-slate-200 text-xl"
              >
                ✕
              </button>
            </div>
            <div className="flex-1 overflow-auto p-6 bg-slate-800">
              <ErrorBoundary>
                <PerformanceCharts
                  allThermo={allThermo}
                  coolingResults={cr}
                  burnTime={burnTime}
                  nozzleType={nozzle.type}
                />
              </ErrorBoundary>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}
