// Matrix rain background effect
(function() {
  // Bail out if user prefers reduced motion
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
    return;
  }

  // Canvas and context
  let canvas = document.getElementById('matrix-rain');
  if (!canvas) return;
  const ctx = canvas.getContext('2d');

  // State
  let columns = [];
  let frameCount = 0;
  let colors = { accent: '#a855f7', accent2: '#00ff88', bg: '#060b10', head: '#ffffff' };

  // Character set: 30% ASCII, 70% katakana
  const ASCII = Array.from({ length: 94 }, (_, i) => String.fromCharCode(33 + i));
  const KATA = Array.from({ length: 96 }, (_, i) => String.fromCodePoint(0x30a0 + i));
  const CHARS = shuffle([...ASCII, ...KATA, ...KATA, ...KATA]);

  // Utility: shuffle array
  function shuffle(arr) {
    for (let i = arr.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [arr[i], arr[j]] = [arr[j], arr[i]];
    }
    return arr;
  }

  // Utility: convert hex or rgb color to rgba string
  function hexToRgba(color, alpha) {
    const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
    if (rgbMatch) {
      return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${alpha})`;
    }
    const hex = color.replace('#', '');
    const r = parseInt(hex.substring(0, 2), 16);
    const g = parseInt(hex.substring(2, 4), 16);
    const b = parseInt(hex.substring(4, 6), 16);
    return `rgba(${r}, ${g}, ${b}, ${alpha})`;
  }

  // Sample CSS variables based on current theme
  function sampleColors() {
    const style = getComputedStyle(document.documentElement);
    const isDark = document.documentElement.classList.contains('theme-dark');
    colors.accent = style.getPropertyValue('--accent').trim();
    colors.accent2 = style.getPropertyValue('--accent2').trim();
    colors.bg = style.getPropertyValue('--bg').trim();
    // Head char: bright white in dark mode, deep purple-black in light mode
    colors.head = isDark ? '#ffffff' : '#1a0533';
  }

  // Resize canvas to window dimensions
  function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    ctx.font = '14px "JetBrains Mono", monospace';
    ctx.textBaseline = 'top';
    initColumns();
  }

  // Initialize columns for the current canvas width
  function initColumns() {
    columns = [];
    const columnWidth = 14;
    const columnCount = Math.floor(canvas.width / columnWidth);

    for (let i = 0; i < columnCount; i++) {
      columns.push({
        x: i * columnWidth,
        y: -Math.floor(Math.random() * 40), // stagger start above viewport
        speed: 2 + Math.floor(Math.random() * 3), // 2-4 frames between drops
        color: Math.random() < 0.6 ? 'accent2' : 'accent', // 60% green, 40% purple
        charIndex: Math.floor(Math.random() * CHARS.length),
        length: 8 + Math.floor(Math.random() * 13), // trail length 8-20
      });
    }
  }

  // Set up MutationObserver for theme switching
  function setupThemeObserver() {
    const observer = new MutationObserver(function(mutations) {
      for (const m of mutations) {
        if (m.attributeName === 'class') {
          sampleColors();
          break;
        }
      }
    });
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class'],
    });
  }

  // Main animation loop
  function drawFrame() {
    frameCount++;

    // Fade layer: semi-transparent background fill
    ctx.fillStyle = hexToRgba(colors.bg, 0.085);
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // Draw each column
    for (const col of columns) {
      // Skip if not time to drop yet (per-column throttle)
      if (frameCount % col.speed !== 0) continue;

      // Draw explicit trail in column color
      ctx.fillStyle = colors[col.color];
      for (let i = 1; i <= col.length; i++) {
        const trailY = (col.y - i) * 14;
        if (trailY < 0) continue;
        const trailCharIndex = (col.charIndex - i + CHARS.length) % CHARS.length;
        ctx.fillText(CHARS[trailCharIndex], col.x, trailY);
      }

      // Draw head character (bright)
      ctx.fillStyle = colors.head;
      const headCharIndex = col.charIndex % CHARS.length;
      ctx.fillText(CHARS[headCharIndex], col.x, col.y * 14);

      // Advance column
      col.y++;
      col.charIndex = (col.charIndex + 1) % CHARS.length;

      // Reset when scrolled off screen
      if (col.y * 14 > canvas.height + col.length * 14) {
        col.y = -Math.floor(Math.random() * 20);
        col.charIndex = Math.floor(Math.random() * CHARS.length);
        col.color = Math.random() < 0.6 ? 'accent2' : 'accent';
      }
    }

    requestAnimationFrame(drawFrame);
  }

  // Initialize
  sampleColors();
  resizeCanvas();
  setupThemeObserver();

  // Debounced resize handler
  let resizeTimer;
  window.addEventListener('resize', function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(resizeCanvas, 150);
  });

  // Start animation when fonts are ready
  document.fonts.ready.then(function() {
    requestAnimationFrame(drawFrame);
  });
})();
