import React from 'react';
import { num } from '../api/useXplane.js';

// Classic analog "six-pack" VFR panel: airspeed, attitude, altimeter, turn
// coordinator, heading indicator, vertical speed — round steam gauges driven by
// the same X-Plane datarefs. For steam/VFR aircraft (and just because it looks
// great). Each gauge is a self-contained SVG on a dark instrument panel.

const arr0 = (v, d = 0) => (Array.isArray(v) ? num(v[0], d) : num(v, d));
const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
// point on a dial: ang in degrees, 0 = up (12 o'clock), clockwise positive.
const pt = (cx, cy, r, ang) => {
  const a = (ang - 90) * Math.PI / 180;
  return [cx + r * Math.cos(a), cy + r * Math.sin(a)];
};

function Bezel({ title, children }) {
  return (
    <div className="vfr-gauge">
      <svg viewBox="0 0 200 200">
        <circle cx="100" cy="100" r="99" fill="#0c0d0f" />
        <circle cx="100" cy="100" r="95" fill="#161a1f" stroke="#2a2f36" strokeWidth="2" />
        <circle cx="100" cy="100" r="88" fill="#08090b" stroke="#000" strokeWidth="1" />
        {children}
      </svg>
      <span className="vfr-name">{title}</span>
    </div>
  );
}

const Needle = ({ ang, len = 70, w = 4, color = '#fff', tail = 14 }) => (
  <g transform={`rotate(${ang} 100 100)`}>
    <line x1="100" y1={100 + tail} x2="100" y2={100 - len} stroke={color} strokeWidth={w} strokeLinecap="round" />
  </g>
);

// generic tick ring
function ticks(min, max, a0, a1, step, big = 1, r = 84, lab) {
  const out = [];
  let i = 0;
  for (let v = min; v <= max + 1e-6; v += step, i++) {
    const ang = a0 + ((v - min) / (max - min)) * (a1 - a0);
    const isBig = i % big === 0;
    const [x1, y1] = pt(100, 100, r, ang);
    const [x2, y2] = pt(100, 100, r - (isBig ? 12 : 7), ang);
    out.push(<line key={'t' + v} x1={x1} y1={y1} x2={x2} y2={y2} stroke="#cfd6dd" strokeWidth={isBig ? 2 : 1} />);
    if (lab && isBig) {
      const [lx, ly] = pt(100, 100, r - 24, ang);
      out.push(<text key={'l' + v} x={lx} y={ly + 4} textAnchor="middle" fill="#e7edf2" fontSize="12" fontFamily="'Saira Condensed',monospace">{lab(v)}</text>);
    }
  }
  return out;
}

/* ---------- Airspeed ---------- */
function ASI({ V }) {
  const kt = num(V.airspeed);
  const A0 = -150, A1 = 150, MIN = 0, MAX = 200;
  const ang = A0 + (clamp(kt, MIN, MAX) - MIN) / (MAX - MIN) * (A1 - A0);
  const arc = (lo, hi, color, rr, wdt) => {
    const [x1, y1] = pt(100, 100, rr, A0 + (lo / MAX) * (A1 - A0));
    const [x2, y2] = pt(100, 100, rr, A0 + (hi / MAX) * (A1 - A0));
    const large = ((hi - lo) / MAX) * 300 > 180 ? 1 : 0;
    return <path d={`M${x1} ${y1} A${rr} ${rr} 0 ${large} 1 ${x2} ${y2}`} fill="none" stroke={color} strokeWidth={wdt} />;
  };
  return (
    <Bezel title="AIRSPEED">
      {arc(33, 85, '#fff', 70, 4)}     {/* white flap arc */}
      {arc(48, 129, '#21d04a', 78, 5)} {/* green normal */}
      {arc(129, 163, '#e6c200', 78, 5)}{/* yellow caution */}
      {(() => { const [x, y] = pt(100, 100, 78, A0 + (163 / MAX) * (A1 - A0)); const [x2, y2] = pt(100, 100, 70, A0 + (163 / MAX) * (A1 - A0)); return <line x1={x} y1={y} x2={x2} y2={y2} stroke="#e23" strokeWidth="4" />; })()}
      {ticks(0, 200, A0, A1, 10, 2, 84, (v) => (v % 20 === 0 && v >= 40 ? v : ''))}
      <text x="100" y="150" textAnchor="middle" fill="#9aa" fontSize="11" fontFamily="monospace">KT</text>
      <Needle ang={ang} />
      <circle cx="100" cy="100" r="7" fill="#ddd" />
    </Bezel>
  );
}

/* ---------- Attitude ---------- */
function AI({ V }) {
  const pitch = num(V.pitch), roll = num(V.roll);
  const PPD = 2.0; // px per degree pitch
  const off = clamp(pitch, -25, 25) * PPD;
  return (
    <Bezel title="ATTITUDE">
      <defs>
        <clipPath id="aiclip"><circle cx="100" cy="100" r="86" /></clipPath>
      </defs>
      <g clipPath="url(#aiclip)">
        <g transform={`rotate(${-roll} 100 100)`}>
          <g transform={`translate(0 ${off})`}>
            <rect x="-60" y="-120" width="320" height="220" fill="#4a90d9" />
            <rect x="-60" y="100" width="320" height="220" fill="#7a5230" />
            <line x1="-60" y1="100" x2="260" y2="100" stroke="#fff" strokeWidth="2" />
            {[-20, -10, 10, 20].map((d) => (
              <g key={d}>
                <line x1={100 - (d % 20 === 0 ? 26 : 16)} y1={100 - d * PPD} x2={100 + (d % 20 === 0 ? 26 : 16)} y2={100 - d * PPD} stroke="#fff" strokeWidth="1.5" />
                {d % 20 === 0 && <text x={100 - 34} y={100 - d * PPD + 4} fill="#fff" fontSize="9" textAnchor="middle">{Math.abs(d)}</text>}
              </g>
            ))}
          </g>
        </g>
        {/* bank arc + pointer */}
        <g transform={`rotate(${-roll} 100 100)`}>
          {[-60, -30, -20, -10, 0, 10, 20, 30, 60].map((b) => { const [x1, y1] = pt(100, 100, 84, b); const [x2, y2] = pt(100, 100, 78, b); return <line key={b} x1={x1} y1={y1} x2={x2} y2={y2} stroke="#fff" strokeWidth={b % 30 === 0 ? 2 : 1} />; })}
          <polygon points="100,16 95,26 105,26" fill="#fff" />
        </g>
      </g>
      {/* fixed aircraft reference */}
      <polygon points="100,12 94,22 106,22" fill="#ffb300" />
      <path d="M60 100 h22 l0 8 M140 100 h-22 l0 8" fill="none" stroke="#ffb300" strokeWidth="4" />
      <rect x="97" y="97" width="6" height="6" fill="#ffb300" />
    </Bezel>
  );
}

/* ---------- Altimeter (3-pointer) ---------- */
function ALT({ V }) {
  const alt = num(V.altitude), baro = num(V.baro, 29.92);
  const a100 = (alt % 1000) / 1000 * 360;
  const a1000 = (alt % 10000) / 10000 * 360;
  const a10000 = (alt % 100000) / 100000 * 360;
  return (
    <Bezel title="ALTITUDE">
      {ticks(0, 1000, 0, 360, 100, 1, 84, (v) => (v < 1000 ? v / 100 : ''))}
      {ticks(0, 1000, 0, 360, 20, 5, 84)}
      <rect x="118" y="92" width="42" height="16" fill="#000" stroke="#444" rx="2" />
      <text x="139" y="104" textAnchor="middle" fill="#fff" fontSize="11" fontFamily="monospace">{baro.toFixed(2)}</text>
      {/* 10000 ft thin pointer */}
      <Needle ang={a10000} len={80} w={2} color="#ccc" tail={6} />
      {/* 1000 ft short fat */}
      <Needle ang={a1000} len={48} w={7} color="#fff" tail={10} />
      {/* 100 ft long */}
      <Needle ang={a100} len={78} w={4} color="#fff" tail={14} />
      <circle cx="100" cy="100" r="7" fill="#ddd" />
    </Bezel>
  );
}

/* ---------- Turn coordinator ---------- */
function TC({ V }) {
  const roll = num(V.roll), slip = num(V.slip);
  const bank = clamp(roll, -30, 30); // little-plane bank (approx turn rate)
  const ballX = 100 + clamp(slip, -8, 8) * 3.0;
  return (
    <Bezel title="TURN COORD.">
      {/* standard-rate marks */}
      {[-25, 25].map((b) => { const [x1, y1] = pt(100, 100, 80, b); const [x2, y2] = pt(100, 100, 66, b); return <line key={b} x1={x1} y1={y1} x2={x2} y2={y2} stroke="#fff" strokeWidth="2" />; })}
      <text x="42" y="96" fill="#fff" fontSize="11">L</text>
      <text x="150" y="96" fill="#fff" fontSize="11">R</text>
      {/* little airplane */}
      <g transform={`rotate(${bank} 100 100)`}>
        <line x1="40" y1="100" x2="160" y2="100" stroke="#fff" strokeWidth="4" />
        <line x1="100" y1="100" x2="100" y2="78" stroke="#fff" strokeWidth="4" />
        <circle cx="100" cy="100" r="5" fill="#fff" />
      </g>
      <text x="100" y="150" textAnchor="middle" fill="#9aa" fontSize="9">2 MIN</text>
      {/* inclinometer (slip ball) */}
      <path d="M78 168 a22 22 0 0 1 44 0" fill="none" stroke="#444" strokeWidth="1" />
      <rect x="92" y="160" width="2" height="12" fill="#666" /><rect x="106" y="160" width="2" height="12" fill="#666" />
      <circle cx={ballX} cy="167" r="5" fill="#cfd6dd" />
    </Bezel>
  );
}

/* ---------- Heading indicator ---------- */
function HI({ V }) {
  const hdg = ((num(V.heading) % 360) + 360) % 360;
  const card = [];
  for (let d = 0; d < 360; d += 5) {
    const big = d % 30 === 0;
    const [x1, y1] = pt(100, 100, 84, d);
    const [x2, y2] = pt(100, 100, 84 - (big ? 12 : 7), d);
    card.push(<line key={d} x1={x1} y1={y1} x2={x2} y2={y2} stroke="#fff" strokeWidth={big ? 2 : 1} />);
    if (big) {
      const [lx, ly] = pt(100, 100, 62, d);
      const lbl = d === 0 ? 'N' : d === 90 ? 'E' : d === 180 ? 'S' : d === 270 ? 'W' : d / 10;
      card.push(<text key={'l' + d} x={lx} y={ly + 4} textAnchor="middle" fill="#fff" fontSize="13" fontFamily="'Saira Condensed',monospace">{lbl}</text>);
    }
  }
  return (
    <Bezel title="HEADING">
      <g transform={`rotate(${-hdg} 100 100)`}>{card}</g>
      {/* fixed aircraft */}
      <line x1="100" y1="64" x2="100" y2="136" stroke="#ffb300" strokeWidth="3" />
      <line x1="78" y1="100" x2="122" y2="100" stroke="#ffb300" strokeWidth="3" />
      <polygon points="100,18 95,28 105,28" fill="#0ff" />
    </Bezel>
  );
}

/* ---------- Vertical speed ---------- */
function VSI({ V }) {
  const vs = clamp(num(V.vspeed), -2000, 2000);
  // 0 at 9 o'clock (270°), climb sweeps up (toward 0/up), descent down.
  const ang = 270 + (vs / 2000) * 160; // -2000→110°, 0→270°, +2000→430°(=70°)
  return (
    <Bezel title="VERT SPEED">
      {ticks(-2000, 2000, 110, 430, 500, 1, 84, (v) => Math.abs(v) / 1000)}
      {ticks(-2000, 2000, 110, 430, 100, 5, 84)}
      <text x="100" y="150" textAnchor="middle" fill="#9aa" fontSize="9">FPM x1000</text>
      <text x="64" y="104" fill="#fff" fontSize="10">0</text>
      <Needle ang={ang} len={78} w={3} />
      <circle cx="100" cy="100" r="6" fill="#ddd" />
    </Bezel>
  );
}

/* ---------- small gauges for the engine/fuel cluster ---------- */
const KG_GAL = 2.72;

function SmallBezel({ title, children }) {
  return (
    <div className="vfr-sg">
      <svg viewBox="0 0 120 120">
        <circle cx="60" cy="60" r="59" fill="#0c0d0f" />
        <circle cx="60" cy="60" r="56" fill="#141414" stroke="#2a2f36" strokeWidth="1.5" />
        {children}
      </svg>
      <span className="vfr-sname">{title}</span>
    </div>
  );
}

// dual half-dial gauge: left needle (lower-left sweep) + right needle (lower-right)
function Dual({ title, l, r }) {
  const sg = (v, min, max, a0, a1) => a0 + (clamp(v, min, max) - min) / (max - min) * (a1 - a0);
  const sp = (cx, cy, rr, ang) => { const a = (ang - 90) * Math.PI / 180; return [cx + rr * Math.cos(a), cy + rr * Math.sin(a)]; };
  const band = (lo, hi, min, max, a0, a1, color) => {
    const [x1, y1] = sp(60, 60, 46, sg(lo, min, max, a0, a1));
    const [x2, y2] = sp(60, 60, 46, sg(hi, min, max, a0, a1));
    return <path d={`M${x1} ${y1} A46 46 0 0 1 ${x2} ${y2}`} fill="none" stroke={color} strokeWidth="3" />;
  };
  const La = sg(l.value, l.min, l.max, -150, -20), Ra = sg(r.value, r.min, r.max, 20, 150);
  return (
    <SmallBezel title={title}>
      {l.green && band(l.green[0], l.green[1], l.min, l.max, -150, -20, '#21d04a')}
      {r.green && band(r.green[0], r.green[1], r.min, r.max, 20, 150, '#21d04a')}
      <text x="30" y="40" fill="#9aa" fontSize="8" textAnchor="middle">{l.tag}</text>
      <text x="90" y="40" fill="#9aa" fontSize="8" textAnchor="middle">{r.tag}</text>
      <g transform={`rotate(${La} 60 60)`}><line x1="60" y1="64" x2="60" y2="22" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" /></g>
      <g transform={`rotate(${Ra} 60 60)`}><line x1="60" y1="64" x2="60" y2="22" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" /></g>
      <circle cx="60" cy="60" r="5" fill="#ccc" />
    </SmallBezel>
  );
}

/* ---------- tachometer ---------- */
function Tach({ V }) {
  const rpm = arr0(V.engRpm);
  const A0 = -150, A1 = 150;
  const ang = A0 + clamp(rpm, 0, 3500) / 3500 * (A1 - A0);
  return (
    <Bezel title="TACHOMETER">
      {ticks(0, 3500, A0, A1, 500, 1, 84, (v) => v / 100)}
      {(() => { const [x1, y1] = pt(100, 100, 84, A0 + 2700 / 3500 * (A1 - A0)); const [x2, y2] = pt(100, 100, 72, A0 + 2700 / 3500 * (A1 - A0)); return <line x1={x1} y1={y1} x2={x2} y2={y2} stroke="#e23" strokeWidth="3" />; })()}
      {(() => { const [x1, y1] = pt(100, 100, 80, A0 + 2100 / 3500 * (A1 - A0)); const [x2, y2] = pt(100, 100, 80, A0 + 2600 / 3500 * (A1 - A0)); return <path d={`M${x1} ${y1} A80 80 0 0 1 ${x2} ${y2}`} fill="none" stroke="#21d04a" strokeWidth="4" />; })()}
      <text x="100" y="128" textAnchor="middle" fill="#9aa" fontSize="10">RPM x100</text>
      <text x="100" y="150" textAnchor="middle" fill="#cfd6dd" fontSize="11" fontFamily="monospace">{Math.round(rpm)}</text>
      <Needle ang={ang} />
      <circle cx="100" cy="100" r="7" fill="#ddd" />
    </Bezel>
  );
}

/* ---------- digital OAT / Volts plate ---------- */
function Clock({ V }) {
  const oatC = num(V.oat), oatF = Math.round(oatC * 9 / 5 + 32);
  const volts = arr0(V.volts, 28);
  return (
    <div className="vfr-clock">
      <div className="vc-row"><b>{oatF}°F</b><span>O.A.T.</span></div>
      <div className="vc-row"><b>{volts.toFixed(1)}</b><span>VOLT</span></div>
    </div>
  );
}

export default function VFR({ values: V }) {
  const fuelL = arr0(V.fuelQty, 0) / KG_GAL, fuelR = (Array.isArray(V.fuelQty) ? num(V.fuelQty[1]) : 0) / KG_GAL;
  const oilF = arr0(V.oilTemp) * 9 / 5 + 32, oilP = arr0(V.oilPress);
  const egtF = arr0(V.egt) * 9 / 5 + 32, ffGph = (arr0(V.fuelFlow) * 3600) / KG_GAL;
  const amps = arr0(V.amps);
  return (
    <div className="vfr-panel">
      <div className="vfr-layout">
        <div className="vfr-cluster">
          <Clock V={V} />
          <Dual title="FUEL QTY" l={{ value: fuelL, min: 0, max: 26, green: [5, 26], tag: 'L' }} r={{ value: fuelR, min: 0, max: 26, green: [5, 26], tag: 'R' }} />
          <Dual title="OIL" l={{ value: oilF, min: 75, max: 250, green: [100, 245], tag: '°F' }} r={{ value: oilP, min: 0, max: 115, green: [25, 100], tag: 'PSI' }} />
          <Dual title="EGT · FF" l={{ value: egtF, min: 800, max: 1650, tag: 'EGT' }} r={{ value: ffGph, min: 0, max: 20, green: [0, 17], tag: 'GPH' }} />
          <Dual title="VAC · AMP" l={{ value: 5, min: 0, max: 10, green: [4.5, 5.5], tag: 'SUC' }} r={{ value: amps, min: -60, max: 60, green: [0, 60], tag: 'AMP' }} />
        </div>
        <div className="vfr-main">
          <div className="vfr-grid">
            <ASI V={V} /><AI V={V} /><ALT V={V} />
            <TC V={V} /><HI V={V} /><VSI V={V} />
          </div>
          <div className="vfr-tach"><Tach V={V} /></div>
        </div>
      </div>
    </div>
  );
}
