// vx-shared.jsx — shared tokens + components for all vx landing directions.
// Exports to window at the bottom (separate babel scopes don't share scope).

const VXP = {
  ink: '#161618',      // darkest
  ink900: '#1b1b1e',
  ink850: '#212125',
  ink800: '#27272c',   // panels
  ink750: '#2e2e33',   // site theme color
  line: 'rgba(255,255,255,0.09)',
  line2: 'rgba(255,255,255,0.16)',
  text: '#ECEAE6',
  mute: '#9c9ba2',
  faint: '#6c6b72',
  blue: '#6f9fe8',
  blueBright: '#8fb6f2',
  blueDim: 'rgba(111,159,232,0.14)',
  coral: '#e8825f',
  coralDim: 'rgba(232,130,95,0.16)',
  green: '#5fb98e',
  display: '"Space Grotesk", "Helvetica Neue", system-ui, sans-serif',
  mono: '"JetBrains Mono", ui-monospace, "SF Mono", monospace',
  poster: '"Bricolage Grotesque", "Space Grotesk", system-ui, sans-serif',
  body: '"Space Grotesk", "Helvetica Neue", system-ui, sans-serif',
};

// ── Pixel mascot ───────────────────────────────────────────────
// Original little ghost/critter rendered from a char-map of squares.
// '#' = body, 'o' = eye (transparent), '.' = empty.
const VX_CRITTER = [
  '..######..',
  '.########.',
  '########..',  // antenna nub handled separately if needed
  '#oo##oo###',
  '#oo##oo###',
  '##########',
  '##########',
  '####..####',
  '###.##.###',
  '##.####.##',
];

function PixelMascot({ px = 6, color = VXP.coral, eye = VXP.ink, blink = true, style = {} }) {
  const rows = VX_CRITTER;
  const w = rows[0].length, h = rows.length;
  const [closed, setClosed] = React.useState(false);
  React.useEffect(() => {
    if (!blink) return;
    let t;
    const loop = () => {
      t = setTimeout(() => {
        setClosed(true);
        setTimeout(() => setClosed(false), 130);
        loop();
      }, 2200 + Math.random() * 2600);
    };
    loop();
    return () => clearTimeout(t);
  }, [blink]);
  const cells = [];
  for (let y = 0; y < h; y++) {
    for (let x = 0; x < w; x++) {
      const c = rows[y][x];
      if (c === '.') continue;
      const isEye = c === 'o';
      cells.push(
        React.createElement('div', {
          key: y + '-' + x,
          style: {
            gridColumn: x + 1, gridRow: y + 1,
            background: isEye ? (closed ? color : 'transparent') : color,
            borderRadius: 1,
          },
        })
      );
    }
  }
  return React.createElement('div', {
    style: {
      display: 'grid',
      gridTemplateColumns: `repeat(${w}, ${px}px)`,
      gridTemplateRows: `repeat(${h}, ${px}px)`,
      gap: 0, ...style,
    },
  }, cells);
}

// ── Inline copy helpers ────────────────────────────────────────
// Let copy strings carry emphasis/code cleanly (see copy.jsx).
function S({ children }) { return <span style={{ color: VXP.text }}>{children}</span>; }       // emphasis
function C({ children }) { return <code style={{ fontFamily: VXP.mono, color: VXP.text }}>{children}</code>; } // inline code

// ── Minimal line icons ─────────────────────────────────────────
function Icon({ name, size = 20, stroke = 'currentColor', sw = 1.7 }) {
  const common = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke, strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const paths = {
    lock: <><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></>,
    bolt: <path d="M13 3 5 13h6l-1 8 8-12h-6z"/>,
    feather: <><path d="M20 4a6 6 0 0 0-9 1L5 11v8h8l6-6a6 6 0 0 0 1-9Z"/><path d="M5 19 14 10"/></>,
    chip: <><rect x="6" y="6" width="12" height="12" rx="2"/><path d="M9 2v3M15 2v3M9 19v3M15 19v3M2 9h3M2 15h3M19 9h3M19 15h3"/></>,
    cloudOff: <><path d="m3 3 18 18"/><path d="M8.5 7A5 5 0 0 1 18 9a3.5 3.5 0 0 1 1.5 6.6"/><path d="M16 16H7a4 4 0 0 1-.9-7.9"/></>,
    mic: <><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M6 11a6 6 0 0 0 12 0M12 17v4"/></>,
    cursor: <><path d="M5 3l5 16 2.5-6.5L19 10z"/></>,
    github: <path d="M9 19c-4 1.5-4-2.5-6-3m12 5v-3.5c0-1 .1-1.4-.5-2 2.8-.3 5.5-1.4 5.5-6a4.6 4.6 0 0 0-1.3-3.2 4.3 4.3 0 0 0-.1-3.2s-1-.3-3.4 1.3a11.5 11.5 0 0 0-6 0C7.3 2.3 6.3 2.6 6.3 2.6a4.3 4.3 0 0 0-.1 3.2A4.6 4.6 0 0 0 5 9c0 4.6 2.7 5.7 5.5 6-.4.4-.5.9-.5 1.8V21"/>,
    download: <><path d="M12 3v12M7 11l5 5 5-5"/><path d="M4 21h16"/></>,
    arrow: <path d="M5 12h14M13 6l6 6-6 6"/>,
    check: <path d="M5 12.5 10 17 19 7"/>,
    yaml: <><path d="M4 5h16v14H4z"/><path d="M8 9l2 2 2-2M10 11v3"/></>,
  };
  return <svg {...common}>{paths[name]}</svg>;
}

// ── Animated waveform bars ─────────────────────────────────────
function Waveform({ bars = 11, color = VXP.green, active = true, h = 22, w = 5, gap = 3 }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap, height: h }}>
      {Array.from({ length: bars }).map((_, i) => (
        <div key={i} style={{
          width: w, borderRadius: w, background: active ? color : 'rgba(255,255,255,0.18)',
          animation: active ? `vxwave 0.9s ease-in-out ${(i * 0.08).toFixed(2)}s infinite` : 'none',
          height: active ? '40%' : '30%',
          transformOrigin: 'center',
        }} />
      ))}
    </div>
  );
}

// ── Recording pill (mirrors the app's floating tooltip) ────────
function RecordPill({ label = 'Recording', dark = true, scale = 1 }) {
  return (
    <div style={{
      display: 'inline-flex', flexDirection: 'column', alignItems: 'center', gap: 8 * scale,
    }}>
      <div style={{
        display: 'inline-flex', alignItems: 'center', gap: 12 * scale,
        background: '#3a3a40', borderRadius: 999, padding: `${9 * scale}px ${10 * scale}px`,
        boxShadow: '0 8px 24px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(255,255,255,0.06)',
      }}>
        <div style={{
          width: 26 * scale, height: 26 * scale, borderRadius: 999, background: 'rgba(255,255,255,0.1)',
          display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#cfcfd4', fontSize: 13 * scale,
        }}>✕</div>
        <Waveform bars={10} h={20 * scale} w={4.5 * scale} gap={2.5 * scale} />
        <div style={{
          width: 26 * scale, height: 26 * scale, borderRadius: 999, background: '#ec5b4d',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <div style={{ width: 9 * scale, height: 9 * scale, borderRadius: 2, background: '#fff' }} />
        </div>
      </div>
      {label && (
        <div style={{
          fontFamily: VXP.body, fontSize: 12 * scale, color: '#b9b9bf', background: 'rgba(0,0,0,0.35)',
          padding: `${3 * scale}px ${10 * scale}px`, borderRadius: 999,
        }}>{label}</div>
      )}
    </div>
  );
}

// ── Typing hook: cycles through phrases, typing then pausing ───
function useTyping(phrases, { speed = 46, hold = 1500, erase = 22 } = {}) {
  const [idx, setIdx] = React.useState(0);
  const [text, setText] = React.useState('');
  const [phase, setPhase] = React.useState('type'); // type | hold | erase
  React.useEffect(() => {
    const target = phrases[idx];
    let t;
    if (phase === 'type') {
      if (text.length < target.length) t = setTimeout(() => setText(target.slice(0, text.length + 1)), speed);
      else t = setTimeout(() => setPhase('hold'), 60);
    } else if (phase === 'hold') {
      t = setTimeout(() => setPhase('erase'), hold);
    } else {
      if (text.length > 0) t = setTimeout(() => setText(target.slice(0, text.length - 1)), erase);
      else { setIdx((i) => (i + 1) % phrases.length); setPhase('type'); }
    }
    return () => clearTimeout(t);
  }, [text, phase, idx, phrases, speed, hold, erase]);
  return { text, active: phase !== 'hold' };
}

// ── Dictation demo: faux text field + the spoken rewrite + pill ─
// Shows speech ("brb in 5") becoming written output, demonstrating rules.
function DictationDemo({ width = 560 }) {
  const phrases = [
    'kubectl get pods, then brb',
    'be right back in five minutes',
    'fix up the grammar and ship it',
  ];
  const { text, active } = useTyping(phrases, { speed: 42, hold: 1700 });
  return (
    <div style={{
      width, maxWidth: '100%', background: VXP.ink850, borderRadius: 14,
      border: `1px solid ${VXP.line}`, boxShadow: '0 30px 80px rgba(0,0,0,0.5)',
      overflow: 'hidden', fontFamily: VXP.body,
    }}>
      {/* window chrome */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 7, padding: '12px 16px', borderBottom: `1px solid ${VXP.line}` }}>
        <span style={{ width: 11, height: 11, borderRadius: 99, background: '#ec6a5e' }} />
        <span style={{ width: 11, height: 11, borderRadius: 99, background: '#f4bf4f' }} />
        <span style={{ width: 11, height: 11, borderRadius: 99, background: '#61c554' }} />
        <span style={{ marginLeft: 10, fontFamily: VXP.mono, fontSize: 12, color: VXP.faint }}>untitled — vx</span>
      </div>
      <div style={{ padding: '30px 28px 26px', position: 'relative', minHeight: 132 }}>
        <div style={{ fontFamily: VXP.mono, fontSize: 12, color: VXP.faint, marginBottom: 14, display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 7, height: 7, borderRadius: 99, background: VXP.coral, boxShadow: `0 0 0 3px ${VXP.coralDim}` }} />
          hold ⌥ space · speak · release
        </div>
        <div style={{ fontSize: 22, lineHeight: 1.5, color: VXP.text, fontWeight: 400, letterSpacing: -0.2 }}>
          {text}
          <span style={{ display: 'inline-block', width: 2, height: '1.05em', background: VXP.blue, marginLeft: 2, transform: 'translateY(3px)', animation: 'vxblink 1s steps(1) infinite' }} />
        </div>
      </div>
      <div style={{ display: 'flex', justifyContent: 'center', padding: '0 0 26px' }}>
        <div style={{
          display: 'inline-flex', alignItems: 'center', gap: 12,
          background: '#34343a', borderRadius: 999, padding: '8px 10px',
          boxShadow: '0 10px 30px rgba(0,0,0,0.45), inset 0 0 0 1px rgba(255,255,255,0.06)',
        }}>
          <div style={{ width: 24, height: 24, borderRadius: 999, background: 'rgba(255,255,255,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#cfcfd4', fontSize: 12 }}>✕</div>
          <Waveform bars={10} color={VXP.green} active={active} h={20} w={4.5} gap={2.5} />
          <div style={{ width: 24, height: 24, borderRadius: 999, background: active ? '#ec5b4d' : 'rgba(255,255,255,0.18)', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'background .2s' }}>
            <div style={{ width: 8, height: 8, borderRadius: 2, background: '#fff' }} />
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Buttons ────────────────────────────────────────────────────
function DownloadBtn({ children = 'Download for macOS', sub, big = false }) {
  return (
    <a href="https://github.com/tonydelanuez/vx/releases" style={{
      display: 'inline-flex', alignItems: 'center', gap: 10, textDecoration: 'none',
      background: VXP.blue, color: VXP.ink, fontFamily: VXP.body, fontWeight: 600,
      fontSize: big ? 18 : 15, padding: big ? '16px 26px' : '12px 20px', borderRadius: 12,
      letterSpacing: -0.2, boxShadow: `0 8px 28px ${VXP.blueDim}`, transition: 'transform .15s', whiteSpace: 'nowrap',
    }}>
      <Icon name="download" size={big ? 21 : 18} stroke={VXP.ink} sw={2} />
      <span style={{ textAlign: 'left' }}>{children}{sub && <span style={{ display: 'block', fontSize: 11, fontWeight: 500, opacity: 0.7 }}>{sub}</span>}</span>
    </a>
  );
}
function GhostBtn({ children = 'View on GitHub', big = false }) {
  return (
    <a href="https://github.com/tonydelanuez/vx" style={{
      display: 'inline-flex', alignItems: 'center', gap: 9, textDecoration: 'none',
      background: 'transparent', color: VXP.text, fontFamily: VXP.body, fontWeight: 500,
      fontSize: big ? 18 : 15, padding: big ? '16px 24px' : '12px 18px', borderRadius: 12,
      border: `1px solid ${VXP.line2}`, letterSpacing: -0.2,
    }}>
      <Icon name="github" size={big ? 20 : 17} sw={1.6} />
      <span>{children}</span>
    </a>
  );
}

// Inject keyframes + base once.
if (typeof document !== 'undefined' && !document.getElementById('vx-kf')) {
  const s = document.createElement('style');
  s.id = 'vx-kf';
  s.textContent = `
    @keyframes vxwave { 0%,100%{ transform: scaleY(0.45);} 50%{ transform: scaleY(1.6);} }
    @keyframes vxblink { 0%,50%{opacity:1;} 51%,100%{opacity:0;} }
    @keyframes vxfloat { 0%,100%{ transform: translateY(0);} 50%{ transform: translateY(-7px);} }
    @keyframes vxmarquee { from{ transform: translateX(0);} to{ transform: translateX(-50%);} }
    @keyframes vxrise { from{ opacity:0; transform: translateY(14px);} to{ opacity:1; transform: translateY(0);} }
    @keyframes vxflash { 0%{ background: rgba(111,159,232,0.40);} 100%{ background: transparent;} }
    @keyframes vxstrike { from{ width:0;} to{ width:100%;} }
    .vx-link{ color:${VXP.blue}; text-decoration:none; }
    .vx-link:hover{ text-decoration:underline; }
  `;
  document.head.appendChild(s);
}

Object.assign(window, { VXP, S, C, PixelMascot, Icon, Waveform, RecordPill, useTyping, DictationDemo, DownloadBtn, GhostBtn });
