// Top bar, drone switcher rail, right-side telemetry, arm/disarm, flight modes

// ================= TOP BAR =================
function TopBar({ starlink, controller, t, onEStop }){
  return (
    <div style={ps.topBar}>
      <div style={ps.topLeft}>
        <div style={ps.logo}>
          <span style={ps.logoMark}>◇</span>
          <span style={ps.logoText}>HYPERION · GCS</span>
          <span className="mono" style={ps.logoBuild}>v2.14.0 · OP:BRIGHT-ANVIL</span>
        </div>
      </div>

      <div style={ps.topCenter}>
        <StatusPill icon="◉" label="STARLINK" status={starlink.status} detail={`${starlink.latency}ms · ↓${starlink.down} ↑${starlink.up} Mbps · SNR ${starlink.snr}dB`} />
        <StatusPill icon="▲" label="UPLINK" status="OK" detail="MAVLink 2 · 57 Hz · AES-256" />
        <StatusPill icon="◆" label="RC" status={controller.status} detail={`${controller.model} · ${Math.round(controller.battery*100)}%`} />
        <StatusPill icon="◈" label="GCS" status="OK" detail="CPU 34% · 18°C · REC" />
      </div>

      <div style={ps.topRight}>
        <div className="mono" style={ps.clock}>{fmtTime(t)}</div>
        <button style={ps.eStop} onClick={onEStop}>
          <span style={ps.eStopDot}/> EMERGENCY STOP
        </button>
      </div>
    </div>
  );
}

function StatusPill({ icon, label, status, detail }){
  const ok = status === 'OK' || status === 'STRONG';
  const warn = status === 'FAIR';
  const bad = status === 'LOST' || status === 'DISCONN';
  const c = bad ? 'var(--danger)' : warn ? 'var(--warn)' : 'var(--accent)';
  return (
    <div style={ps.pill}>
      <span style={{...ps.pillIcon, color:c}}>{icon}</span>
      <div style={ps.pillStack}>
        <div style={ps.pillRow}>
          <span style={ps.pillLabel}>{label}</span>
          <span className="mono" style={{...ps.pillStatus, color:c}}>{status}</span>
        </div>
        <div className="mono" style={ps.pillDetail}>{detail}</div>
      </div>
    </div>
  );
}

// ================= LEFT RAIL — FLEET =================
function FleetRail({ fleet, activeId, onSelect }){
  return (
    <div style={ps.rail}>
      <div style={ps.railHeader}>
        <div>
          <div style={ps.railTitle}>FLEET</div>
          <div className="mono" style={ps.railSub}>{fleet.filter(f => f.link !== 'LOST').length}/{fleet.length} ONLINE</div>
        </div>
        <button style={ps.railAdd}>+ ADD</button>
      </div>

      <div style={ps.railList}>
        {fleet.map(d => <FleetItem key={d.id} drone={d} active={d.id === activeId} onClick={()=>onSelect(d.id)} />)}
      </div>

      <div style={ps.railFooter}>
        <button style={ps.railFooterBtn}>FORMATION…</button>
        <button style={ps.railFooterBtn}>RTB ALL</button>
      </div>
    </div>
  );
}

function FleetItem({ drone, active, onClick }){
  const off = drone.link === 'LOST';
  const bars = linkBars(drone.link);
  return (
    <button style={{...ps.fleetItem, ...(active ? ps.fleetItemActive : null), ...(off ? ps.fleetItemOff : null)}} onClick={onClick}>
      <div style={ps.fleetTop}>
        <div style={ps.fleetIdBlock}>
          <div className="mono" style={ps.fleetId}>{drone.id}</div>
          <div style={ps.fleetCall}>{drone.call}</div>
        </div>
        <div style={ps.fleetMeta}>
          <div style={{display:'flex', gap:2, alignItems:'flex-end', height:12}}>
            {[1,2,3,4].map(i => (
              <span key={i} style={{
                width:3, height:3+i*2,
                background: i <= bars ? (off ? 'var(--ink-3)' : 'var(--accent)') : 'var(--line-2)'
              }}/>
            ))}
          </div>
          <div className="mono" style={ps.fleetRole}>{drone.role}</div>
        </div>
      </div>

      <div style={ps.fleetBottom}>
        <div style={ps.fleetBatRow}>
          <div style={ps.batTrack}>
            <div style={{...ps.batFill, width:`${drone.battery*100}%`, background: batteryColor(drone.battery)}}/>
          </div>
          <div className="mono" style={{...ps.fleetBatPct, color: batteryColor(drone.battery)}}>{Math.round(drone.battery*100)}%</div>
        </div>
        <div className="mono" style={ps.fleetStatLine}>
          {off ? 'LINK LOST · last 04:22 ago' : `${drone.mode} · ${drone.alt}m · ${drone.dist.toFixed(1)}km`}
        </div>
      </div>

      {active && <span style={ps.fleetActiveBar} />}
      {drone.armed && !off && <span style={ps.fleetArmDot} title="ARMED"/>}
    </button>
  );
}

// ================= RIGHT COLUMN =================
function RightColumn({ drone, onArmToggle, onMode }){
  return (
    <div style={ps.right}>
      <TelemetryPanel drone={drone} />
      <FlightModePanel drone={drone} onMode={onMode} />
      <ArmPanel drone={drone} onArmToggle={onArmToggle} />
      <SubsystemsPanel drone={drone} />
    </div>
  );
}

function TelemetryPanel({ drone }){
  const t = useClock();
  const head = (drone.head + Math.sin(t/2000)*1.2);
  return (
    <div style={ps.card}>
      <div style={ps.cardHeader}>
        <span style={ps.cardTitle}>TELEMETRY</span>
        <span className="mono" style={ps.cardSub}>{drone.id} · {drone.call}</span>
      </div>
      <div style={ps.teleGrid}>
        <TeleCell label="BATTERY" value={`${Math.round(drone.battery*100)}%`} sub={`${(drone.battery*22.2).toFixed(1)}V · 6S`} color={batteryColor(drone.battery)} />
        <TeleCell label="ALT MSL" value={drone.alt} unit="m" sub={`VS ${(Math.sin(t/1500)*0.8).toFixed(1)} m/s`} />
        <TeleCell label="SPEED" value={drone.spd.toFixed(1)} unit="m/s" sub={`${(drone.spd*3.6).toFixed(0)} km/h`} />
        <TeleCell label="HEADING" value={head.toFixed(0).padStart(3,'0')} unit="°" sub={cardinal(head)} />
        <TeleCell label="GPS" value={drone.gps} unit="sat" sub={drone.gps >= 12 ? 'RTK FIX' : drone.gps >= 8 ? '3D FIX' : 'NO FIX'} color={drone.gps >= 12 ? 'var(--accent)' : drone.gps >= 8 ? 'var(--warn)' : 'var(--danger)'} />
        <TeleCell label="DISTANCE" value={drone.dist.toFixed(2)} unit="km" sub="FROM HOME" />
      </div>

      <div style={ps.bar}>
        <div style={ps.barLabel}>
          <span className="mono" style={{color:'var(--ink-3)'}}>SIGNAL VIA STARLINK</span>
          <span className="mono" style={{color:'var(--accent)'}}>-68 dBm</span>
        </div>
        <div style={ps.barTrack}>
          <div style={{...ps.barFill, width:'78%'}}/>
          <div style={{...ps.barMark, left:'25%'}}/>
          <div style={{...ps.barMark, left:'50%'}}/>
          <div style={{...ps.barMark, left:'75%'}}/>
        </div>
      </div>
    </div>
  );
}

function TeleCell({ label, value, unit, sub, color }){
  return (
    <div style={ps.teleCell}>
      <div className="mono" style={ps.teleLabel}>{label}</div>
      <div className="mono" style={{...ps.teleValue, color: color || 'var(--ink)'}}>
        {value}<span style={ps.teleUnit}>{unit ? ' '+unit : ''}</span>
      </div>
      <div className="mono" style={ps.teleSub}>{sub}</div>
    </div>
  );
}

function cardinal(h){
  const dirs = ['N','NE','E','SE','S','SW','W','NW'];
  return dirs[Math.round(((h%360)/45))%8];
}

function FlightModePanel({ drone, onMode }){
  return (
    <div style={ps.card}>
      <div style={ps.cardHeader}>
        <span style={ps.cardTitle}>FLIGHT MODE</span>
        <span className="mono" style={ps.cardSub}>CURRENT · {drone.mode}</span>
      </div>
      <div style={ps.modeRow}>
        {MODES.map(m => (
          <button key={m}
            style={{...ps.modeBtn, ...(drone.mode === m ? ps.modeBtnActive : null)}}
            onClick={()=>onMode(m)}>
            <span style={ps.modeBtnLabel}>{m}</span>
            <span style={ps.modeBtnDesc}>{modeDesc(m)}</span>
          </button>
        ))}
      </div>
    </div>
  );
}

function modeDesc(m){
  return { MANUAL:'Stick input', STAB:'Self-level', AUTO:'Mission', RTL:'Return home' }[m];
}

function ArmPanel({ drone, onArmToggle }){
  const [confirming, setConfirming] = React.useState(false);
  const [holdPct, setHoldPct] = React.useState(0);
  const holdRef = React.useRef(null);

  React.useEffect(()=>{
    if (!confirming){ setHoldPct(0); return; }
  }, [confirming]);

  const startHold = () => {
    const start = Date.now();
    const step = () => {
      const p = Math.min(1, (Date.now()-start)/1200);
      setHoldPct(p);
      if (p >= 1){
        onArmToggle();
        setConfirming(false);
        setHoldPct(0);
      } else {
        holdRef.current = requestAnimationFrame(step);
      }
    };
    holdRef.current = requestAnimationFrame(step);
  };
  const cancelHold = () => {
    if (holdRef.current) cancelAnimationFrame(holdRef.current);
    setHoldPct(0);
  };

  const action = drone.armed ? 'DISARM' : 'ARM';
  const actionColor = drone.armed ? 'var(--warn)' : 'var(--accent)';

  return (
    <div style={ps.card}>
      <div style={ps.cardHeader}>
        <span style={ps.cardTitle}>MOTOR STATE</span>
        <span className="mono" style={{...ps.cardSub, color: drone.armed ? 'var(--accent)' : 'var(--ink-3)'}}>
          {drone.armed ? '● ARMED' : '○ DISARMED'}
        </span>
      </div>

      {!confirming ? (
        <button style={{...ps.armBtn, color:actionColor, borderColor:actionColor}} onClick={()=>setConfirming(true)}>
          <span style={ps.armBtnIcon}>{drone.armed ? '◎' : '◉'}</span>
          <span style={ps.armBtnLabel}>{action}</span>
          <span style={ps.armBtnHint}>requires confirm</span>
        </button>
      ) : (
        <div>
          <div style={ps.confirmMsg}>
            Hold to {action.toLowerCase()} <b>{drone.id} {drone.call}</b>.
            {drone.armed ? ' Rotors will spin down.' : ' Rotors will spin up. Clear the area.'}
          </div>
          <button
            style={{...ps.holdBtn, borderColor:actionColor}}
            onMouseDown={startHold} onMouseUp={cancelHold} onMouseLeave={cancelHold}
            onTouchStart={startHold} onTouchEnd={cancelHold}
          >
            <div style={{...ps.holdFill, width:`${holdPct*100}%`, background:actionColor, opacity:.25}}/>
            <span style={{...ps.holdLabel, color:actionColor}}>HOLD TO {action}</span>
          </button>
          <button style={ps.cancelBtn} onClick={()=>setConfirming(false)}>CANCEL</button>
        </div>
      )}
    </div>
  );
}

function SubsystemsPanel({ drone }){
  const t = useClock();
  const rows = [
    { k:'IMU',     v:'OK',   c:'var(--accent)' },
    { k:'COMPASS', v:'OK',   c:'var(--accent)' },
    { k:'BARO',    v:'OK',   c:'var(--accent)' },
    { k:'ESC',     v:`${(28+Math.sin(t/900)*2).toFixed(0)}°C`, c:'var(--ink-2)' },
    { k:'PAYLOAD', v: drone.role === 'STRIKE' ? 'ARMED' : 'NONE',    c: drone.role==='STRIKE' ? 'var(--warn)':'var(--ink-3)' },
    { k:'FAILSAFE', v:'RTL @ 20%', c:'var(--ink-2)' },
  ];
  return (
    <div style={ps.card}>
      <div style={ps.cardHeader}>
        <span style={ps.cardTitle}>SUBSYSTEMS</span>
      </div>
      <div style={ps.subGrid}>
        {rows.map(r => (
          <div key={r.k} style={ps.subRow}>
            <span className="mono" style={ps.subKey}>{r.k}</span>
            <span className="mono" style={{...ps.subVal, color:r.c}}>{r.v}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// Controller (RC) stick visualizer for top bar overflow
function ControllerWidget({ controller }){
  return (
    <div style={ps.ctrl}>
      <StickVis label="L" x={controller.lx} y={controller.ly} />
      <StickVis label="R" x={controller.rx} y={controller.ry} />
    </div>
  );
}
function StickVis({ label, x, y }){
  return (
    <div style={ps.stick}>
      <div style={ps.stickRing}/>
      <div style={{...ps.stickDot, transform:`translate(${x*18}px, ${-y*18}px)`}}/>
      <div className="mono" style={ps.stickLabel}>{label}</div>
    </div>
  );
}

// ================= STYLES =================
const ps = {
  topBar: {
    position:'absolute', top:0, left:0, right:0, height:58,
    display:'flex', alignItems:'stretch',
    background:'var(--panel)', borderBottom:'1px solid var(--line)', zIndex:20
  },
  topLeft:  { display:'flex', alignItems:'center', padding:'0 18px', borderRight:'1px solid var(--line)', minWidth:260 },
  topCenter:{ flex:1, display:'flex', alignItems:'stretch' },
  topRight: { display:'flex', alignItems:'center', gap:14, padding:'0 14px 0 18px', borderLeft:'1px solid var(--line)' },

  logo: { display:'flex', flexDirection:'column', gap:2 },
  logoMark: { display:'none' },
  logoText: { fontSize:13, fontWeight:600, letterSpacing:'.18em' },
  logoBuild: { fontSize:9.5, color:'var(--ink-3)', letterSpacing:'.1em' },

  pill: {
    flex:1, display:'flex', alignItems:'center', gap:10,
    padding:'0 16px', borderRight:'1px solid var(--line)', minWidth:0
  },
  pillIcon: { fontSize:14, lineHeight:1 },
  pillStack: { display:'flex', flexDirection:'column', gap:1, minWidth:0 },
  pillRow: { display:'flex', alignItems:'baseline', gap:8 },
  pillLabel: { fontSize:10, color:'var(--ink-3)', letterSpacing:'.14em', fontWeight:600 },
  pillStatus: { fontSize:11, fontWeight:600, letterSpacing:'.08em' },
  pillDetail: { fontSize:10.5, color:'var(--ink-2)', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' },

  clock: { fontSize:15, fontWeight:500, color:'var(--ink)', letterSpacing:'.04em' },
  eStop: {
    display:'flex', alignItems:'center', gap:8,
    padding:'8px 14px', border:'1px solid rgba(255,90,90,.5)',
    color:'var(--danger)', fontSize:11, fontWeight:700, letterSpacing:'.14em',
    background:'rgba(255,90,90,.06)', borderRadius:2,
    fontFamily:'inherit'
  },
  eStopDot: { width:8, height:8, borderRadius:'50%', background:'var(--danger)', animation:'pulse 1.4s infinite' },

  // ---- Fleet rail ----
  rail: {
    position:'absolute', top:58, left:0, bottom:0, width:260,
    background:'var(--panel)', borderRight:'1px solid var(--line)',
    display:'flex', flexDirection:'column', zIndex:15
  },
  railHeader: {
    display:'flex', justifyContent:'space-between', alignItems:'flex-end',
    padding:'16px 18px 12px', borderBottom:'1px solid var(--line)'
  },
  railTitle: { fontSize:11, fontWeight:700, letterSpacing:'.22em', color:'var(--ink-2)' },
  railSub: { fontSize:10, color:'var(--ink-3)', marginTop:3, letterSpacing:'.08em' },
  railAdd: {
    fontSize:10, letterSpacing:'.12em', color:'var(--ink-2)',
    border:'1px solid var(--line-2)', padding:'5px 9px', borderRadius:2
  },
  railList: { flex:1, overflowY:'auto', padding:'8px' },
  railFooter: {
    display:'flex', gap:6, padding:'10px', borderTop:'1px solid var(--line)'
  },
  railFooterBtn: {
    flex:1, fontSize:10, letterSpacing:'.14em', color:'var(--ink-2)',
    border:'1px solid var(--line-2)', padding:'9px 6px', borderRadius:2
  },

  fleetItem: {
    position:'relative', display:'block', width:'100%', textAlign:'left',
    padding:'10px 12px 10px 14px',
    border:'1px solid transparent', borderRadius:2,
    marginBottom:4,
    background:'transparent',
    transition:'background .15s'
  },
  fleetItemActive: {
    background:'rgba(110,242,196,.05)', border:'1px solid rgba(110,242,196,.25)'
  },
  fleetItemOff: { opacity:.5 },
  fleetActiveBar: {
    position:'absolute', left:0, top:6, bottom:6, width:2, background:'var(--accent)'
  },
  fleetArmDot: {
    position:'absolute', right:10, top:10, width:5, height:5, borderRadius:'50%',
    background:'var(--accent)', boxShadow:'0 0 6px var(--accent)'
  },
  fleetTop: { display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:8 },
  fleetIdBlock: {},
  fleetId: { fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em' },
  fleetCall: { fontSize:14, fontWeight:600, letterSpacing:'.04em', marginTop:1 },
  fleetMeta: { display:'flex', flexDirection:'column', alignItems:'flex-end', gap:3 },
  fleetRole: { fontSize:9, letterSpacing:'.14em', color:'var(--ink-3)' },
  fleetBottom: {},
  fleetBatRow: { display:'flex', alignItems:'center', gap:8, marginBottom:4 },
  batTrack: { flex:1, height:4, background:'var(--line)', borderRadius:1, overflow:'hidden' },
  batFill:  { height:'100%' },
  fleetBatPct: { fontSize:10.5, fontWeight:600, minWidth:32, textAlign:'right' },
  fleetStatLine: { fontSize:10, color:'var(--ink-2)', letterSpacing:'.06em' },

  // ---- Right column ----
  right: {
    position:'absolute', top:58, right:0, bottom:0, width:340,
    background:'var(--panel)', borderLeft:'1px solid var(--line)',
    display:'flex', flexDirection:'column', overflowY:'auto', zIndex:15
  },
  card: {
    padding:'16px 18px', borderBottom:'1px solid var(--line)'
  },
  cardHeader: {
    display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:12
  },
  cardTitle: { fontSize:11, fontWeight:700, letterSpacing:'.22em', color:'var(--ink-2)', whiteSpace:'nowrap' },
  cardSub:   { fontSize:10, color:'var(--ink-3)', letterSpacing:'.08em' },

  teleGrid: { display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:'14px 12px' },
  teleCell: { minWidth:0 },
  teleLabel: { fontSize:9.5, color:'var(--ink-3)', letterSpacing:'.14em', marginBottom:4 },
  teleValue: { fontSize:20, fontWeight:500, lineHeight:1 },
  teleUnit:  { fontSize:11, color:'var(--ink-3)', fontWeight:400 },
  teleSub:   { fontSize:9.5, color:'var(--ink-2)', marginTop:4, letterSpacing:'.06em' },

  bar: { marginTop:16 },
  barLabel: { display:'flex', justifyContent:'space-between', fontSize:10, marginBottom:5 },
  barTrack: { position:'relative', height:4, background:'var(--line)', borderRadius:1, overflow:'hidden' },
  barFill:  { height:'100%', background:'linear-gradient(90deg, var(--accent-dim), var(--accent))' },
  barMark:  { position:'absolute', top:0, bottom:0, width:1, background:'var(--bg)' },

  modeRow: { display:'grid', gridTemplateColumns:'1fr 1fr', gap:6 },
  modeBtn: {
    border:'1px solid var(--line-2)', background:'transparent', padding:'10px 12px',
    textAlign:'left', display:'flex', flexDirection:'column', gap:3, borderRadius:2
  },
  modeBtnActive: {
    border:'1px solid var(--accent)', background:'rgba(110,242,196,.06)'
  },
  modeBtnLabel: { fontSize:12, fontWeight:600, letterSpacing:'.1em' },
  modeBtnDesc:  { fontSize:10, color:'var(--ink-3)' },

  armBtn: {
    width:'100%', display:'flex', alignItems:'center', gap:14,
    border:'1px solid', padding:'16px 18px', background:'transparent',
    borderRadius:2, fontFamily:'inherit', textAlign:'left'
  },
  armBtnIcon: { fontSize:22 },
  armBtnLabel: { fontSize:16, fontWeight:600, letterSpacing:'.16em', flex:1 },
  armBtnHint:  { fontSize:9.5, color:'var(--ink-3)', letterSpacing:'.1em' },

  confirmMsg: { fontSize:12, color:'var(--ink-2)', marginBottom:10, lineHeight:1.5 },
  holdBtn: {
    position:'relative', width:'100%', border:'1px solid', background:'transparent',
    padding:'14px', fontFamily:'inherit', overflow:'hidden', borderRadius:2
  },
  holdFill: { position:'absolute', left:0, top:0, bottom:0 },
  holdLabel: { position:'relative', fontSize:13, fontWeight:700, letterSpacing:'.18em' },
  cancelBtn: {
    width:'100%', fontSize:10.5, letterSpacing:'.14em', color:'var(--ink-3)',
    padding:'8px', marginTop:6
  },

  subGrid: { display:'grid', gridTemplateColumns:'1fr 1fr', gap:'8px 12px' },
  subRow: { display:'flex', justifyContent:'space-between', alignItems:'baseline', borderBottom:'1px dashed var(--line)', paddingBottom:4 },
  subKey: { fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em' },
  subVal: { fontSize:11, fontWeight:500 },

  ctrl: { display:'flex', gap:6 },
  stick: { position:'relative', width:40, height:40 },
  stickRing: { position:'absolute', inset:0, border:'1px solid var(--line-2)', borderRadius:'50%' },
  stickDot: { position:'absolute', left:'50%', top:'50%', width:4, height:4, marginLeft:-2, marginTop:-2, background:'var(--accent)', borderRadius:'50%' },
  stickLabel: { position:'absolute', bottom:-10, left:0, right:0, textAlign:'center', fontSize:8, color:'var(--ink-3)' }
};

Object.assign(window, { TopBar, FleetRail, RightColumn, ControllerWidget });
