// Shared data + helpers for all 4 variations
const ISSUES = [
  {
    no: '001',
    stardate: '2026.04.17',
    title: 'Welcome to the Grid',
    excerpt: 'News, stories, and resources to guide cyborgs towards an undivided life — proactive data defense, Centaur workflows, and Friction by Design.',
    tags: ['editorial', 'privacy', 'ai', 'centaur', 'friction'],
    lead: true,
  },
  {
    no: '002',
    stardate: '2026.04.16',
    title: 'The Algorithm Dreams of Electric Sheep',
    excerpt: 'When the machine begins to generate culture, what does it mean for those of us who still dream in analog? A dispatch on AI, creativity, and the education of synthetic minds.',
    tags: ['ai', 'creativity', 'education', 'culture'],
  },
  {
    no: '003',
    stardate: '2026.04.15',
    title: 'Augmented Reality, Diminished Patience',
    excerpt: "The promise of augmented reality was that it would enhance the world. Instead, we've discovered it mostly reveals how little patience we have for the world as it actually is.",
    tags: ['opinion', 'augmented reality', 'attention', 'embodiment'],
  },
];

const TICKER = [
  'Cognitive load moderate',
  'Augmentation index rising',
  'Signal clarity: 73%',
  'Upload winds from the northwest',
  'Synaptic pressure: nominal',
  'Memory fragmentation: low',
  'Firewall integrity: 99.2%',
  'Dream cache: 84% full',
];

const NAV = ['Frontpage', 'Archive', 'How to be a Cyborg', 'Marketplace', 'Subscribe'];

// Glyph rain canvas — keeps density low for subtle mode
function useGlyphRain(canvasRef, {
  color = 'rgba(120,180,120,0.45)',
  headColor = 'rgba(180,255,180,0.9)',
  fontSize = 14,
  density = 0.9, // multiplier for column count
  speed = 1,
  fade = 0.08,
  active = true,
} = {}) {
  React.useEffect(() => {
    if (!active) return;
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let w = canvas.width = canvas.offsetWidth;
    let h = canvas.height = canvas.offsetHeight;
    const chars = 'アイウエオカキクケコサシスセソタチツテトナニヌネノ01010110+-*/<>[]{}';
    let cols = Math.floor((w / fontSize) * density);
    let drops = Array(cols).fill(0).map(() => Math.random() * h / fontSize);

    let raf;
    const resize = () => {
      w = canvas.width = canvas.offsetWidth;
      h = canvas.height = canvas.offsetHeight;
      cols = Math.floor((w / fontSize) * density);
      drops = Array(cols).fill(0).map(() => Math.random() * h / fontSize);
    };
    const ro = new ResizeObserver(resize);
    ro.observe(canvas);

    const draw = () => {
      ctx.fillStyle = `rgba(5,15,5,${fade})`;
      ctx.fillRect(0, 0, w, h);
      ctx.font = `${fontSize}px "Share Tech Mono", monospace`;
      for (let i = 0; i < cols; i++) {
        const ch = chars[Math.floor(Math.random() * chars.length)];
        const x = i * fontSize / density;
        const y = drops[i] * fontSize;
        ctx.fillStyle = headColor;
        ctx.fillText(ch, x, y);
        ctx.fillStyle = color;
        ctx.fillText(chars[Math.floor(Math.random() * chars.length)], x, y - fontSize);
        if (y > h && Math.random() > 0.975) drops[i] = 0;
        drops[i] += speed;
      }
      raf = requestAnimationFrame(draw);
    };
    draw();
    return () => { cancelAnimationFrame(raf); ro.disconnect(); };
  }, [active]);
}

// Glitch hover — scrambles characters briefly
function GlitchText({ children, as = 'span', style, className, scrambleChars = '!<>-_\\/[]{}—=+*^?#01' }) {
  const ref = React.useRef(null);
  const [text] = React.useState(typeof children === 'string' ? children : '');
  const onEnter = () => {
    const el = ref.current;
    if (!el) return;
    const original = text;
    let frame = 0;
    const queue = original.split('').map((c, i) => ({
      from: c, to: c,
      start: Math.random() * 8,
      end: Math.random() * 10 + 4,
    }));
    const update = () => {
      let out = '';
      let done = 0;
      for (let i = 0; i < queue.length; i++) {
        const { from, to, start, end } = queue[i];
        if (frame >= end) { out += to; done++; }
        else if (frame >= start) {
          out += scrambleChars[Math.floor(Math.random() * scrambleChars.length)];
        } else out += from;
      }
      el.textContent = out;
      if (done < queue.length) { frame++; requestAnimationFrame(update); }
      else el.textContent = original;
    };
    update();
  };
  const Tag = as;
  return <Tag ref={ref} style={style} className={className} onMouseEnter={onEnter}>{children}</Tag>;
}

Object.assign(window, { ISSUES, TICKER, NAV, useGlyphRain, GlitchText });
