import React, { useState } from 'react';
import { num } from '../api/useXplane.js';
import MapView from './MapView.jsx';
import Nearest from './Nearest.jsx';
import FplPage from './FplPage.jsx';

const arr = (v, i = 0, d = 0) => (Array.isArray(v) ? num(v[i], d) : num(v, d));
const KG_PER_GAL = 2.72; // avgas
const navF = (v) => (num(v) / 100).toFixed(2);
const comF = (v) => (num(v) / 100).toFixed(3);

// Active flight-plan leg: distance / desired track / ETE to the active waypoint
// (great-circle from the aircraft), for the MFD nav data bar. Mirrors the PFD's
// activeNav so the two displays agree.
const R_NM = 3440.065, D2R = Math.PI / 180, R2D = 180 / Math.PI;
function legNav(V, fp) {
  const wps = fp?.waypoints || [];
  const ai = Math.max(1, Math.min(wps.length - 1, fp?.activeLeg ?? 1));
  const wp = wps[ai];
  const lat = num(V.lat), lon = num(V.lon);
  if (!wp || (!lat && !lon)) return null;
  const dLat = (wp.lat - lat) * D2R, dLon = (wp.lon - lon) * D2R;
  const a = Math.sin(dLat / 2) ** 2 + Math.cos(lat * D2R) * Math.cos(wp.lat * D2R) * Math.sin(dLon / 2) ** 2;
  const dist = 2 * R_NM * Math.asin(Math.min(1, Math.sqrt(a)));
  const y = Math.sin(dLon) * Math.cos(wp.lat * D2R);
  const x = Math.cos(lat * D2R) * Math.sin(wp.lat * D2R) - Math.sin(lat * D2R) * Math.cos(wp.lat * D2R) * Math.cos(dLon);
  const dtk = (Math.atan2(y, x) * R2D + 360) % 360;
  const gs = num(V.groundspeed) * 1.94384;
  return { id: wp.id, dist, dtk, ete: gs > 20 ? (dist / gs) * 3600 : null };
}
const fmtEte = (s) => {
  if (s == null) return '__:__';
  const m = Math.floor(s / 60), ss = Math.round(s % 60);
  return m < 60 ? `${m}:${String(ss).padStart(2, '0')}` : `${Math.floor(m / 60)}+${String(m % 60).padStart(2, '0')}`;
};

// G1000 MFD — full-width NAV/COM bar on top, the engine instrument strip (EIS)
// down the left as real bar gauges, and the moving map (X-Plane nav data) with
// G1000 chrome (compass rose, range, NORTH UP, mode) filling the rest.
const MFD_PAGES = [{ id: 'map', name: 'MAP' }, { id: 'fpl', name: 'FPL' }, { id: 'nrst', name: 'NRST' }];
export default function MFD({ values: V, flightPlan, fp, mapMode, page = 'map', onCycle, xp, vnav, onVnav }) {
  const [rangeNm, setRangeNm] = useState(8);
  const idx = Math.max(0, MFD_PAGES.findIndex((p) => p.id === page));
  return (
    <div className="mfd-g1000">
      <MfdTopBar V={V} fp={flightPlan} />
      <div className="mfd-body">
        <EisStrip V={V} />
        <div className="mfd-map">
          {/* MapView stays mounted (keeps tiles warm) but is hidden under NRST */}
          <div style={{ position: 'absolute', inset: 0, visibility: page === 'map' ? 'visible' : 'hidden' }}>
            <MapView values={V} flightPlan={flightPlan} fp={fp} hud={false}
              mapMode={mapMode} dcltr={mapMode?.dcltr || 0} rangeNm={num(V.uiMapRange) || undefined}
              terrain={xp?.terrain} rose onView={({ rangeNm }) => setRangeNm(rangeNm)} />
            <MapChrome V={V} rangeNm={rangeNm} />
          </div>
          {page === 'map' && mapMode?.profile && <VertProfile V={V} fp={flightPlan} />}
          {page === 'nrst' && <Nearest xp={xp} full />}
          {page === 'fpl' && xp && <FplPage xp={xp} full vnav={vnav} onVnav={onVnav} />}
          {/* page-group indicator (bottom-right), like the real G1000 — selected
              by the FMS knob; tappable as a touch fallback. */}
          <button className="mfd-pageind" onClick={() => onCycle && onCycle(1)} title="Seite (FMS-Knopf)">
            <span>{MFD_PAGES[idx].name}</span>
            {MFD_PAGES.map((p, i) => <em key={p.id} className={i === idx ? 'on' : ''} />)}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---------------- top NAV/COM bar ---------------- */
function MfdTopBar({ V, fp }) {
  const gs = Math.round(num(V.groundspeed) * 1.94384);
  const trk = String(Math.round(num(V.track)) % 360).padStart(3, '0');
  const leg = legNav(V, fp);
  const dtk = leg ? `${String(Math.round(leg.dtk) % 360).padStart(3, '0')}°` : '___°';
  const swap = (x, y) => <text x={x} y={y} fill="#0ff" fontSize="16" textAnchor="middle">⇔</text>;
  return (
    <svg className="mfd-topbar" viewBox="0 0 1000 70" preserveAspectRatio="none" fontFamily="monospace">
      <rect x="0" y="0" width="1000" height="70" fill="#000" />
      {[300, 660].map((x) => <line key={x} x1={x} y1="2" x2={x} y2="68" stroke="#333" strokeWidth="1.5" />)}
      <line x1="0" y1="70" x2="1000" y2="70" stroke="#3a3a3a" strokeWidth="2" />
      {/* NAV1 / NAV2 — standby LEFT (cyan, boxed), active RIGHT (white) per manual */}
      <text x="10" y="27" fill="#fff" fontSize="13">NAV1</text>
      <rect x="50" y="11" width="80" height="21" fill="none" stroke="#0ff" strokeWidth="1.3" />
      <text x="126" y="27" fill="#0ff" fontSize="17" textAnchor="end">{navF(V.nav1Sb)}</text>
      {swap(150, 27)}
      <text x="174" y="27" fill="#fff" fontSize="17">{navF(V.nav1)}</text>
      <text x="10" y="58" fill="#fff" fontSize="13">NAV2</text>
      <text x="126" y="58" fill="#0ff" fontSize="17" textAnchor="end">{navF(V.nav2Sb)}</text>
      <text x="174" y="58" fill="#fff" fontSize="17">{navF(V.nav2)}</text>
      {/* centre: GS/DTK/TRK/ETE + active mode line */}
      <text x="312" y="27" fill="#fff" fontSize="13">GS</text>
      <text x="350" y="27" fill="#e040fb" fontSize="15" fontWeight="bold">{gs}</text>
      <text x="378" y="27" fill="#0c9" fontSize="11">KT</text>
      <text x="410" y="27" fill="#fff" fontSize="13">DTK</text>
      <text x="448" y="27" fill="#e040fb" fontSize="15" fontWeight="bold">{dtk}</text>
      <text x="520" y="27" fill="#fff" fontSize="13">TRK</text>
      <text x="560" y="27" fill="#e040fb" fontSize="15" fontWeight="bold">{trk}°</text>
      <text x="610" y="27" fill="#fff" fontSize="13">ETE</text>
      <text x="648" y="27" fill="#fff" fontSize="15">{fmtEte(leg?.ete)}</text>
      {/* active leg (centre): → waypoint + distance, or no-flight-plan note */}
      {leg ? (
        <g>
          <text x="412" y="58" fill="#e040fb" fontSize="16">→</text>
          <text x="432" y="58" fill="#fff" fontSize="16" fontWeight="bold">{leg.id}</text>
          <text x="520" y="58" fill="#0ff" fontSize="15">{leg.dist.toFixed(1)}</text>
          <text x="566" y="58" fill="#0c9" fontSize="11">NM</text>
        </g>
      ) : (
        <text x="480" y="58" fill="#777" fontSize="14" textAnchor="middle">NO ACTIVE WAYPOINT</text>
      )}
      {/* COM1 / COM2 */}
      <text x="690" y="27" fill="#0f0" fontSize="17">{comF(V.com1)}</text>
      {swap(818, 27)}
      <rect x="846" y="11" width="92" height="21" fill="none" stroke="#0ff" strokeWidth="1.3" />
      <text x="936" y="27" fill="#0ff" fontSize="17" textAnchor="end">{comF(V.com1Sb)}</text>
      <text x="994" y="27" fill="#fff" fontSize="12" textAnchor="end">COM1</text>
      <text x="690" y="58" fill="#fff" fontSize="17">{comF(V.com2)}</text>
      <text x="936" y="58" fill="#fff" fontSize="17" textAnchor="end">{comF(V.com2Sb)}</text>
      <text x="994" y="58" fill="#fff" fontSize="12" textAnchor="end">COM2</text>
    </svg>
  );
}

/* ---------------- vertical profile (PROFILE softkey) ---------------- */
// Altitude-vs-distance view along the active flight plan: the aircraft at the
// left, upcoming waypoints with their target altitudes, and the planned descent
// path between them. Pure geometry from the plan + current altitude.
function VertProfile({ V, fp }) {
  const R = 3440.065, rad = (d) => (d * Math.PI) / 180;
  const dist = (a, b) => {
    const dLat = rad(b.lat - a.lat), dLon = rad(b.lon - a.lon);
    const s = Math.sin(dLat / 2) ** 2 + Math.cos(rad(a.lat)) * Math.cos(rad(b.lat)) * Math.sin(dLon / 2) ** 2;
    return 2 * R * Math.asin(Math.min(1, Math.sqrt(s)));
  };
  const wps = fp?.waypoints || [];
  const ai = Math.max(1, Math.min(wps.length - 1, fp?.activeLeg ?? 1));
  const alt = num(V.altitude);
  const pts = []; let cum = 0, prev = { lat: num(V.lat), lon: num(V.lon) };
  for (let i = ai; i < wps.length; i++) { cum += dist(prev, wps[i]); prev = wps[i]; pts.push({ d: cum, alt: num(wps[i].alt) || null, id: wps[i].id }); }
  const maxD = Math.max(10, cum);
  const altMax = Math.max(alt, ...pts.map((p) => p.alt || 0), 3000) * 1.15;
  const W = 1000, H = 200, padL = 46, padR = 12, padT = 12, padB = 22;
  const x = (d) => padL + (d / maxD) * (W - padL - padR);
  const y = (a) => (H - padB) - (a / altMax) * (H - padT - padB);
  const altPts = pts.filter((p) => p.alt != null);
  const path = [`${x(0)},${y(alt)}`, ...altPts.map((p) => `${x(p.d)},${y(p.alt)}`)].join(' ');
  const grid = [0, altMax / 2, altMax].map((a) => Math.round(a / 500) * 500);
  return (
    <div className="vprof">
      <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
        <rect x="0" y="0" width={W} height={H} fill="#05080b" />
        {grid.map((a) => (
          <g key={a}>
            <line x1={padL} y1={y(a)} x2={W - padR} y2={y(a)} stroke="#1b2730" strokeWidth="1" />
            <text x={padL - 5} y={y(a) + 4} fill="#6f808d" fontSize="11" textAnchor="end" fontFamily="monospace">{Math.round(a / 100) * 100}</text>
          </g>
        ))}
        {/* planned vertical path through waypoint target altitudes */}
        {altPts.length > 0 && <polyline points={path} fill="none" stroke="#ff20ff" strokeWidth="2.5" />}
        {/* waypoints */}
        {pts.map((p, i) => (
          <g key={p.id + i}>
            <line x1={x(p.d)} y1={padT} x2={x(p.d)} y2={H - padB} stroke="#222d36" strokeWidth="1" />
            {p.alt != null && <rect x={x(p.d) - 3} y={y(p.alt) - 3} width="6" height="6" fill="#4fa8ff" />}
            <text x={x(p.d)} y={H - padB + 14} fill="#9fb3c0" fontSize="11" textAnchor="middle" fontFamily="monospace">{p.id}</text>
            {p.alt != null && <text x={x(p.d)} y={y(p.alt) - 7} fill="#4fa8ff" fontSize="10" textAnchor="middle" fontFamily="monospace">{p.alt}</text>}
          </g>
        ))}
        {/* own aircraft at the left edge */}
        <polygon points={`${x(0) - 7},${y(alt)} ${x(0) + 7},${y(alt) - 5} ${x(0) + 7},${y(alt) + 5}`} fill="#ffce00" />
        <text x={x(0) + 10} y={y(alt) - 6} fill="#ffce00" fontSize="11" fontFamily="monospace">{Math.round(alt)}</text>
      </svg>
    </div>
  );
}

/* ---------------- engine instrument strip (EIS) ---------------- */
function EisStrip({ V }) {
  const rpm = arr(V.engRpm);
  const ffGph = (arr(V.fuelFlow) * 3600) / KG_PER_GAL;
  const oilPsi = arr(V.oilPress);
  // X-Plane's temperature indicator datarefs may already honor the user's unit
  // (°F) despite the "_deg_C" name. Auto-detect: only convert if it still looks
  // like Celsius, so we don't double-convert (which pegged the gauges red).
  const oilT = arr(V.oilTemp), egtT = arr(V.egt);
  const oilF = oilT > 150 ? oilT : oilT * 9 / 5 + 32;
  const egtF = egtT > 900 ? egtT : egtT * 9 / 5 + 32;
  const fuelL = arr(V.fuelQty, 0) / KG_PER_GAL;
  const fuelR = arr(V.fuelQty, 1) / KG_PER_GAL;
  const voltsM = arr(V.volts, 0, 28);                 // main bus
  const voltsE = arr(V.volts, 1, voltsM);             // essential bus (falls back to main)
  const ampsM = arr(V.genAmps, 0);                    // alternator (M)
  const ampsS = arr(V.amps, 0);                       // battery (S)
  const engHrs = num(V.engHrs) / 3600;
  return (
    <svg className="eis-svg" viewBox="0 0 190 540" preserveAspectRatio="xMidYMin meet" fontFamily="monospace">
      <rect x="0" y="0" width="190" height="540" fill="#0a0a0a" />
      <RpmArc rpm={rpm} />
      <Bar y={132} label="FFLOW GPH" val={ffGph.toFixed(1)} min={0} max={20} value={ffGph}
        zones={[{ from: 0, to: 17, c: '#0c0' }, { from: 17, to: 20, c: '#c00' }]} />
      <Bar y={170} label="OIL PSI" val={Math.round(oilPsi)} min={0} max={100} value={oilPsi}
        zones={[{ from: 0, to: 20, c: '#c00' }, { from: 20, to: 100, c: '#0c0' }]} />
      <Bar y={208} label="OIL °F" val={Math.round(oilF)} min={75} max={250} value={oilF}
        zones={[{ from: 100, to: 245, c: '#0c0' }]} />
      <Bar y={246} label="EGT °F" val={Math.round(egtF)} min={800} max={1650} value={egtF} zones={[]} />
      <Bar y={284} label="VAC" min={0} max={10} value={5}
        zones={[{ from: 4.5, to: 5.5, c: '#0c0' }]} />
      <FuelBar y={330} left={fuelL} right={fuelR} />
      {/* fuel totalizer (SYSTEM → DEC/INC/RST FUEL): pilot-set remaining + used */}
      {(() => {
        const rem = num(V.fuelTot) / KG_PER_GAL;
        const used = Math.max(0, (num(V.fuelMax) - num(V.fuelTot)) / KG_PER_GAL);
        return (<>
          <text x="8" y="392" fill="#39d3c0" fontSize="11">CALC</text>
          <text x="118" y="392" fill="#fff" fontSize="14" textAnchor="end">{rem.toFixed(1)}</text>
          <text x="124" y="392" fill="#7f8c97" fontSize="10">GAL</text>
          <text x="182" y="392" fill="#9aa" fontSize="10" textAnchor="end">USED {used.toFixed(0)}</text>
        </>);
      })()}
      <text x="8" y="412" fill="#39d3c0" fontSize="12">ENG</text>
      <text x="182" y="412" fill="#fff" fontSize="14" textAnchor="end">{engHrs.toFixed(1)} HRS</text>
      <text x="95" y="438" fill="#39d3c0" fontSize="12" textAnchor="middle">– ELECTRICAL –</text>
      <text x="20" y="462" fill="#fff" fontSize="12">M</text>
      <text x="95" y="462" fill="#39d3c0" fontSize="12" textAnchor="middle">BUS</text>
      <text x="170" y="462" fill="#fff" fontSize="12" textAnchor="end">E</text>
      <text x="18" y="482" fill="#fff" fontSize="15">{voltsM.toFixed(1)}</text>
      <text x="95" y="482" fill="#39d3c0" fontSize="11" textAnchor="middle">VOLTS</text>
      <text x="172" y="482" fill="#fff" fontSize="15" textAnchor="end">{voltsE.toFixed(1)}</text>
      <text x="20" y="506" fill="#fff" fontSize="12">M</text>
      <text x="95" y="506" fill="#39d3c0" fontSize="12" textAnchor="middle">BATT</text>
      <text x="170" y="506" fill="#fff" fontSize="12" textAnchor="end">S</text>
      <text x="18" y="526" fill="#fff" fontSize="15">{ampsM >= 0 ? '+' : ''}{ampsM.toFixed(1)}</text>
      <text x="95" y="526" fill="#39d3c0" fontSize="11" textAnchor="middle">AMPS</text>
      <text x="172" y="526" fill="#fff" fontSize="15" textAnchor="end">{ampsS >= 0 ? '+' : ''}{ampsS.toFixed(1)}</text>
    </svg>
  );
}

function Bar({ y, label, val, min, max, value, zones }) {
  const x0 = 8, x1 = 182, bw = x1 - x0;
  const px = (v) => x0 + bw * Math.max(0, Math.min(1, (v - min) / (max - min)));
  const p = px(value);
  return (
    <g>
      <text x={x0} y={y} fill="#39d3c0" fontSize="12">{label}</text>
      {val != null && <text x={x1} y={y} fill="#fff" fontSize="16" fontWeight="bold" textAnchor="end">{val}</text>}
      <rect x={x0} y={y + 9} width={bw} height="5" fill="#2a2a2a" />
      {zones.map((z, i) => <rect key={i} x={px(z.from)} y={y + 9} width={Math.max(0, px(z.to) - px(z.from))} height="5" fill={z.c} />)}
      <polygon points={`${p},${y + 9} ${p - 5},${y + 1} ${p + 5},${y + 1}`} fill="#fff" stroke="#000" strokeWidth="0.5" />
    </g>
  );
}

// Fuel quantity: one bar per the C172's two tanks, with L and R pointers on a
// shared 0–10–20–F (gal) scale; yellow/red caution zone at the low end.
function FuelBar({ y, left, right }) {
  const x0 = 8, x1 = 182, bw = x1 - x0, max = 26.5;
  const px = (g) => x0 + bw * Math.max(0, Math.min(1, g / max));
  const tick = (g, lbl) => (
    <g key={lbl}>
      <line x1={px(g)} y1={y + 16} x2={px(g)} y2={y + 20} stroke="#777" strokeWidth="1" />
      <text x={px(g)} y={y + 31} fill="#aaa" fontSize="10" textAnchor="middle">{lbl}</text>
    </g>
  );
  const ptr = (g, lbl) => (
    <g>
      <polygon points={`${px(g)},${y + 8} ${px(g) - 5},${y} ${px(g) + 5},${y}`} fill="#fff" stroke="#000" strokeWidth="0.5" />
      <text x={px(g)} y={y - 2} fill="#fff" fontSize="9" textAnchor="middle">{lbl}</text>
    </g>
  );
  return (
    <g>
      <text x={x0} y={y - 6} fill="#39d3c0" fontSize="12">FUEL QTY GAL</text>
      <rect x={x0} y={y + 8} width={bw} height="6" fill="#2a2a2a" />
      <rect x={px(0)} y={y + 8} width={px(2.5) - px(0)} height="6" fill="#c00" />
      <rect x={px(2.5)} y={y + 8} width={px(5) - px(2.5)} height="6" fill="#dd0" />
      <rect x={px(5)} y={y + 8} width={px(max) - px(5)} height="6" fill="#0c0" />
      {tick(0, '0')}{tick(8.83, '10')}{tick(17.66, '20')}{tick(max, 'F')}
      {ptr(left, 'L')}{ptr(right, 'R')}
    </g>
  );
}

function RpmArc({ rpm }) {
  const max = 2700, frac = Math.max(0, Math.min(1, rpm / max));
  const a0 = -210, a1 = 30, ang = a0 + (a1 - a0) * frac;
  const cx = 95, cy = 62, r = 42;
  const pt = (deg, rr) => [cx + rr * Math.cos((deg * Math.PI) / 180), cy + rr * Math.sin((deg * Math.PI) / 180)];
  const arc = (s, e, color, w) => {
    const [x0, y0] = pt(s, r), [x1, y1] = pt(e, r);
    return <path d={`M${x0} ${y0} A${r} ${r} 0 ${e - s > 180 ? 1 : 0} 1 ${x1} ${y1}`} fill="none" stroke={color} strokeWidth={w} />;
  };
  const [nx, ny] = pt(ang, r - 2);
  return (
    <g fontFamily="monospace">
      {arc(a0, a1, '#2a2a2a', 7)}
      {arc(a0, -30, '#0c0', 7)}
      {arc(0, a1, '#c00', 7)}
      <line x1={cx} y1={cy} x2={nx} y2={ny} stroke="#fff" strokeWidth="2.5" />
      <circle cx={cx} cy={cy} r="3" fill="#fff" />
      <text x={cx} y={cy + 14} fill="#39d3c0" fontSize="12" textAnchor="middle">RPM</text>
      <text x={cx} y={cy + 40} fill="#fff" fontSize="26" fontWeight="bold" textAnchor="middle">{Math.round(rpm)}</text>
    </g>
  );
}

/* ---------------- map chrome overlay (compass rose / range / mode) ---------------- */
const NICE = [0.5, 1, 1.5, 2, 2.5, 4, 5, 7.5, 10, 15, 20, 25, 40, 50, 75, 100, 150, 200, 250, 500];
function niceRange(nm) { let r = NICE[0]; for (const s of NICE) if (nm >= s) r = s; return r; }

function MapChrome({ V, rangeNm }) {
  const gs = Math.round(num(V.groundspeed) * 1.94384);
  const rng = niceRange(rangeNm);
  const wd = ((Math.round(num(V.windDir)) % 360) + 360) % 360, ws = Math.round(num(V.windSpd));
  return (
    <div className="map-chrome">
      {/* the compass rose now lives in MapView, anchored to the aircraft */}
      <div className="mc-tr"><b>{gs} KT</b><span>NORTH UP</span></div>
      <div className="mc-wind">
        {ws >= 1
          ? (<><span className="mc-windarr" style={{ transform: `rotate(${wd + 180}deg)` }}>↑</span><span>{String(wd).padStart(3, '0')}° {ws}<i>kt</i></span></>)
          : <span>CALM</span>}
      </div>
      <div className="mc-range">{rng} NM</div>
    </div>
  );
}
