/* global React, AndroidStatus, MiniDayDial, Meter, TabBar, SH_EL */
// Skyhearth mobile — EXPEDITION / FIELD, three directions matching the Port set.
// The desktop field is a WIDE node graph (Zone 0, 1300×340). On a tall phone we
// turn the route vertical. Node vocabulary kept from zone0.md:
//   vessel · forage · gate · danger · recruit · terminal.

// real Zone-0 board geometry (numbers/zone0 · expedition.jsx Z0)
const Z0_COORDS = {
  launch: [50, 168], a: [217, 14], d: [219, 130], b: [362, 298], h: [417, 143],
  c: [442, 15], f: [650, 27], g: [680, 223], j: [756, 125], i: [859, 17],
  k: [877, 194], n1: [822, 303], end1: [1196, 57], end2: [1187, 172], end3: [1187, 279],
};
const Z0_EDGES = [
  ['launch', 'a'], ['launch', 'd'], ['launch', 'b'], ['a', 'c'], ['d', 'c'], ['d', 'h'],
  ['h', 'g'], ['c', 'f'], ['f', 'i'], ['f', 'j'], ['b', 'j'], ['b', 'n1'], ['g', 'j'],
  ['g', 'k'], ['i', 'j'], ['i', 'end1'], ['i', 'end2'], ['j', 'end2'], ['k', 'n1'], ['n1', 'end3'],
];
// route the player has actually walked so far (for the minimap highlight)
const Z0_PATH = ['launch', 'd', 'h', 'g'];

function Minimap({ w = 332, h = 92, current = 'g' }) {
  const SW = 1300, SH = 340, padX = 12, padY = 10;
  const sx = (x) => padX + (x / SW) * (w - padX * 2);
  const sy = (y) => padY + (y / SH) * (h - padY * 2);
  const stateOf = (id) => {
    if (id === current) return 'active';
    if (Z0_PATH.includes(id)) return 'done';
    if (id.startsWith('end')) return 'dest';
    return 'idle';
  };
  const col = { active: 'var(--stamp-amber)', done: 'var(--ink)', dest: 'var(--ink-soft)', idle: 'var(--ink-ghost)' };
  return (
    <svg viewBox={`0 0 ${w} ${h}`} style={{ width: '100%', height: h, display: 'block' }}>
      {Z0_EDGES.map(([a, b], i) => {
        const A = Z0_COORDS[a], B = Z0_COORDS[b];
        const walked = Z0_PATH.includes(a) && Z0_PATH.includes(b);
        return <line key={i} x1={sx(A[0])} y1={sy(A[1])} x2={sx(B[0])} y2={sy(B[1])}
          stroke={walked ? 'var(--ink-faded)' : 'var(--ink-trace)'} strokeWidth={walked ? 1.2 : 0.8} strokeDasharray="2 2.5" />;
      })}
      {Object.entries(Z0_COORDS).map(([id, [x, y]]) => {
        const st = stateOf(id); const r = id === current ? 5.5 : id.startsWith('end') ? 4.5 : 3.5;
        return <g key={id}>
          {st === 'active' && <circle cx={sx(x)} cy={sy(y)} r={9} fill="none" stroke="var(--stamp-amber)" strokeOpacity="0.35" strokeWidth="1.5" />}
          <circle cx={sx(x)} cy={sy(y)} r={r} fill={st === 'idle' ? 'var(--paper-light)' : col[st]} stroke={col[st]} strokeWidth="1.2" />
        </g>;
      })}
    </svg>
  );
}

// node iconography
const X_GLYPH = { vessel: '⚓', forage: '❦', gate: '⌖', danger: '✶', recruit: '✦', terminal: '◈' };

function FieldDial() { return <MiniDayDial day={1} slotIdx={2} size={50} schedule={['x', 'x', null, null]} />; }

function HullRow({ hull = 16, max = 20 }) {
  const segs = 10, filled = Math.round((hull / max) * segs);
  return (
    <div className="row g8 aic">
      <span className="label" style={{ fontSize: 8.5, width: 30, flex: '0 0 30px' }}>Hull</span>
      <div className="meter" style={{ flex: 1 }}>
        {Array.from({ length: segs }).map((_, i) =>
          <div key={i} className={'meter-seg' + (i < filled ? (filled <= 3 ? ' crit' : ' on') : '')} />)}
      </div>
      <span className="mono" style={{ fontSize: 10, width: 34, textAlign: 'right' }}>{hull}/{max}</span>
    </div>
  );
}

const TELEM = [
  ['faded', '› vessel slips the Skyhearth moorings'],
  ['', 'd · tide-gate — Earth 12 ', ['ok', '✓ held']],
  ['gold', 'h · a navigator hails from the lee ✦ recruited'],
  ['cyan', 'g · kelp-perch detected — the bloom stirs'],
];
function Telem({ lines = TELEM }) {
  return (
    <div className="telem col g4">
      {lines.map((ln, i) => (
        <div key={i} className={ln[0]}>{ln[1]}{ln[2] && <span className={ln[2][0]}>{ln[2][1]}</span>}</div>
      ))}
    </div>
  );
}

// ======================================================================
// DIRECTION A — "VERTICAL ROUTE"  (faithful — matches The Ledger)
// The wide field graph rotated into a downward snaking spine. Walked nodes
// behind, current node live, the route ahead dimmed. Choices + telemetry below.
// ======================================================================
const SPINE = [
  { id: 'launch', kind: 'vessel', state: 'done', side: 'c', title: 'Cast Off', desc: 'Skyhearth moorings' },
  { id: 'd', kind: 'gate', state: 'success', side: 'l', title: 'Tide-Gate', desc: 'Earth 12 · held' },
  { id: 'h', kind: 'recruit', state: 'success', side: 'r', title: 'Navigator', desc: 'recruited ✦' },
  { id: 'g', kind: 'forage', state: 'active', side: 'l', title: 'Kelp-Perch', desc: 'Nature check · the bloom' },
  { id: 'n1', kind: 'danger', state: 'idle', side: 'r', title: 'Squall', desc: 'hazard ahead' },
  { id: 'end3', kind: 'terminal', state: 'locked', side: 'c', title: 'Gateway', desc: 'breadth gate · sealed' },
];
function ExpVerticalA() {
  return (
    <div className="phone sh-m">
      <AndroidStatus />
      <div className="appbar" style={{ paddingBottom: 4 }}>
        <div className="col">
          <span className="home" style={{ fontSize: 15 }}>Whispering Strata</span>
          <span className="sub">ZONE 0 · AFTERNOON</span>
        </div>
        <FieldDial />
      </div>
      <div className="panel panel-pad col g6" style={{ margin: '0 14px' }}>
        <HullRow hull={16} />
        <div className="row g8">
          <div className="row g6 aic grow"><span className="label" style={{ fontSize: 8, width: 30, flex: '0 0 30px' }}>Fatig</span><Meter value={42} segs={9} tone="warn" /></div>
          <div className="row g6 aic grow"><span className="label" style={{ fontSize: 8, width: 30, flex: '0 0 30px' }}>Full</span><Meter value={50} segs={9} tone="ok" /></div>
        </div>
        <span className="label" style={{ fontSize: 8, color: 'var(--el-lightning)' }}>Afternoon · Lightning &amp; Wind awake</span>
      </div>

      {/* vertical route spine */}
      <div className="screen-body scrolls" style={{ paddingTop: 10, gap: 0 }}>
        <span className="label" style={{ padding: '0 2px 6px' }}>Route · Whispering Strata</span>
        <div style={{ position: 'relative' }}>
          {/* center dashed spine */}
          <div style={{ position: 'absolute', left: '50%', top: 14, bottom: 14, width: 0, borderLeft: '1.5px dashed var(--ink-ghost)', transform: 'translateX(-50%)' }} />
          {SPINE.map((n) => {
            const stCls = n.state === 'active' ? 'active' : n.state === 'success' ? 'success' : (n.state === 'locked' || n.state === 'idle') ? 'unvisited' : '';
            const extra = n.kind === 'recruit' ? ' recruit' : n.kind === 'danger' ? ' danger' : n.kind === 'gate' ? ' gate' : n.kind === 'terminal' ? ' recruit' : '';
            // label sits to the right for 'r'/'c', to the left for 'l'
            const labelLeft = n.side === 'l';
            return (
              <div key={n.id} style={{ position: 'relative', minHeight: 60 }}>
                {/* node, locked to the spine */}
                <div className={'xnode' + (stCls ? ' ' + stCls : '') + extra}
                  style={{ position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%,-50%)', zIndex: 1 }}>{X_GLYPH[n.kind]}</div>
                {/* label, offset to one side of the spine */}
                <div className="col" style={{
                  position: 'absolute', top: '50%', transform: 'translateY(-50%)',
                  ...(labelLeft
                    ? { right: 'calc(50% + 34px)', alignItems: 'flex-end', textAlign: 'right' }
                    : { left: 'calc(50% + 34px)', alignItems: 'flex-start' }),
                  maxWidth: 130,
                }}>
                  <span className="fell" style={{ fontSize: 14, lineHeight: 1.05 }}>{n.title}</span>
                  <span className="mono muted" style={{ fontSize: 9 }}>{n.desc}</span>
                </div>
              </div>
            );
          })}
        </div>

        {/* current node action card */}
        <div className="panel brackets panel-pad col g8" style={{ marginTop: 6 }}>
          <div className="card-head" style={{ margin: 0 }}>
            <span className="fell" style={{ fontSize: 16 }}>Kelp-Perch · Forage</span>
            <span className="stamp stamp-amber" style={{ fontSize: 8 }}>Here</span>
          </div>
          <span className="mono muted" style={{ fontSize: 10.5, lineHeight: 1.5 }}>A drift of pale kelp clouds the strata. Working it draws on the spirit's <b style={{ color: 'var(--el-nature)' }}>Nature</b>.</span>
          <button className="btn-primary" style={{ fontSize: 14, padding: 11 }}>Forage the bloom · Nature 64%</button>
          <button className="btn-ghost">Move on ▾</button>
        </div>

        <div className="panel panel-soft panel-pad" style={{ marginTop: 4 }}>
          <span className="label" style={{ marginBottom: 6, display: 'block' }}>Field Log</span>
          <Telem />
        </div>
      </div>

      <TabBar active="expedition" />
    </div>
  );
}

// ======================================================================
// DIRECTION B — "FOCUS NODE"  (matches Focus Dial)
// One encounter, full-bleed. A minimap of the whole route sits up top; the
// current node's choices live in a bottom sheet. The 3-solution hazard model.
// ======================================================================
function ExpFocusB() {
  return (
    <div className="phone sh-m">
      <AndroidStatus />
      <div className="row between aic" style={{ padding: '4px 16px 0' }}>
        <div className="col">
          <span className="label">Whispering Strata · Z0</span>
          <span className="fell" style={{ fontSize: 17, lineHeight: 1 }}>The Squall</span>
        </div>
        <FieldDial />
      </div>

      {/* minimap */}
      <div className="panel panel-soft" style={{ margin: '8px 14px 0', padding: '2px 2px 0' }}>
        <Minimap current="n1" />
      </div>

      {/* hero encounter */}
      <div className="grow col center aic" style={{ padding: '6px 18px' }}>
        <div className={'xnode danger active'} style={{ width: 96, height: 96, fontSize: 40, borderWidth: 2 }}>✶</div>
        <span className="fell" style={{ fontSize: 22, marginTop: 12 }}>Squall-Wall</span>
        <span className="mono muted" style={{ fontSize: 11, textAlign: 'center', marginTop: 4, lineHeight: 1.5, maxWidth: 270 }}>
          A wall of charged air bars the gateway tail. Push through, slip the edge, or wait it down.
        </span>
        <div className="row g8 aic" style={{ marginTop: 10 }}>
          <span className="stamp" style={{ fontSize: 8 }}>Hazard · n1</span>
          <span className="mono muted" style={{ fontSize: 10 }}>fail bites −6 Hull</span>
        </div>
      </div>

      {/* condition slim */}
      <div className="row g8" style={{ padding: '0 16px 8px' }}>
        <div className="col grow g4"><div className="row between"><span className="label" style={{ fontSize: 8 }}>Hull</span><span className="mono" style={{ fontSize: 10 }}>16/20</span></div><Meter value={80} segs={8} tone="on" /></div>
        <div className="col grow g4"><div className="row between"><span className="label" style={{ fontSize: 8 }}>Fatigue</span><span className="mono" style={{ fontSize: 10 }}>42</span></div><Meter value={42} segs={8} tone="warn" /></div>
        <div className="col grow g4"><div className="row between"><span className="label" style={{ fontSize: 8 }}>Full</span><span className="mono" style={{ fontSize: 10 }}>50</span></div><Meter value={50} segs={8} tone="ok" /></div>
      </div>

      {/* choices sheet — three solutions */}
      <div className="sheet">
        <div className="handle" />
        <span className="label" style={{ marginBottom: 8, display: 'block' }}>Three ways through</span>
        <div className="col g6">
          <div className="vein" style={{ borderColor: SH_EL.lightning.color }}>
            <div className="glyph" style={{ color: SH_EL.lightning.color }}><img className="drop-white" src={SH_EL.lightning.icon} alt="" /></div>
            <div className="col grow"><span className="nm">Force it · Lightning</span><span className="yield">risky · band [16,36] · <span className="ot" style={{ color: 'var(--stamp-amber)' }}>on-time +12</span></span></div>
            <span className="mono" style={{ fontSize: 12 }}>71%</span>
          </div>
          <div className="vein" style={{ borderColor: 'var(--ink)' }}>
            <div className="glyph" style={{ color: 'var(--ink)' }}>◑</div>
            <div className="col grow"><span className="nm">Finesse the edge</span><span className="yield">sure · costs <b>−3 Hull</b></span></div>
            <span className="mono muted" style={{ fontSize: 12 }}>safe</span>
          </div>
          <div className="vein" style={{ borderColor: 'var(--ink-faded)', opacity: 0.85 }}>
            <div className="glyph" style={{ color: 'var(--ink-faded)' }}>≋</div>
            <div className="col grow"><span className="nm">Wait it down</span><span className="yield">sure · costs <b>−6 Hull</b> · 1 slot</span></div>
            <span className="mono muted" style={{ fontSize: 12 }}>safe</span>
          </div>
        </div>
      </div>
      <TabBar active="expedition" />
    </div>
  );
}

// ======================================================================
// DIRECTION C — "RUN LEDGER"  (denser — matches Card Deck)
// The run as a stacked timeline of node cards with a live ticker; the current
// node expanded with its choices. High-density, log-forward.
// ======================================================================
function RunCard({ glyph, kind, title, meta, state, expanded, children }) {
  const tone = state === 'success' ? 'var(--ok)' : state === 'active' ? 'var(--stamp-amber)' : state === 'recruit' ? 'var(--gold)' : 'var(--ink-faded)';
  return (
    <div className="panel" style={{ borderColor: expanded ? 'var(--stamp-amber)' : 'var(--ink-faded)', borderWidth: expanded ? 2 : 1, padding: '9px 11px', opacity: state === 'idle' ? 0.55 : 1, background: expanded ? 'rgba(244,236,214,0.6)' : 'rgba(244,236,214,0.35)' }}>
      <div className="row g8 aic">
        <div className="xnode" style={{ width: 30, height: 30, fontSize: 14, borderColor: tone, color: kind === 'recruit' || kind === 'terminal' ? 'var(--paper-light)' : tone, background: kind === 'recruit' ? 'var(--ink)' : 'var(--paper-light)', flex: '0 0 30px' }}>{glyph}</div>
        <div className="col grow"><span className="fell" style={{ fontSize: 14 }}>{title}</span><span className="mono muted" style={{ fontSize: 9 }}>{meta}</span></div>
        <span className="label" style={{ fontSize: 7.5, color: tone }}>{state === 'active' ? 'Here' : state}</span>
      </div>
      {expanded && children}
    </div>
  );
}
function ExpDeckC() {
  return (
    <div className="phone sh-m">
      <AndroidStatus />
      <div className="appbar" style={{ paddingBottom: 4 }}>
        <div className="row g6 aic">
          <span className="home" style={{ fontSize: 14 }}>Whispering Strata</span>
          <span className="stamp" style={{ fontSize: 7 }}>Z0</span>
        </div>
        <FieldDial />
      </div>
      <div className="panel panel-pad" style={{ margin: '0 14px 8px' }}>
        <HullRow hull={16} />
      </div>

      <div className="screen-body scrolls" style={{ gap: 7 }}>
        <span className="label" style={{ padding: '0 2px' }}>Run · 4 nodes walked</span>
        <RunCard glyph="⚓" kind="vessel" title="Cast Off" meta="Skyhearth moorings" state="success" />
        <RunCard glyph="⌖" kind="gate" title="Tide-Gate" meta="Earth 12 · held" state="success" />
        <RunCard glyph="✦" kind="recruit" title="Navigator" meta="recruited to the Hearth" state="recruit" />
        <RunCard glyph="❦" kind="forage" title="Kelp-Perch" meta="Nature check · the bloom stirs" state="active" expanded>
          <div className="hairline-dash" style={{ margin: '9px 0' }} />
          <span className="mono muted" style={{ fontSize: 10, lineHeight: 1.5, display: 'block', marginBottom: 8 }}>Work the bloom on the spirit's <b style={{ color: 'var(--el-nature)' }}>Nature</b> — a good draw feeds the larder.</span>
          <div className="row g6">
            <button className="btn-primary grow" style={{ fontSize: 12.5, padding: 9 }}>Forage · 64%</button>
            <button className="btn-ghost" style={{ fontSize: 12.5, padding: 9, flex: '0 0 92px' }}>Move on</button>
          </div>
        </RunCard>
        <RunCard glyph="✶" kind="danger" title="Squall" meta="hazard · guards the gateway" state="idle" />
        <RunCard glyph="◈" kind="terminal" title="Gateway" meta="breadth gate · sealed" state="idle" />

        <div className="panel panel-soft panel-pad" style={{ marginTop: 2 }}>
          <span className="label" style={{ marginBottom: 6, display: 'block' }}>Ticker</span>
          <Telem />
        </div>
      </div>
      <TabBar active="expedition" />
    </div>
  );
}

Object.assign(window, { ExpVerticalA, ExpFocusB, ExpDeckC, Minimap });
