/* THE 137 DESKTOP — interactive finale. Folders are the navigation. */
const { useState, useRef, useEffect } = React;
const _DSX = window.StudioX37DesignSystem_cfd700 || {};
const { Button, Input, Tag, SectionHeader, StatusLamp, Switch } = _DSX;

const FOLDERS = [
  { id: 'works', mark: '⊞', label: 'WORKS' },
  { id: 'projects', mark: '⌬', label: 'PROJECTS' },
  { id: 'paint', mark: '✳', label: 'PAINT.137' },
  { id: 'browser', mark: '◍', label: 'NET' },
  { id: 'manifesto', mark: '◬', label: 'MANIFESTO' },
  { id: 'archive', mark: '▤', label: 'ARCHIVE' },
  { id: 'transmissions', mark: '◉', label: 'TRANSMISSIONS' },
  { id: 'contact', mark: '✉', label: 'CONTACT' },
  { id: 'readme', mark: '✶', label: 'README.137' },
];

const WIN_META = {
  readme:        { title: 'README.137',    idx: '✶', w: 400, h: 250 },
  works:         { title: 'WORKS // DROP A', idx: '01', w: 640, h: 470 },
  projects:      { title: 'PROJECTS // PROC', idx: '⌬', w: 540, h: 430 },
  paint:         { title: 'PAINT.137',     idx: '⬡', w: 600, h: 408 },
  browser:       { title: 'NET // OPEN SIM', idx: '◍', w: 440, h: 322 },
  manifesto:     { title: 'MANIFESTO',     idx: '02', w: 440, h: 330 },
  archive:       { title: 'ARCHIVE',       idx: '03', w: 420, h: 360 },
  transmissions: { title: 'TRANSMISSIONS', idx: '04', w: 440, h: 360 },
  contact:       { title: 'CONTACT',       idx: '05', w: 420, h: 410 },
};

const WORKS = (window.X37_WORKS && window.X37_WORKS.items) || [];
const STORE_URL = (window.X37_WORKS && window.X37_WORKS.store) || '#';
const imgAt = (u, w) => (u ? u + (u.indexOf('?') > -1 ? '&' : '?') + 'width=' + w : u);

const LOG = [
  { code: '037', txt: 'Carrier locked — S 1/37', state: 'live' },
  { code: '112', txt: 'Brass hinge fabricated', state: 'idle' },
  { code: '135', txt: 'Phosphor ignition — warm to green', state: 'live' },
  { code: '136', txt: 'Wall sync — ninety screens wake', state: 'signal' },
  { code: '137', txt: 'Threshold open — step through', state: 'alarm' },
  { code: '138', txt: 'Signal beyond — no return path', state: 'idle' },
];

function clock() {
  const d = new Date();
  const p = (n) => String(n).padStart(2, '0');
  return `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
}

function Win({ meta, z, pos, onFocus, onClose, onMove, children }) {
  const start = useRef(null);
  const onDown = (e) => {
    onFocus();
    start.current = { sx: e.clientX, sy: e.clientY, ox: pos.x, oy: pos.y };
    const move = (ev) => {
      const s = start.current; if (!s) return;
      onMove({ x: Math.max(-40, s.ox + (ev.clientX - s.sx)), y: Math.max(0, s.oy + (ev.clientY - s.sy)) });
    };
    const up = () => { start.current = null; window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };
    window.addEventListener('pointermove', move); window.addEventListener('pointerup', up);
  };
  return (
    <div className="win" style={{ left: pos.x, top: pos.y, width: meta.w, height: meta.h, zIndex: z }} onPointerDown={onFocus}>
      <div className="win-bar" onPointerDown={onDown}>
        <span className="win-title">{meta.idx} · {meta.title}</span>
        <span className="win-actions">
          {StatusLamp ? <StatusLamp state="live" /> : null}
          <button className="win-x" onClick={(e) => { e.stopPropagation(); onClose(); }}>✕</button>
        </span>
      </div>
      <div className="win-body">{children}</div>
    </div>
  );
}

function WorksBody() {
  const [view, setView] = useState('icons'); // 'icons' | 'list'
  const [sel, setSel] = useState(null);      // index into WORKS
  const [liveAvail, setLiveAvail] = useState(null); // {handle: availableForSale} from Storefront API
  const w = sel != null ? WORKS[sel] : null;

  // Live sold-lamps: ask the Storefront API when a token is configured;
  // otherwise (or on any failure) lamps fall back to the baked qty snapshot.
  useEffect(() => {
    const CFG = window.X37_CONFIG || {};
    if (!CFG.shopDomain || !CFG.storefrontToken) return;
    let live = true;
    fetch('https://' + CFG.shopDomain + '/api/' + (CFG.storefrontApiVersion || '2026-04') + '/graphql.json', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-Shopify-Storefront-Access-Token': CFG.storefrontToken },
      body: JSON.stringify({
        query: 'query($q:String!){ products(first: 50, query: $q){ edges { node { handle availableForSale } } } }',
        variables: { q: 'tag:137-studio' },
      }),
    }).then((r) => r.json()).then((j) => {
      if (!live) return;
      const m = {};
      ((((j || {}).data || {}).products || { edges: [] }).edges).forEach((e) => { m[e.node.handle] = e.node.availableForSale; });
      if (Object.keys(m).length) setLiveAvail(m);
    }).catch(() => {});
    return () => { live = false; };
  }, []);

  const handleOf = (x) => ((x.url || '').split('/products/')[1] || '').split('?')[0];
  const avail = (x) => { const h = handleOf(x); return liveAvail && h in liveAvail ? liveAvail[h] : x.qty > 0; };

  if (w) {
    return (
      <div className="wk">
        <div className="wk-head">
          {Button ? <Button variant="secondary" size="sm" onClick={() => setSel(null)}>◀ DROP A</Button> : <button className="chip" onClick={() => setSel(null)}>◀</button>}
          <span className="wk-dmeta">{w.sku} // 1 OF 1</span>
        </div>
        <div className="wk-detail">
          <div className="wk-dimg"><img src={imgAt(w.img, 900)} alt={w.title} /></div>
          <div className="wk-dinfo">
            <div>
              <div className="wk-dtitle">{w.title}</div>
              <div className="wk-dmeta" style={{ marginTop: 6 }}>{w.medium}</div>
            </div>
            <p className="body-copy" style={{ fontSize: 13, margin: 0 }}>{w.desc}</p>
            <div className="wk-davail">
              {StatusLamp ? <StatusLamp state={avail(w) ? 'live' : 'alarm'} blink={avail(w)} label={avail(w) ? 'Available' : 'Sold'} /> : null}
              <span className="wk-dprice">${w.price}</span>
            </div>
            <div className="wk-acts">
              {avail(w) && Button ? <Button variant="primary" onClick={() => window.open(w.checkout, '_blank', 'noopener')}>ACQUIRE →</Button> : null}
              <a className="wk-link" href={w.url} target="_blank" rel="noopener noreferrer">VIEW ON COUNTER ↗</a>
            </div>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="wk">
      <div className="wk-head">
        {SectionHeader ? <SectionHeader label="DROP A // ORIGINALS" index={String(WORKS.length)} /> : null}
        <div className="wk-views">
          <button className={'chip' + (view === 'icons' ? ' on' : '')} onClick={() => setView('icons')}>ICONS</button>
          <button className={'chip' + (view === 'list' ? ' on' : '')} onClick={() => setView('list')}>LIST</button>
        </div>
      </div>

      {view === 'icons' ? (
        <div className="wk-grid">
          {WORKS.map((x, i) => (
            <button className={'wk-tile' + (avail(x) ? '' : ' sold')} key={x.sku} onClick={() => setSel(i)}>
              {x.flagship ? <span className="wk-flag">Flagship</span> : null}
              <span className="wk-thumb"><img src={imgAt(x.img, 320)} alt={x.title} /></span>
              <span className="wk-tile-meta">
                <span className="wk-tile-title">{x.title}</span>
                <span className="wk-price">{avail(x) ? '$' + x.price : 'SOLD'}</span>
              </span>
            </button>
          ))}
        </div>
      ) : (
        <div>
          {WORKS.map((x, i) => (
            <div className="row" key={x.sku} onClick={() => setSel(i)} style={{ cursor: 'pointer' }}>
              <span className="row-idx">{x.ch}</span>
              <span className="row-title">{x.title}</span>
              {Tag ? <Tag tone={avail(x) ? 'acid' : 'magenta'}>{avail(x) ? '$' + x.price : 'SOLD'}</Tag> : <span className="wk-price">${x.price}</span>}
            </div>
          ))}
        </div>
      )}

      <div className="wk-foot">
        <span>ORIGINALS · SIGNED · SHIPS FROM MINNEAPOLIS / TC PICKUP</span>
        <a className="wk-link" href={STORE_URL} target="_blank" rel="noopener noreferrer">FULL CATALOG ↗</a>
      </div>
    </div>
  );
}

function ProjectsBody() {
  const PROJECTS = window.X37_PROJECTS || [];
  const [tick, setTick] = useState(0);
  useEffect(() => { const t = setInterval(() => setTick((n) => n + 1), 900); return () => clearInterval(t); }, []);
  const cpu = (p, i) => {
    const seed = Math.sin((tick + 1) * (i + 3) * 12.9898) * 43758.5453;
    const r = seed - Math.floor(seed);
    if (p.status === 'RUNNING') return (12 + r * 26).toFixed(0);
    if (p.status === 'COMPILING') return (55 + r * 37).toFixed(0);
    return (r * 3).toFixed(0);
  };
  const lampFor = (s) => (s === 'RUNNING' ? 'live' : s === 'COMPILING' ? 'signal' : 'idle');
  return (
    <div>
      {SectionHeader ? <SectionHeader label="RUNNING PROCESSES" index={String(PROJECTS.length)} style={{ marginBottom: 8 }} /> : null}
      <div className="prc-head">
        <span style={{ width: 32 }}>PID</span>
        <span style={{ flex: 1 }}>PROCESS</span>
        <span className="prc-stat" style={{ color: 'inherit' }}>STATE</span>
        <span style={{ width: 40, textAlign: 'right' }}>CPU</span>
      </div>
      {PROJECTS.map((p, i) => (
        <div className="prc-row" key={p.pid}>
          <span className="prc-pid">{p.pid}</span>
          <span className="prc-main">
            <span className="prc-name">{p.name}</span>
            <div className="prc-line">{p.line}</div>
          </span>
          <span className="prc-stat">{StatusLamp ? <StatusLamp state={lampFor(p.status)} blink={p.status !== 'SLEEPING'} /> : null}{p.status}</span>
          <span className="prc-cpu">{cpu(p, i)}%</span>
          {p.url ? <span className="prc-exec"><button className="chip" onClick={() => window.open(p.url, '_blank', 'noopener')}>EXEC ↗</button></span> : null}
        </div>
      ))}
      <p className="body-copy" style={{ fontSize: 12, color: 'var(--x37-bone-faint)', marginTop: 12 }}>Processes without an EXEC handle are compiling behind the wall. They surface when they're ready.</p>
    </div>
  );
}

function ManifestoBody() {
  return (
    <div>
      {SectionHeader ? <SectionHeader label="THE DOOR IS PAINTED OPEN" index="02" style={{ marginBottom: 16 }} /> : null}
      <p className="body-copy">We salvage dead machines and teach them to dream. Each work is an apparatus — paint, signal, and ritual arranged until the room tilts toward a higher dimension.</p>
      <p className="body-copy">We paint the door. The machine opens it. Higher dimensions. Lower fidelity. You are receiving this transmission because the frequency chose you.</p>
    </div>
  );
}

function ArchiveBody() {
  return (
    <div className="log">
      {LOG.map((l, i) => (
        <div className="log-row" key={i}>
          {StatusLamp ? <StatusLamp state={l.state} blink={l.state !== 'idle'} /> : null}
          <span className="log-code">{l.code}</span>
          <span className="log-txt">{l.txt}</span>
        </div>
      ))}
    </div>
  );
}

function TransmissionsBody() {
  return (
    <div>
      <div className="tv-well">
        <video src="assets/loop-transmission.mp4" autoPlay muted loop playsInline></video>
      </div>
      <p className="body-copy" style={{ marginTop: 14 }}>CH 137 // live feed from the shrine. Muted by transmission protocol. The signal loops until the threshold closes.</p>
    </div>
  );
}

function ContactBody() {
  const CFG = window.X37_CONFIG || {};
  const [f, setF] = useState({ call: '', freq: '', msg: '' });
  const [state, setState] = useState('idle'); // idle | sending | sent | mailed | jammed
  const [hint, setHint] = useState('');
  const reset = () => { setState('idle'); setF({ call: '', freq: '', msg: '' }); };

  const transmit = async () => {
    if (!f.freq.trim()) { setHint('NEED A FREQUENCY TO ANSWER ON'); return; }
    if (!f.msg.trim()) { setHint('THE APPARATUS NEEDS A MESSAGE'); return; }
    setHint('');
    if (CFG.transmitUrl) {
      setState('sending');
      try {
        const res = await fetch(CFG.transmitUrl, {
          method: 'POST',
          headers: Object.assign({ 'Content-Type': 'application/json' }, CFG.transmitHeaders || {}),
          body: JSON.stringify({ callsign: f.call, freq: f.freq, msg: f.msg }),
        });
        setState(res.ok ? 'sent' : 'jammed');
      } catch (e) { setState('jammed'); }
    } else {
      const subject = encodeURIComponent('TRANSMISSION // 137 — ' + (f.call || 'unknown callsign'));
      const body = encodeURIComponent('CALLSIGN: ' + f.call + '\r\nFREQUENCY: ' + f.freq + '\r\n\r\n' + f.msg + '\r\n\r\n— sent from the 137 desktop');
      window.location.href = 'mailto:' + (CFG.contactEmail || '') + '?subject=' + subject + '&body=' + body;
      setState('mailed');
    }
  };

  if (state === 'sent' || state === 'mailed') {
    return (
      <div className="contact-sent">
        <div className="sent-mark x37-sigil" title="SENT" aria-hidden="true">TX</div>
        <div className="x37-label" style={{ color: 'var(--x37-acid)', letterSpacing: '.28em' }}>
          {state === 'sent' ? 'SIGNAL TRANSMITTED' : 'CARRIER HANDED OFF'}
        </div>
        <p className="body-copy" style={{ maxWidth: 280 }}>
          {state === 'sent'
            ? 'Your carrier is logged. If the studio answers, it answers on 137.'
            : 'Your mail client is carrying the signal — hit send there and the studio receives it.'}
        </p>
        {state === 'mailed' ? (
          <p className="body-copy" style={{ maxWidth: 280, fontSize: 12, color: 'var(--x37-bone-faint)' }}>
            No mail client opened? Write direct:{' '}
            <a href={'mailto:' + (CFG.contactEmail || '')}>{CFG.contactEmail}</a>
            {CFG.instagram ? <> · <a href={CFG.instagram} target="_blank" rel="noopener noreferrer">{CFG.igHandle || 'Instagram'}</a></> : null}
          </p>
        ) : null}
        {Button ? <Button variant="secondary" size="sm" onClick={reset}>NEW TRANSMISSION</Button> : null}
      </div>
    );
  }

  if (state === 'jammed') {
    return (
      <div className="contact-sent">
        <div className="sent-mark x37-sigil" style={{ color: 'var(--x37-red)', textShadow: 'none' }} title="JAMMED" aria-hidden="true">XX</div>
        <div className="x37-label" style={{ color: 'var(--x37-red)', letterSpacing: '.28em' }}>CHANNEL JAMMED</div>
        <p className="body-copy" style={{ maxWidth: 280 }}>
          The relay refused the carrier. Reach the studio direct:{' '}
          <a href={'mailto:' + (CFG.contactEmail || '')}>{CFG.contactEmail}</a>
          {CFG.instagram ? <> · <a href={CFG.instagram} target="_blank" rel="noopener noreferrer">{CFG.igHandle || 'Instagram'}</a></> : null}
        </p>
        {Button ? <Button variant="secondary" size="sm" onClick={() => setState('idle')}>RETRY</Button> : null}
      </div>
    );
  }

  return (
    <div className="field-stack">
      {Input ? <Input label="Callsign" placeholder="who is transmitting" value={f.call} onChange={(e) => setF({ ...f, call: e.target.value })} /> : null}
      {Input ? <Input label="Frequency / Email" placeholder="where to answer" value={f.freq} onChange={(e) => setF({ ...f, freq: e.target.value })} /> : null}
      {Input ? <Input label="Message" multiline placeholder="speak into the apparatus" value={f.msg} onChange={(e) => setF({ ...f, msg: e.target.value })} /> : null}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
        {StatusLamp ? <StatusLamp state={hint ? 'alarm' : (state === 'sending' ? 'signal' : 'live')} label={hint || (state === 'sending' ? 'Transmitting…' : 'Channel Open')} /> : null}
        {Button ? <Button variant="primary" onClick={transmit} disabled={state === 'sending'}>{state === 'sending' ? 'TRANSMITTING…' : 'TRANSMIT →'}</Button> : null}
      </div>
    </div>
  );
}

function ReadmeBody({ onClose }) {
  return (
    <div>
      <p className="body-copy">You have arrived at the shrine. The apparatus is yours to open — every folder is a channel.</p>
      <p className="body-copy" style={{ color: 'var(--x37-bone-faint)', fontSize: 13 }}>Drag a window by its seam. Turn the wheel upward to rewind the transmission and leave.</p>
      <div style={{ marginTop: 16, display: 'flex', justifyContent: 'flex-end' }}>
        {Button ? <Button variant="secondary" size="sm" onClick={onClose}>UNDERSTOOD</Button> : null}
      </div>
    </div>
  );
}

function PaintBody() {
  const W = 452, H = 220;
  const cvRef = useRef(null);
  const guideRef = useRef(null);
  const st = useRef({ down: false, x: 0, y: 0, sx: 0, sy: 0 });
  const [tool, setTool] = useState('brush');
  const [color, setColor] = useState('#63D98F');
  const [size, setSize] = useState(3);
  const [fold, setFold] = useState(6);
  const [guide, setGuide] = useState(true);
  const toolR = useRef(tool), colorR = useRef(color), sizeR = useRef(size), foldR = useRef(fold);
  toolR.current = tool; colorR.current = color; sizeR.current = size; foldR.current = fold;

  useEffect(() => { const ctx = cvRef.current.getContext('2d'); ctx.fillStyle = '#0A0907'; ctx.fillRect(0, 0, W, H); }, []);
  useEffect(() => { drawGuide(); }, [guide]);

  function drawGuide() {
    const g = guideRef.current; if (!g) return; const ctx = g.getContext('2d');
    ctx.clearRect(0, 0, W, H); if (!guide) return;
    ctx.strokeStyle = 'rgba(232,223,206,0.12)'; ctx.lineWidth = 1;
    const cx = W / 2, cy = H / 2, r = 32, pts = [[0, 0]];
    for (let i = 0; i < 6; i++) pts.push([r * Math.cos(i * Math.PI / 3), r * Math.sin(i * Math.PI / 3)]);
    for (let i = 0; i < 6; i++) { pts.push([2 * r * Math.cos(i * Math.PI / 3), 2 * r * Math.sin(i * Math.PI / 3)]); pts.push([r * Math.sqrt(3) * Math.cos(i * Math.PI / 3 + Math.PI / 6), r * Math.sqrt(3) * Math.sin(i * Math.PI / 3 + Math.PI / 6)]); }
    pts.forEach(([dx, dy]) => { ctx.beginPath(); ctx.arc(cx + dx, cy + dy, r, 0, 7); ctx.stroke(); });
    ctx.beginPath(); ctx.arc(cx, cy, 3 * r, 0, 7); ctx.stroke();
  }
  const sector = (ctx, fn) => {
    const cx = W / 2, cy = H / 2, n = foldR.current;
    for (let i = 0; i < n; i++) for (const m of [1, -1]) { ctx.save(); ctx.translate(cx, cy); ctx.rotate(i * 2 * Math.PI / n); ctx.scale(1, m); ctx.translate(-cx, -cy); fn(ctx); ctx.restore(); }
  };
  const seg = (x0, y0, x1, y1) => {
    const ctx = cvRef.current.getContext('2d'), er = toolR.current === 'eraser';
    ctx.lineCap = 'round'; ctx.lineJoin = 'round';
    ctx.strokeStyle = er ? '#0A0907' : colorR.current; ctx.lineWidth = er ? sizeR.current * 4 : sizeR.current;
    ctx.shadowColor = er ? 'transparent' : colorR.current; ctx.shadowBlur = er ? 0 : Math.min(12, sizeR.current + 2);
    sector(ctx, (c) => { c.beginPath(); c.moveTo(x0, y0); c.lineTo(x1, y1); c.stroke(); });
    ctx.shadowBlur = 0;
  };
  const stamp = (x, y) => {
    const ctx = cvRef.current.getContext('2d'), chs = 'ABCDEFGHJKLMNPRSTVWXYZ✶⌖◬⊗☍';
    const ch = chs[Math.floor(Math.random() * chs.length)];
    ctx.fillStyle = colorR.current; ctx.shadowColor = colorR.current; ctx.shadowBlur = 8;
    ctx.font = (16 + sizeR.current * 5) + "px 'X37 Sigils','Syne',sans-serif"; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
    sector(ctx, (c) => { c.fillText(ch, x, y); }); ctx.shadowBlur = 0;
  };
  const pos = (e) => { const r = cvRef.current.getBoundingClientRect(); return { x: (e.clientX - r.left) * (W / r.width), y: (e.clientY - r.top) * (H / r.height) }; };
  const down = (e) => { e.stopPropagation(); const p = pos(e); st.current = { down: true, x: p.x, y: p.y, sx: p.x, sy: p.y }; if (toolR.current === 'sigil') stamp(p.x, p.y); try { cvRef.current.setPointerCapture(e.pointerId); } catch (z) {} };
  const move = (e) => { if (!st.current.down) return; const p = pos(e); const t = toolR.current; if (t === 'brush' || t === 'eraser') { seg(st.current.x, st.current.y, p.x, p.y); st.current.x = p.x; st.current.y = p.y; } };
  const up = (e) => { if (toolR.current === 'line' && st.current.down) { const p = pos(e); seg(st.current.sx, st.current.sy, p.x, p.y); } st.current.down = false; };
  const clear = () => { const ctx = cvRef.current.getContext('2d'); ctx.fillStyle = '#0A0907'; ctx.fillRect(0, 0, W, H); };

  const TOOLS = [{ id: 'brush', g: '✎' }, { id: 'line', g: '／' }, { id: 'sigil', g: '✶' }, { id: 'eraser', g: '▨' }];
  const PALETTE = ['#E8DFCE', '#63D98F', '#8FFFBE', '#FF2E7E', '#DF7A1F', '#36B9A2', '#D8331F', '#A89E8B'];

  return (
    <div className="paint">
      <div className="paint-menu">
        <span className="pm-lbl" style={{ color: 'var(--x37-acid)' }}>◬ SACRED GEOMETRY</span>
        <div className="pm-grp"><span className="pm-lbl">FOLD</span>{[1, 2, 3, 4, 6, 8, 12].map((n) => (<button key={n} className={'chip' + (fold === n ? ' on' : '')} onClick={() => setFold(n)}>{n}</button>))}</div>
        <div className="pm-grp"><span className="pm-lbl">SIZE</span>{[1, 3, 6, 10].map((n) => (<button key={n} className={'chip' + (size === n ? ' on' : '')} onClick={() => setSize(n)}>{n}</button>))}</div>
        {Switch ? <Switch checked={guide} onChange={setGuide} label="GUIDE" /> : null}
        {Button ? <Button size="sm" variant="secondary" onClick={clear}>CLEAR</Button> : null}
      </div>
      <div className="paint-main">
        <div className="paint-tools">{TOOLS.map((t) => (<button key={t.id} className={'tool' + (tool === t.id ? ' on' : '')} onClick={() => setTool(t.id)} title={t.id}>{t.g}</button>))}</div>
        <div className="paint-stage">
          <canvas ref={cvRef} className="paint-cv" width={W} height={H} onPointerDown={down} onPointerMove={move} onPointerUp={up}></canvas>
          <canvas ref={guideRef} className="paint-guide" width={W} height={H}></canvas>
        </div>
      </div>
      <div className="paint-palette">
        {PALETTE.map((c) => (<button key={c} className={'sw' + (color === c ? ' on' : '')} style={{ background: c }} onClick={() => setColor(c)}></button>))}
      </div>
    </div>
  );
}

function BrowserBody() {
  const url = 'https://websim.com';
  return (
    <div className="brz">
      <div className="brz-bar">
        <span className="brz-dots"><i></i><i></i><i></i></span>
        <a className="brz-url" href={url} target="_blank" rel="noopener noreferrer">{url}</a>
        <a className="brz-go" href={url} target="_blank" rel="noopener noreferrer" title="open">↗</a>
      </div>
      <div className="brz-body">
        <div className="brz-sig" title="OPEN SIM" aria-hidden="true">NET</div>
        <p className="body-copy" style={{ maxWidth: 300 }}>External transmission. This channel routes off the 137 network — out into the open simulation.</p>
        {Button ? <Button variant="primary" onClick={() => window.open(url, '_blank', 'noopener')}>OPEN WEBSIM ↗</Button> : null}
        <p className="body-copy" style={{ color: 'var(--x37-bone-faint)', fontSize: 12, maxWidth: 300 }}>Type anything into the address bar of the universe. We only point the way.</p>
      </div>
    </div>
  );
}

function bodyFor(id, api) {
  if (id === 'works') return <WorksBody />;
  if (id === 'projects') return <ProjectsBody />;
  if (id === 'paint') return <PaintBody />;
  if (id === 'browser') return <BrowserBody />;
  if (id === 'manifesto') return <ManifestoBody />;
  if (id === 'archive') return <ArchiveBody />;
  if (id === 'transmissions') return <TransmissionsBody />;
  if (id === 'contact') return <ContactBody />;
  if (id === 'readme') return <ReadmeBody onClose={() => api.close('readme')} />;
  return null;
}

function Desktop137({ active, onExit }) {
  const [wins, setWins] = useState([]); // {id, x, y}
  const [ztop, setZtop] = useState(34); // icons sit at z 32, chrome at 40 — windows live between
  const [now, setNow] = useState(clock());
  const opened = useRef(false);

  useEffect(() => { const t = setInterval(() => setNow(clock()), 1000); return () => clearInterval(t); }, []);

  // auto-open README the first time we arrive
  useEffect(() => {
    if (active && !opened.current) { opened.current = true; setTimeout(() => open('readme'), 700); }
  }, [active]);

  // lock the page scroll while a window is open so wheeling doesn't rewind mid-read
  useEffect(() => {
    if (window.__x37Lock) window.__x37Lock(active && wins.length > 0);
  }, [wins, active]);

  const open = (id) => {
    setZtop((z) => z + 1);
    setWins((cur) => {
      if (cur.find((w) => w.id === id)) return cur.map((w) => (w.id === id ? { ...w, z: ztop + 1 } : w));
      const n = cur.length;
      const meta = WIN_META[id];
      const vw = window.innerWidth, vh = window.innerHeight;
      const insetX = vw * 0.022, insetY = vh * 0.024;
      const uTop = insetY + 40 + 8, uBottom = vh - insetY - 44 - 8;
      const uLeft = insetX + 8, uRight = vw - insetX - 8;
      const seedX = (id === 'readme' ? 300 : (id === 'paint' ? 84 : 150)) + n * 34;
      const seedY = uTop + 6 + n * 26;
      const x = Math.max(uLeft, Math.min(seedX, Math.max(uLeft, uRight - meta.w)));
      const y = Math.max(uTop, Math.min(seedY, Math.max(uTop, uBottom - meta.h)));
      return [...cur, { id, x, y, z: ztop + 1 }];
    });
  };
  const close = (id) => setWins((cur) => cur.filter((w) => w.id !== id));
  const focus = (id) => { setZtop((z) => z + 1); setWins((cur) => cur.map((w) => (w.id === id ? { ...w, z: ztop + 1 } : w))); };
  const move = (id, pos) => setWins((cur) => cur.map((w) => (w.id === id ? { ...w, x: pos.x, y: pos.y } : w)));
  const api = { open, close };

  return (
    <div className="desk-inner">
      <div className="desk-bg"></div>
      <div className="desk-wash"></div>

      <div className="menubar">
        <div className="mb-left">
          <span className="lamp"></span>
          <span className="mb-name">STUDIO X37 OS</span>
          <span className="mb-sig" aria-hidden="true">X37</span>
        </div>
        <div className="mb-mid">// THE 137 DESKTOP</div>
        <div className="mb-right">
          <span className="mb-sys">SYS NOMINAL</span>
          <span className="mb-clock">{now}</span>
        </div>
      </div>

      <div className="icons">
        {FOLDERS.map((f) => (
          <div className="folder" key={f.id} onDoubleClick={() => open(f.id)} onClick={() => { if (window.matchMedia && window.matchMedia('(pointer:coarse)').matches) open(f.id); }} title={`Open ${f.label}`}>
            <div className="folder-ico"><span>{f.mark}</span></div>
            <div className="folder-lbl">{f.label}</div>
          </div>
        ))}
      </div>

      {wins.map((w) => (
        <Win key={w.id} meta={WIN_META[w.id]} z={w.z} pos={{ x: w.x, y: w.y }}
          onFocus={() => focus(w.id)} onClose={() => close(w.id)} onMove={(p) => move(w.id, p)}>
          {bodyFor(w.id, api)}
        </Win>
      ))}

      <div className="dock">
        <div className="dock-left">
          {wins.length === 0
            ? <span className="dock-chip" style={{ cursor: 'default', borderColor: 'transparent' }}>◉ 137 ONLINE — DOUBLE-CLICK A FOLDER</span>
            : wins.map((w) => <span className="dock-chip" key={w.id} onClick={() => focus(w.id)}>{WIN_META[w.id].title}</span>)}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, flex: 'none' }}>
          <button className="dock-rewind" onClick={onExit}>▲ REWIND TRANSMISSION</button>
          <span className="dock-clock">CH 137</span>
        </div>
      </div>

      <div className="desk-scan"></div>
    </div>
  );
}

window.X37Desktop = Desktop137;
