<!-- PretextBackground.svelte — Pretext-inspired dynamic floating text background
     Words (MAC, MBM, AI) float and scatter on hover/touch with physics -->
<script>
  import { onMount, onDestroy } from 'svelte';

  let containerEl;
  let rafId;
  let words = [];
  let mouse = { x: -9999, y: -9999, active: false };

  // Word configuration — scattered across viewport
  const WORD_CONFIG = [
    { text: 'MAC', x: 0.07, y: 0.08, size: 42, rot: -8,  weight: 900 },
    { text: 'MBM', x: 0.82, y: 0.12, size: 20, rot: 5,   weight: 700 },
    { text: 'AI',  x: 0.42, y: 0.05, size: 26, rot: -12,  weight: 800 },
    { text: 'MAC', x: 0.91, y: 0.35, size: 34, rot: 3,   weight: 900 },
    { text: 'MBM', x: 0.15, y: 0.45, size: 16, rot: -6,  weight: 600 },
    { text: 'AI',  x: 0.68, y: 0.22, size: 42, rot: 10,  weight: 900 },
    { text: 'MAC', x: 0.55, y: 0.72, size: 20, rot: -3,  weight: 700 },
    { text: 'MBM', x: 0.28, y: 0.78, size: 26, rot: 7,   weight: 800 },
    { text: 'AI',  x: 0.78, y: 0.55, size: 16, rot: -14, weight: 600 },
    { text: 'MAC', x: 0.04, y: 0.65, size: 34, rot: 4,   weight: 900 },
    { text: 'MBM', x: 0.60, y: 0.88, size: 42, rot: -9,  weight: 900 },
    { text: 'AI',  x: 0.88, y: 0.78, size: 20, rot: 6,   weight: 700 },
    { text: 'MAC', x: 0.35, y: 0.90, size: 16, rot: -5,  weight: 600 },
    { text: 'MBM', x: 0.18, y: 0.22, size: 26, rot: 11,  weight: 800 },
    { text: 'AI',  x: 0.48, y: 0.42, size: 34, rot: -7,  weight: 900 },
    { text: 'MAC', x: 0.72, y: 0.60, size: 20, rot: 2,   weight: 700 },
    { text: 'MBM', x: 0.95, y: 0.15, size: 16, rot: -13, weight: 600 },
    { text: 'AI',  x: 0.08, y: 0.88, size: 26, rot: 9,   weight: 800 },
    { text: 'MAC', x: 0.50, y: 0.18, size: 42, rot: -4,  weight: 900 },
    { text: 'MBM', x: 0.38, y: 0.55, size: 20, rot: 13,  weight: 700 },
    { text: 'CLOUD', x: 0.22, y: 0.35, size: 16, rot: -2, weight: 600 },
    { text: 'GPU',   x: 0.75, y: 0.42, size: 16, rot: 8,  weight: 600 },
    { text: 'LLM',   x: 0.62, y: 0.68, size: 16, rot: -6, weight: 600 },
  ];

  // Physics constants
  const REPEL_RADIUS = 200;
  const MAX_PUSH = 80;
  const SPRING = 0.05;
  const FRICTION = 0.82;
  const PROXIMITY_GLOW_RADIUS = 160;

  function initWords() {
    if (!containerEl) return;
    const rect = containerEl.getBoundingClientRect();
    words = WORD_CONFIG.map((cfg, i) => ({
      ...cfg,
      origX: cfg.x * rect.width,
      origY: cfg.y * rect.height,
      currX: cfg.x * rect.width,
      currY: cfg.y * rect.height,
      vx: 0,
      vy: 0,
      opacity: 0.10,
      el: null,
      idx: i,
    }));
  }

  function physicsLoop() {
    if (!containerEl) return;
    let anyMoving = false;

    words.forEach(w => {
      if (!w.el) return;

      // Distance from mouse
      const dx = w.currX - mouse.x;
      const dy = w.currY - mouse.y;
      const dist = Math.sqrt(dx * dx + dy * dy);

      // Proximity glow
      let targetOpacity = 0.10;
      if (mouse.active && dist < PROXIMITY_GLOW_RADIUS) {
        targetOpacity = 0.15 + (1 - dist / PROXIMITY_GLOW_RADIUS) * 0.30;
      }
      w.opacity += (targetOpacity - w.opacity) * 0.1;

      // Repel force from mouse
      if (mouse.active && dist < REPEL_RADIUS && dist > 1) {
        const force = ((REPEL_RADIUS - dist) / REPEL_RADIUS) * MAX_PUSH;
        w.vx += (dx / dist) * force * 0.06;
        w.vy += (dy / dist) * force * 0.06;
      }

      // Spring back to origin
      w.vx += (w.origX - w.currX) * SPRING;
      w.vy += (w.origY - w.currY) * SPRING;

      // Friction
      w.vx *= FRICTION;
      w.vy *= FRICTION;

      // Update position
      w.currX += w.vx;
      w.currY += w.vy;

      // Apply transform
      const deltaX = w.currX - w.origX;
      const deltaY = w.currY - w.origY;
      w.el.style.transform = `rotate(${w.rot}deg) translate(${deltaX}px, ${deltaY}px)`;
      w.el.style.opacity = w.opacity;

      if (Math.abs(w.vx) > 0.05 || Math.abs(w.vy) > 0.05) anyMoving = true;
    });

    if (anyMoving || mouse.active) {
      rafId = requestAnimationFrame(physicsLoop);
    } else {
      rafId = null;
    }
  }

  function startPhysics() {
    if (!rafId) {
      rafId = requestAnimationFrame(physicsLoop);
    }
  }

  function handleMouseMove(e) {
    if (!containerEl) return;
    const rect = containerEl.getBoundingClientRect();
    mouse.x = e.clientX - rect.left;
    mouse.y = e.clientY - rect.top;
    mouse.active = true;
    startPhysics();
  }

  function handleMouseLeave() {
    mouse.x = -9999;
    mouse.y = -9999;
    mouse.active = false;
    startPhysics(); // let spring-back animate
  }

  function handleTouchMove(e) {
    if (!e.touches.length || !containerEl) return;
    const rect = containerEl.getBoundingClientRect();
    mouse.x = e.touches[0].clientX - rect.left;
    mouse.y = e.touches[0].clientY - rect.top;
    mouse.active = true;
    startPhysics();
  }

  function handleTouchEnd() {
    mouse.x = -9999;
    mouse.y = -9999;
    mouse.active = false;
    startPhysics();
  }

  function handleResize() {
    if (!containerEl) return;
    const rect = containerEl.getBoundingClientRect();
    words.forEach((w, i) => {
      const cfg = WORD_CONFIG[i];
      w.origX = cfg.x * rect.width;
      w.origY = cfg.y * rect.height;
      w.currX = w.origX;
      w.currY = w.origY;
      w.vx = 0;
      w.vy = 0;
    });
  }

  onMount(() => {
    initWords();
    // Bind word elements
    setTimeout(() => {
      if (!containerEl) return;
      const els = containerEl.querySelectorAll('.pt-word');
      els.forEach((el, i) => {
        if (words[i]) words[i].el = el;
      });
    }, 0);

    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
      if (rafId) cancelAnimationFrame(rafId);
    };
  });

  onDestroy(() => {
    if (rafId) cancelAnimationFrame(rafId);
  });
</script>

<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
  bind:this={containerEl}
  class="pretext-bg"
  aria-hidden="true"
  on:mousemove={handleMouseMove}
  on:mouseleave={handleMouseLeave}
  on:touchmove|passive={handleTouchMove}
  on:touchend={handleTouchEnd}
>
  <!-- Scanlines overlay -->
  <div class="pt-scanlines"></div>

  <!-- Floating words -->
  {#each WORD_CONFIG as cfg, i}
    <span
      class="pt-word"
      style="
        left: {cfg.x * 100}%;
        top: {cfg.y * 100}%;
        font-size: {cfg.size}px;
        font-weight: {cfg.weight};
        transform: rotate({cfg.rot}deg);
        opacity: 0.10;
      "
    >{cfg.text}</span>
  {/each}
</div>

<style>
  .pretext-bg {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: auto;
    overflow: hidden;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
  }

  .pt-scanlines {
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(
      to bottom,
      transparent 0,
      transparent 5px,
      rgba(217, 116, 73, 0.018) 6px
    );
    mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 80%, transparent);
    pointer-events: none;
  }

  .pt-word {
    position: absolute;
    color: var(--accent, #D97449);
    font-family: 'Courier New', monospace;
    letter-spacing: 0.15em;
    pointer-events: none;
    will-change: transform, opacity;
    transition: opacity 0.3s ease;
    text-transform: uppercase;
  }

  @media (prefers-reduced-motion: reduce) {
    .pt-word {
      transition: none !important;
    }
  }
</style>
