// Shared tokens, placeholders, and bits used across all three variations.

const SN_PALETTE = {
  dirt: '#7B5A3A',
  dirtDark: '#5A4229',
  dirtLight: '#A07A4F',
  grass: '#6B8E3D',
  grassDark: '#4E6B28',
  grassLight: '#8FB05A',
  stone: '#8A8A8A',
  stoneDark: '#5F5F5F',
  stoneLight: '#B5B5B5',
  parchment: '#F3ECDC',
  parchmentDark: '#E4D9BD',
  ink: '#1F1A14',
  linkBlue: '#0000EE',
  linkVisited: '#551A8B',
};

// Tiled block background as an SVG data URI — 32x32 tile.
// Slight per-cell variation to avoid grid pattern readability.
function tiledBlockBg(top, mid, dark, size = 32) {
  const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='${size*2}' height='${size*2}' viewBox='0 0 ${size*2} ${size*2}'>
    <rect width='100%' height='100%' fill='${mid}'/>
    <g fill='${dark}' opacity='0.35'>
      <rect x='0' y='${size-2}' width='${size*2}' height='2'/>
      <rect x='${size-1}' y='0' width='1' height='${size*2}'/>
      <rect x='4' y='6' width='2' height='2'/>
      <rect x='${size+10}' y='3' width='3' height='2'/>
      <rect x='${size+20}' y='${size+8}' width='2' height='2'/>
      <rect x='10' y='${size+14}' width='3' height='2'/>
      <rect x='20' y='22' width='2' height='2'/>
      <rect x='${size+4}' y='${size+22}' width='2' height='3'/>
    </g>
    <g fill='${top}' opacity='0.25'>
      <rect x='0' y='0' width='${size*2}' height='2'/>
      <rect x='0' y='${size}' width='${size*2}' height='2'/>
      <rect x='2' y='3' width='3' height='1'/>
      <rect x='${size+6}' y='${size+1}' width='4' height='1'/>
      <rect x='14' y='${size+3}' width='2' height='1'/>
    </g>
  </svg>`;
  return `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
}

// A "grass top" strip bg — darker dirt below a lighter grass cap.
function grassTopBg() {
  const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='32' height='64' viewBox='0 0 32 64'>
    <rect width='32' height='10' fill='${SN_PALETTE.grass}'/>
    <rect y='8' width='32' height='4' fill='${SN_PALETTE.grassDark}' opacity='0.6'/>
    <rect y='12' width='32' height='52' fill='${SN_PALETTE.dirt}'/>
    <g fill='${SN_PALETTE.grassLight}'><rect x='2' y='2' width='2' height='2'/><rect x='10' y='4' width='3' height='2'/><rect x='20' y='1' width='2' height='3'/><rect x='26' y='5' width='2' height='2'/></g>
    <g fill='${SN_PALETTE.dirtDark}' opacity='0.5'><rect x='4' y='18' width='3' height='2'/><rect x='14' y='24' width='2' height='2'/><rect x='22' y='20' width='2' height='3'/><rect x='8' y='36' width='2' height='2'/><rect x='18' y='42' width='3' height='2'/><rect x='26' y='50' width='2' height='2'/><rect x='6' y='56' width='2' height='2'/></g>
    <g fill='${SN_PALETTE.dirtLight}' opacity='0.35'><rect x='10' y='16' width='2' height='1'/><rect x='20' y='30' width='2' height='2'/><rect x='2' y='44' width='3' height='1'/></g>
  </svg>`;
  return `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
}

// Diagonal-stripe placeholder SVG w/ a mono label centered.
function StripedPlaceholder({ w = 320, h = 180, label = 'screenshot', tone = 'dirt' }) {
  const stroke = tone === 'stone' ? '#6a6a6a' : tone === 'grass' ? '#4E6B28' : '#5A4229';
  const fill = tone === 'stone' ? '#c5c5c2' : tone === 'grass' ? '#a8c073' : '#cdb48a';
  const fg = tone === 'stone' ? '#2a2a2a' : '#2a1f12';
  const svg = (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} xmlns="http://www.w3.org/2000/svg" style={{ display: 'block' }}>
      <defs>
        <pattern id={`stripes-${tone}-${w}-${h}`} patternUnits="userSpaceOnUse" width="10" height="10" patternTransform="rotate(45)">
          <rect width="10" height="10" fill={fill}/>
          <line x1="0" y1="0" x2="0" y2="10" stroke={stroke} strokeWidth="1" opacity="0.45"/>
        </pattern>
      </defs>
      <rect width={w} height={h} fill={`url(#stripes-${tone}-${w}-${h})`}/>
      <rect x="0.5" y="0.5" width={w-1} height={h-1} fill="none" stroke={stroke} strokeWidth="1"/>
      <g transform={`translate(${w/2}, ${h/2})`}>
        <rect x={-Math.max(70, label.length*5)} y={-14} width={Math.max(140, label.length*10)} height={28} fill="#f3ecdc" stroke={stroke}/>
        <text x="0" y="5" textAnchor="middle" fontFamily="'VT323', 'Courier New', monospace" fontSize="18" fill={fg}>{label}</text>
      </g>
    </svg>
  );
  return svg;
}

// Tiny pixel logo: spells "SN" in blocks. Uses a grid of colored pixels.
function PixelLogoSN({ scale = 6, top = SN_PALETTE.grass, side = SN_PALETTE.grassDark, base = SN_PALETTE.dirt, shadow = SN_PALETTE.dirtDark }) {
  // 2-color block lettering on a 15x7 grid. S then N.
  const S = [
    '.###.',
    '#....',
    '#....',
    '.##..',
    '...#.',
    '....#',
    '###..',
  ];
  const N = [
    '#...#',
    '##..#',
    '#.#.#',
    '#..##',
    '#...#',
    '#...#',
    '#...#',
  ];
  const rows = 7, cols = 11; // 5 + 1 gap + 5
  const grid = [];
  for (let r = 0; r < rows; r++) {
    let line = '';
    for (let c = 0; c < 5; c++) line += S[r][c];
    line += '.';
    for (let c = 0; c < 5; c++) line += N[r][c];
    grid.push(line);
  }
  return (
    <div style={{ display: 'inline-block', imageRendering: 'pixelated', lineHeight: 0 }}>
      {grid.map((row, r) => (
        <div key={r} style={{ display: 'flex' }}>
          {row.split('').map((ch, c) => {
            const on = ch === '#';
            const bg = on ? (r === 0 ? top : r === rows - 1 ? shadow : side) : 'transparent';
            return <div key={c} style={{ width: scale, height: scale, background: bg }}/>;
          })}
        </div>
      ))}
    </div>
  );
}

// A rendered 3D-ish isometric "grass block" drawn with CSS/SVG pixels.
function PixelGrassBlock({ size = 64 }) {
  const p = size / 16;
  const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='${size}' height='${size}' viewBox='0 0 16 16' shape-rendering='crispEdges'>
    <rect x='0' y='0' width='16' height='4' fill='${SN_PALETTE.grass}'/>
    <rect x='0' y='3' width='16' height='2' fill='${SN_PALETTE.grassDark}' opacity='0.55'/>
    <rect x='0' y='4' width='16' height='12' fill='${SN_PALETTE.dirt}'/>
    <rect x='2' y='1' width='2' height='1' fill='${SN_PALETTE.grassLight}'/>
    <rect x='8' y='2' width='2' height='1' fill='${SN_PALETTE.grassLight}'/>
    <rect x='12' y='1' width='1' height='2' fill='${SN_PALETTE.grassLight}'/>
    <rect x='3' y='6' width='2' height='2' fill='${SN_PALETTE.dirtDark}' opacity='0.45'/>
    <rect x='10' y='8' width='2' height='1' fill='${SN_PALETTE.dirtDark}' opacity='0.45'/>
    <rect x='6' y='11' width='3' height='2' fill='${SN_PALETTE.dirtDark}' opacity='0.45'/>
    <rect x='13' y='13' width='2' height='1' fill='${SN_PALETTE.dirtDark}' opacity='0.45'/>
    <rect x='1' y='13' width='1' height='1' fill='${SN_PALETTE.dirtLight}' opacity='0.5'/>
    <rect x='8' y='6' width='1' height='1' fill='${SN_PALETTE.dirtLight}' opacity='0.5'/>
  </svg>`;
  return <img src={`data:image/svg+xml;utf8,${encodeURIComponent(svg)}`} width={size} height={size} style={{ imageRendering: 'pixelated', display: 'block' }} alt="grass block"/>;
}

// A simple day/night toggle — pixel sun/moon with 2 states.
function DayNightToggle({ night, onToggle, scale = 3 }) {
  // 12x12 pixel sun/moon
  const sun = [
    '....####....',
    '...#....#...',
    '..#......#..',
    '.#........#.',
    '#..........#',
    '#..........#',
    '#..........#',
    '#..........#',
    '.#........#.',
    '..#......#..',
    '...#....#...',
    '....####....',
  ];
  const moon = [
    '....####....',
    '...#....#...',
    '..#..##...#.',
    '.#..####..#.',
    '#..####....#',
    '#..####....#',
    '#..####....#',
    '#..####....#',
    '.#..####..#.',
    '..#..##...#.',
    '...#....#...',
    '....####....',
  ];
  const art = night ? moon : sun;
  const fill = night ? '#e6e2c7' : '#e8c24a';
  const stroke = night ? '#7a7560' : '#8a6a1e';
  return (
    <button
      onClick={onToggle}
      title={night ? 'switch to day' : 'switch to night'}
      aria-label={night ? 'switch to day' : 'switch to night'}
      style={{
        display: 'inline-block', padding: 4, lineHeight: 0,
        background: night ? '#1a1f2e' : '#cfe2ff',
        border: `2px solid ${night ? '#050812' : '#6b91c8'}`,
        cursor: 'pointer',
      }}
    >
      <div style={{ display: 'inline-block', imageRendering: 'pixelated' }}>
        {art.map((row, r) => (
          <div key={r} style={{ display: 'flex' }}>
            {row.split('').map((ch, c) => (
              <div key={c} style={{
                width: scale, height: scale,
                background: ch === '#' ? (ch === '#' && r === 0 ? stroke : fill) : 'transparent',
              }}/>
            ))}
          </div>
        ))}
      </div>
    </button>
  );
}

// Pixel cursor trail — spawns small colored squares that fade.
// Activated inside a container via onMouseMove.
function useCursorTrail(containerRef, { enabled = true, color = '#6B8E3D' } = {}) {
  React.useEffect(() => {
    if (!enabled) return;
    const el = containerRef.current;
    if (!el) return;
    let last = 0;
    const onMove = (e) => {
      const now = performance.now();
      if (now - last < 28) return;
      last = now;
      const r = el.getBoundingClientRect();
      const x = e.clientX - r.left;
      const y = e.clientY - r.top;
      const dot = document.createElement('div');
      dot.style.position = 'absolute';
      dot.style.left = (x - 3) + 'px';
      dot.style.top = (y - 3) + 'px';
      dot.style.width = '6px';
      dot.style.height = '6px';
      dot.style.background = color;
      dot.style.pointerEvents = 'none';
      dot.style.opacity = '1';
      dot.style.transition = 'opacity 600ms linear, transform 600ms linear';
      dot.style.zIndex = '999';
      el.appendChild(dot);
      requestAnimationFrame(() => {
        dot.style.opacity = '0';
        dot.style.transform = `translate(${(Math.random()-0.5)*6}px, ${6 + Math.random()*8}px)`;
      });
      setTimeout(() => { dot.remove(); }, 650);
    };
    el.addEventListener('mousemove', onMove);
    return () => el.removeEventListener('mousemove', onMove);
  }, [containerRef, enabled, color]);
}

Object.assign(window, {
  SN_PALETTE, tiledBlockBg, grassTopBg,
  StripedPlaceholder, PixelLogoSN, PixelGrassBlock,
  DayNightToggle, useCursorTrail,
});
