/* global React */
// Animated mosaic wordmark — "eth3r" built from tile tessera that fly in
// and settle into pixel-grid letterforms.
//
// Design rules (corrected after legibility issues):
//   - Each letter has ONE dominant color (handmade variation only within hue family).
//   - Glyphs are 6 wide × 8 tall, hand-tuned to be unambiguously legible.
//   - Dust tiles strictly in the outer margin, small, and never overlap letters.

const { useMemo } = React;

// 6×8 glyph grids.
// Rows top→bottom. '#' = tile, '.' = empty.
const GLYPHS = {
  e: [
    '......',
    '......',
    '.####.',
    '#....#',
    '######',
    '#.....',
    '#....#',
    '.####.',
  ],
  t: [
    '..#...',
    '..#...',
    '######',
    '..#...',
    '..#...',
    '..#...',
    '..#...',
    '...###',
  ],
  h: [
    '#.....',
    '#.....',
    '#.....',
    '#.###.',
    '##...#',
    '#....#',
    '#....#',
    '#....#',
  ],
  '3': [
    '.####.',
    '#....#',
    '.....#',
    '...##.',
    '.....#',
    '.....#',
    '#....#',
    '.####.',
  ],
  r: [
    '......',
    '......',
    '#.####',
    '##....',
    '#.....',
    '#.....',
    '#.....',
    '#.....',
  ],
};

const WORD = ['e', 't', 'h', '3', 'r'];
const LETTER_W = 6;
const LETTER_H = 8;
const LETTER_GAP = 2; // empty cols between letters

// Each letter has ONE dominant color family — kept tight so letters read.
// Within a letter, ~25% of tiles use the lighter sibling for handmade variation.
const LETTER_COLORS = [
  { base: 'var(--t1)', light: 'var(--t1-lt)' }, // e → rose
  { base: 'var(--t2)', light: 'var(--t2-lt)' }, // t → cobalt
  { base: 'var(--t3)', light: 'var(--t3-lt)' }, // h → saffron
  { base: 'var(--t4)', light: 'var(--t4-lt)' }, // 3 → jade
  { base: 'var(--t5)', light: 'var(--t5-lt)' }, // r → plum
];

// Deterministic pseudo-random based on seed
function rand(seed) {
  const x = Math.sin(seed * 9301 + 49297) * 233280;
  return x - Math.floor(x);
}

function buildTiles() {
  const tiles = [];
  let xOffset = 0;
  WORD.forEach((char, letterIdx) => {
    const glyph = GLYPHS[char];
    for (let row = 0; row < LETTER_H; row++) {
      for (let col = 0; col < LETTER_W; col++) {
        if (glyph[row][col] === '#') {
          tiles.push({
            x: xOffset + col,
            y: row,
            letterIdx,
            row,
            col,
          });
        }
      }
    }
    xOffset += LETTER_W + LETTER_GAP;
  });
  return { tiles, totalW: xOffset - LETTER_GAP };
}

function HeroWordmark() {
  const { tiles, totalW } = useMemo(buildTiles, []);
  const TILE = 100;       // cell size in viewBox units
  const GROUT = 6;        // gap between tiles (smaller → bolder letters)
  const PAD = 100;        // viewBox padding
  const vbW = totalW * TILE + PAD * 2;
  const vbH = LETTER_H * TILE + PAD * 2;

  // Wordmark bounding box (in viewBox units) — used to keep dust OUT
  const wordLeft = PAD;
  const wordRight = PAD + totalW * TILE;
  const wordTop = PAD;
  const wordBottom = PAD + LETTER_H * TILE;

  // Dust tiles — small tessera scattered in margin only, far from letters.
  const dust = useMemo(() => {
    const arr = [];
    const allColors = [
      'var(--t1-lt)', 'var(--t2-lt)', 'var(--t3-lt)',
      'var(--t4-lt)', 'var(--t5-lt)', 'var(--ground-3)',
    ];
    let attempts = 0;
    while (arr.length < 22 && attempts < 200) {
      const seed = attempts + 7;
      attempts++;
      const r1 = rand(seed);
      const r2 = rand(seed + 100);
      const r3 = rand(seed + 200);
      const r4 = rand(seed + 300);
      const size = 18 + r4 * 26;
      // pick a margin region
      const region = Math.floor(r3 * 4);
      let dx, dy;
      const marginPad = 16; // keep tiles a touch off the canvas edge
      if (region === 0) {
        // top margin
        dx = marginPad + r1 * (vbW - 2 * marginPad - size);
        dy = marginPad + r2 * (wordTop - 2 * marginPad - size);
      } else if (region === 1) {
        // bottom margin
        dx = marginPad + r1 * (vbW - 2 * marginPad - size);
        dy = wordBottom + marginPad + r2 * (vbH - wordBottom - 2 * marginPad - size);
      } else if (region === 2) {
        // left margin
        dx = marginPad + r1 * (wordLeft - 2 * marginPad - size);
        dy = marginPad + r2 * (vbH - 2 * marginPad - size);
      } else {
        // right margin
        dx = wordRight + marginPad + r1 * (vbW - wordRight - 2 * marginPad - size);
        dy = marginPad + r2 * (vbH - 2 * marginPad - size);
      }
      // skip if any dimension came out negative (region too small)
      if (dx < 0 || dy < 0 || dx + size > vbW || dy + size > vbH) continue;
      // final overlap guard against the wordmark rect
      if (
        dx + size > wordLeft && dx < wordRight &&
        dy + size > wordTop && dy < wordBottom
      ) continue;
      arr.push({
        x: dx, y: dy,
        size,
        rot: (rand(seed + 400) - 0.5) * 30,
        colorIdx: attempts % allColors.length,
        color: allColors[attempts % allColors.length],
        delay: 1400 + arr.length * 80,
      });
    }
    return arr;
  }, [vbW, vbH, wordLeft, wordRight, wordTop, wordBottom]);

  return (
    <div className="hero-wordmark" aria-label="eth3r">
      <svg viewBox={`0 0 ${vbW} ${vbH}`} preserveAspectRatio="xMidYMid meet">
        <defs>
          <filter id="tile-shadow" x="-20%" y="-20%" width="140%" height="140%">
            <feGaussianBlur in="SourceAlpha" stdDeviation="3" />
            <feOffset dx="0" dy="6" result="offset" />
            <feComponentTransfer><feFuncA type="linear" slope="0.20" /></feComponentTransfer>
            <feMerge>
              <feMergeNode />
              <feMergeNode in="SourceGraphic" />
            </feMerge>
          </filter>
        </defs>

        {/* Drift dust tiles (in margin only) */}
        {dust.map((d, i) => (
          <rect
            key={`d-${i}`}
            className="dust"
            x={d.x}
            y={d.y}
            width={d.size}
            height={d.size}
            fill={d.color}
            transform={`rotate(${d.rot} ${d.x + d.size / 2} ${d.y + d.size / 2})`}
            style={{
              '--target-opacity': 0.5,
              '--r': `${d.rot}deg`,
              animationDelay: `${d.delay}ms, ${d.delay}ms`,
            }}
          />
        ))}

        {/* Letter tiles */}
        <g filter="url(#tile-shadow)">
          {tiles.map((t, i) => {
            const palette = LETTER_COLORS[t.letterIdx];
            // ~25% of tiles in a letter use the lighter sibling for handmade variation.
            const variation = rand(i + 11) < 0.25;
            const color = variation ? palette.light : palette.base;

            // gentle jitter so tiles read as hand-cut tessera, not pixels
            const jitterX = (rand(i + 1) - 0.5) * 4;
            const jitterY = (rand(i + 21) - 0.5) * 4;
            const jitterR = (rand(i + 31) - 0.5) * 4;

            // entry animation offsets (random scatter origin)
            const dx = (rand(i + 41) - 0.5) * 1000;
            const dy = (rand(i + 51) - 0.5) * 700 - 80;
            const dr = (rand(i + 61) - 0.5) * 80;

            const cellX = PAD + t.x * TILE + GROUT / 2 + jitterX;
            const cellY = PAD + t.y * TILE + GROUT / 2 + jitterY;
            const size = TILE - GROUT;

            // stagger: left-to-right wave, with row & jitter
            const delay = t.letterIdx * 90 + t.col * 20 + t.row * 18 + rand(i) * 120;

            return (
              <rect
                key={i}
                className="hero-tile"
                x={cellX}
                y={cellY}
                width={size}
                height={size}
                rx={2}
                fill={color}
                style={{
                  '--dx': `${dx}px`,
                  '--dy': `${dy}px`,
                  '--dr': `${dr}deg`,
                  '--final-r': `${jitterR}deg`,
                  '--delay': `${delay}ms`,
                  transformOrigin: `${cellX + size / 2}px ${cellY + size / 2}px`,
                }}
              />
            );
          })}
        </g>
      </svg>
    </div>
  );
}

window.HeroWordmark = HeroWordmark;
