// XphrTerminalShowcase.jsx — drop-in block for sciphr-site /xphr.
// A compact, live-feeling preview of the XPHR v2 light terminal: candle chart,
// domain order book, and the WYSIWYS ticket with the quote locked.
// Depends only on: SP_COL, SP_MONO_W, SectionEyebrow, XphrButton, SP_LINKS.
// Load AFTER XphrBlocks.jsx in xphr.html, render inside XphrPage.
//
// Design source: SciPHR Design System project → ui_kits/xphr/XPHR Terminal v2.html

const TS_AMBER_INK = '#7A5800'; // amber text on white needs this for contrast

// ── light-surface dotted row ────────────────────────────────────────────────
function TSRow({ k, v, accent = false, strong = false, muted = false }) {
  return (
    <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, fontFamily: SP_MONO_W, fontSize: 11, lineHeight: 1.5 }}>
      <span style={{ color: '#808080', textTransform: 'uppercase', letterSpacing: '0.12em', fontSize: 9, fontWeight: 700, whiteSpace: 'nowrap' }}>{k}</span>
      <span aria-hidden="true" style={{ flex: 1, borderBottom: '1px dotted #C0C0C0', transform: 'translateY(-3px)', minWidth: 10 }} />
      <span style={{
        color: muted ? '#C0C0C0' : accent ? TS_AMBER_INK : '#000',
        fontWeight: strong ? 700 : 600, whiteSpace: 'nowrap', textAlign: 'right',
      }}>{v}</span>
    </div>
  );
}

// ── mini candle chart, canvas ───────────────────────────────────────────────
function tsCandles(n = 56) {
  let s = 7;
  const rnd = () => { s = (s * 16807) % 2147483647; return s / 2147483647; };
  const out = [];
  let px = 2.131;
  for (let i = 0; i < n; i++) {
    const o = px, c = Math.max(2.05, o + (rnd() - 0.47) * 0.012);
    out.push({ o, c, h: Math.max(o, c) + rnd() * 0.005, l: Math.min(o, c) - rnd() * 0.005, v: 4000 + rnd() * 26000 });
    px = c;
  }
  out[n - 1].c = 2.1842;
  out[n - 1].h = Math.max(out[n - 1].h, 2.1842);
  return out;
}

function TSChart({ height = 230 }) {
  const wrapRef = React.useRef(null);
  const canvasRef = React.useRef(null);
  const [width, setWidth] = React.useState(420);
  React.useEffect(() => {
    const el = wrapRef.current;
    if (!el) return;
    const ro = new ResizeObserver(() => setWidth(Math.max(120, el.clientWidth)));
    ro.observe(el);
    setWidth(Math.max(120, el.clientWidth));
    return () => ro.disconnect();
  }, []);
  React.useEffect(() => {
    const cv = canvasRef.current;
    if (!cv) return;
    const candles = tsCandles();
    const dpr = window.devicePixelRatio || 1;
    cv.width = width * dpr; cv.height = height * dpr;
    const ctx = cv.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, width, height);
    ctx.font = '8px Menlo, monospace';
    const AXIS_W = 44, VOL_H = 34;
    const plotW = width - AXIS_W, plotH = height - VOL_H - 12;
    const lo = Math.min(...candles.map(c => c.l)), hi = Math.max(...candles.map(c => c.h));
    const pad = (hi - lo) * 0.08;
    const yOf = p => 6 + (1 - (p - (lo - pad)) / ((hi + pad) - (lo - pad))) * plotH;
    const step = plotW / candles.length;
    const maxV = Math.max(...candles.map(c => c.v));
    for (let g = 0; g <= 4; g++) {
      const p = (lo - pad) + ((hi + pad) - (lo - pad)) * (g / 4);
      ctx.strokeStyle = '#EEEEEE';
      ctx.beginPath(); ctx.moveTo(0, yOf(p)); ctx.lineTo(plotW, yOf(p)); ctx.stroke();
      ctx.fillStyle = '#808080';
      ctx.fillText(p.toFixed(3), plotW + 5, yOf(p) + 3);
    }
    const bw = Math.max(2, step * 0.55);
    candles.forEach((c, i) => {
      const x = i * step + step / 2, up = c.c >= c.o;
      ctx.strokeStyle = '#000';
      ctx.beginPath(); ctx.moveTo(x, yOf(c.h)); ctx.lineTo(x, yOf(c.l)); ctx.stroke();
      const yT = yOf(Math.max(c.o, c.c)), h = Math.max(1, yOf(Math.min(c.o, c.c)) - yT);
      if (up) { ctx.fillStyle = '#FFF'; ctx.fillRect(x - bw / 2, yT, bw, h); ctx.strokeRect(x - bw / 2 + 0.5, yT + 0.5, bw - 1, Math.max(1, h - 1)); }
      else { ctx.fillStyle = '#000'; ctx.fillRect(x - bw / 2, yT, bw, h); }
      const vh = (c.v / maxV) * (VOL_H - 6);
      ctx.fillStyle = up ? '#E0E0E0' : '#C0C0C0';
      ctx.fillRect(x - bw / 2, height - vh, bw, vh);
    });
    const last = candles[candles.length - 1].c, yl = yOf(last);
    ctx.strokeStyle = '#FFB800'; ctx.setLineDash([4, 3]);
    ctx.beginPath(); ctx.moveTo(0, yl); ctx.lineTo(plotW, yl); ctx.stroke();
    ctx.setLineDash([]);
    ctx.fillStyle = '#000'; ctx.fillRect(plotW, yl - 7, AXIS_W, 14);
    ctx.fillStyle = '#FFB800'; ctx.fillText(last.toFixed(4), plotW + 5, yl + 3);
  }, [width, height]);
  return (
    <div ref={wrapRef} style={{ width: '100%' }}>
      <canvas ref={canvasRef} style={{ width: '100%', height, display: 'block' }}></canvas>
    </div>
  );
}

// ── mini domain book ────────────────────────────────────────────────────────
const TS_BOOK = {
  asks: [['2.1879', '12,400'], ['2.1866', '8,210'], ['2.1858', '22,050'], ['2.1851', '5,300'], ['2.1846', '15,990']],
  bids: [['2.1833', '18,330'], ['2.1821', '9,400'], ['2.1808', '31,200'], ['2.1794', '7,150'], ['2.1788', '12,080']],
};

function TSBook() {
  const max = 31200;
  const row = ([px, sz], side, i) => (
    <div key={side + i} style={{ position: 'relative', display: 'flex', justifyContent: 'space-between', padding: '2px 10px', fontFamily: SP_MONO_W, fontSize: 10 }}>
      <span style={{
        position: 'absolute', top: 1, bottom: 1, right: 0,
        width: `${(parseInt(sz.replace(/,/g, ''), 10) / max) * 100}%`,
        background: side === 'ask' ? 'rgba(0,0,0,0.06)' : 'rgba(255,184,0,0.18)',
      }} />
      <span style={{ position: 'relative', color: side === 'ask' ? '#404040' : '#000', fontWeight: side === 'ask' ? 400 : 700 }}>{px}</span>
      <span style={{ position: 'relative', color: '#404040' }}>{sz}</span>
    </div>
  );
  return (
    <div style={{ display: 'flex', flexDirection: 'column', borderLeft: '1px solid #C0C0C0', minWidth: 0 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '6px 10px', borderBottom: '1px solid #E0E0E0', fontFamily: SP_MONO_W, fontSize: 8, letterSpacing: '0.18em', color: '#808080' }}>
        <span>DOMAIN BOOK</span><span>SIZE XRP</span>
      </div>
      <div style={{ padding: '4px 0' }}>{TS_BOOK.asks.map((r, i) => row(r, 'ask', i))}</div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', padding: '4px 10px', borderTop: '1px solid #000', borderBottom: '1px solid #000', background: 'rgba(255,184,0,0.12)' }}>
        <span style={{ fontFamily: SP_MONO_W, fontSize: 12, fontWeight: 700, color: '#000' }}>2.1842</span>
        <span style={{ fontFamily: SP_MONO_W, fontSize: 8, letterSpacing: '0.12em', color: '#404040' }}>SPREAD 6.0 BPS</span>
      </div>
      <div style={{ padding: '4px 0' }}>{TS_BOOK.bids.map((r, i) => row(r, 'bid', i))}</div>
      <div style={{ marginTop: 'auto', padding: '5px 10px', borderTop: '1px solid #E0E0E0', fontFamily: SP_MONO_W, fontSize: 7.5, letterSpacing: '0.14em', color: '#808080' }}>
        DOMAIN 100% · BOOK + AMM
      </div>
    </div>
  );
}

// ── mini ticket, quote locked, looping TTL ──────────────────────────────────
function TSTicket() {
  const [ttl, setTtl] = React.useState(12);
  React.useEffect(() => {
    const id = setInterval(() => setTtl(t => (t <= 1 ? 12 : t - 1)), 1000);
    return () => clearInterval(id);
  }, []);
  return (
    <div style={{ borderLeft: '1px solid #C0C0C0', padding: 10, display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
      <div style={{ border: '2px solid #000', padding: '6px 10px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: SP_MONO_W, fontSize: 8, letterSpacing: '0.2em', color: '#808080' }}>
          <span>SELL</span><span>MAX</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginTop: 2 }}>
          <span style={{ fontFamily: SP_MONO_W, fontSize: 17, fontWeight: 700, color: '#000' }}>500.00</span>
          <span style={{ fontFamily: SP_MONO_W, fontSize: 10, fontWeight: 700, letterSpacing: '0.12em', color: '#404040' }}>XRP</span>
        </div>
      </div>
      <div style={{ border: '1px solid #C0C0C0' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', padding: '5px 10px', borderBottom: '1px solid #E0E0E0' }}>
          <span style={{ fontFamily: SP_MONO_W, fontSize: 7.5, fontWeight: 700, letterSpacing: '0.2em', color: '#808080' }}>WYSIWYS</span>
          <span style={{ fontFamily: SP_MONO_W, fontSize: 8.5, fontWeight: 700, color: ttl <= 4 ? '#FF0000' : TS_AMBER_INK }}>LOCKED · {String(ttl).padStart(2, '0')}S</span>
        </div>
        <div style={{ padding: '8px 10px', display: 'flex', flexDirection: 'column', gap: 5 }}>
          <TSRow k="RATE" v="2.1842 RLUSD" />
          <TSRow k="ROUTE" v="DOMAIN 100%" accent strong />
          <TSRow k="FEE 0.20%" v="1.00 XRP" />
          <TSRow k="SPREAD MARKUP" v="NONE" strong />
          <TSRow k="NETWORK" v="TESTNET" accent strong />
        </div>
        <div style={{ margin: '0 10px 10px', padding: '6px 8px', border: '2px solid #000', boxShadow: '2px 2px 0 0 #000' }}>
          <TSRow k="RECEIVE" v="1,089.92 RLUSD" strong />
        </div>
      </div>
      <div style={{
        fontFamily: SP_MONO_W, fontSize: 9.5, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase',
        textAlign: 'center', padding: '10px 0', background: '#FFB800', color: '#000',
        border: '2px solid #000', boxShadow: '2px 2px 0 0 #000',
      }}>SIGN IN YOUR WALLET</div>
      <span style={{ fontFamily: SP_MONO_W, fontSize: 7, letterSpacing: '0.14em', color: '#808080', textTransform: 'uppercase', lineHeight: 1.6 }}>
        SIGNING DISABLED WHILE QUOTING. STALE QUOTES NEVER SIGN.
      </span>
    </div>
  );
}

// ── the terminal mock, white card on the dark site ──────────────────────────
function TSTerminalMock() {
  const [ledger, setLedger] = React.useState(94118267);
  React.useEffect(() => {
    const id = setInterval(() => setLedger(l => l + 1), 3900);
    return () => clearInterval(id);
  }, []);
  return (
    <div style={{
      background: '#FFF', color: '#000',
      border: `2px solid ${SP_COL.white}`, borderRightWidth: 3, borderBottomWidth: 3,
      boxShadow: `4px 4px 0 0 ${SP_COL.grayDark}`, overflow: 'hidden',
    }}>
      {/* header strip */}
      <div style={{ background: '#000', color: '#FFF', display: 'flex', alignItems: 'center', gap: 10, padding: '9px 12px', flexWrap: 'wrap' }}>
        <span style={{ fontFamily: SP_MONO_W, fontSize: 11, fontWeight: 700, letterSpacing: '0.3em' }}>XPHR</span>
        <span style={{ fontFamily: SP_MONO_W, fontSize: 10, color: '#C0C0C0', letterSpacing: '0.08em' }}>XRP / RLUSD</span>
        <span style={{ fontFamily: SP_MONO_W, fontSize: 8, fontWeight: 700, letterSpacing: '0.2em', background: '#FFB800', color: '#000', padding: '2px 6px' }}>TESTNET</span>
        <span style={{ flex: 1 }} />
        <span className="sp-xphr-term-hide-sm" style={{ fontFamily: SP_MONO_W, fontSize: 8, letterSpacing: '0.15em', color: '#FFB800', border: '1px solid rgba(255,184,0,0.6)', padding: '2px 6px' }}>
          DOMAIN: XPHR · CREDENTIAL: ACTIVE
        </span>
        <span className="sp-xphr-term-hide-sm" style={{ fontFamily: SP_MONO_W, fontSize: 8.5, letterSpacing: '0.1em', color: '#808080' }}>
          LEDGER <span style={{ color: '#FFB800' }}>{ledger.toLocaleString('en-US')}</span>
        </span>
      </div>
      {/* body */}
      <div className="sp-xphr-term-grid" style={{ display: 'grid', gridTemplateColumns: 'minmax(0,1fr) 188px 256px' }}>
        <div style={{ minWidth: 0, padding: '8px 0 0 4px' }}>
          <div style={{ display: 'flex', gap: 10, padding: '0 10px 6px', fontFamily: SP_MONO_W, fontSize: 8.5, color: '#808080', letterSpacing: '0.08em' }}>
            <span style={{ color: '#000', fontWeight: 700 }}>XRP / RLUSD · 1H</span>
            <span>O 2.2672 H 2.2683 L 2.2615 C 2.1842</span>
            <span style={{ color: TS_AMBER_INK, fontWeight: 700 }}>+2.50%</span>
          </div>
          <TSChart height={236} />
        </div>
        <TSBook />
        <TSTicket />
      </div>
      {/* footer strip */}
      <div style={{ borderTop: '2px solid #000', display: 'flex', gap: 18, padding: '6px 12px', overflow: 'hidden' }}>
        {['QUOTE ROUTE = EXECUTION ROUTE', 'SPREAD MARKUP: NONE', 'KEYS NEVER LEAVE YOUR DEVICE'].map(t => (
          <span key={t} style={{ fontFamily: SP_MONO_W, fontSize: 8, letterSpacing: '0.15em', color: '#808080', whiteSpace: 'nowrap' }}>{t}</span>
        ))}
        <span style={{ flex: 1 }} />
        <span style={{ fontFamily: SP_MONO_W, fontSize: 8, letterSpacing: '0.2em', color: TS_AMBER_INK, fontWeight: 700 }}>TESTNET</span>
      </div>
    </div>
  );
}

// ── the section ─────────────────────────────────────────────────────────────
function XphrTerminalShowcase({ index = 2 }) {
  const highlights = [
    ['Two doors in', 'Link an existing xCIPHR identity, or create one in four steps. The first three steps can never cost money.'],
    ['Five states, one contract', 'Quoting, confirmed, signing, executed, receipt. Signing is disabled while a quote resolves, and stale quotes never sign.'],
    ['An honest book', 'Quotes fill against the permissioned order book and a domain-restricted AMM, whichever is better at your size. The depth shown is the depth that exists, so an empty testnet book renders as 0 offers, not padded.'],
  ];
  return (
    <section id="terminal" data-screen-label="XPHR terminal showcase" style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
      <SectionEyebrow index={index} label="Terminal preview" />
      <div>
        <h2 style={{ margin: '0 0 12px 0', fontFamily: SP_MONO_W, fontSize: 'clamp(26px, 3vw, 38px)', lineHeight: 1.15, color: SP_COL.white }}>
          The terminal, as it ships.
        </h2>
        <p style={{ margin: 0, maxWidth: 720, fontFamily: SP_MONO_W, fontSize: 14, lineHeight: 1.65, color: SP_COL.grayLight }}>
          Chart, domain order book, and the WYSIWYS ticket, all visible at once.
          What you see below is the live quote contract: rate, route, fee in both
          assets, and the 12-second lock, exactly as it renders before you sign.
        </p>
      </div>
      <TSTerminalMock />
      <div className="sp-xphr-grid-4" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 18 }}>
        {highlights.map(([t, d]) => (
          <div key={t} style={{ border: `1px solid ${SP_COL.grayDark}`, borderRadius: 4, background: SP_COL.black, padding: '14px 16px', display: 'flex', flexDirection: 'column', gap: 8 }}>
            <span style={{ fontFamily: SP_MONO_W, fontSize: 12, fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: SP_COL.white }}>{t}</span>
            <p style={{ margin: 0, fontFamily: SP_MONO_W, fontSize: 12, lineHeight: 1.6, color: SP_COL.grayLight }}>{d}</p>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
        <XphrButton label="Request early access" href="#access" />
        <XphrButton label="How it works" href="#how" secondary />
      </div>
    </section>
  );
}

Object.assign(window, { XphrTerminalShowcase, TSTerminalMock });
