// Animated centerpiece compositions. Each variant returns an SVG.
// All variants live inside a 1000x1000 viewBox; the page scales them.

const C = 500; // center

// ────────────────────────────────────────────────────────────────────
// ORBITAL — concentric rotating arcs + tick marks + iridescent core
// ────────────────────────────────────────────────────────────────────
function Orbital({ speed = 1, accent = 'iridescent' }) {
  // Tick generator
  const ticks = (r, count, len) => {
    const arr = [];
    for (let i = 0; i < count; i++) {
      const a = (i / count) * Math.PI * 2;
      const x1 = C + Math.cos(a) * r;
      const y1 = C + Math.sin(a) * r;
      const x2 = C + Math.cos(a) * (r + len);
      const y2 = C + Math.sin(a) * (r + len);
      arr.push(<line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" />);
    }
    return arr;
  };

  // Dashed arc segment
  const arc = (r, sweep, rot) => {
    const a0 = (rot * Math.PI) / 180;
    const a1 = a0 + (sweep * Math.PI) / 180;
    const x0 = C + Math.cos(a0) * r;
    const y0 = C + Math.sin(a0) * r;
    const x1 = C + Math.cos(a1) * r;
    const y1 = C + Math.sin(a1) * r;
    const large = sweep > 180 ? 1 : 0;
    return `M ${x0} ${y0} A ${r} ${r} 0 ${large} 1 ${x1} ${y1}`;
  };

  return (
    <svg viewBox="0 0 1000 1000" style={{ width: '100%', height: '100%', overflow: 'visible' }}>
      <defs>
        <radialGradient id="coreGrad" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="var(--accent-1)" stopOpacity="1" />
          <stop offset="55%" stopColor="var(--accent-2)" stopOpacity="0.7" />
          <stop offset="100%" stopColor="var(--accent-3)" stopOpacity="0" />
        </radialGradient>
        <linearGradient id="irid" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="var(--accent-1)" />
          <stop offset="50%" stopColor="var(--accent-2)" />
          <stop offset="100%" stopColor="var(--accent-3)" />
        </linearGradient>
        <filter id="blurCore" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur stdDeviation="40" />
        </filter>
      </defs>

      {/* glow halo */}
      <circle cx={C} cy={C} r="240" fill="url(#coreGrad)" opacity="0.55" filter="url(#blurCore)" />

      {/* Outer ring with ticks (slow rotation) */}
      <g style={{ animation: `spin ${120 / speed}s linear infinite`, transformOrigin: 'center' }} color="var(--fg-dim)">
        <circle cx={C} cy={C} r="460" fill="none" stroke="currentColor" strokeWidth="0.8" opacity="0.5" />
        {ticks(460, 60, 8)}
        {ticks(460, 12, 18)}
      </g>

      {/* Ring 2 — dashed, counter-rotation */}
      <g style={{ animation: `spinR ${80 / speed}s linear infinite`, transformOrigin: 'center' }} color="var(--fg-dim)">
        <circle cx={C} cy={C} r="380" fill="none" stroke="currentColor" strokeWidth="1" strokeDasharray="3 8" opacity="0.7" />
      </g>

      {/* Ring 3 — arc segments */}
      <g style={{ animation: `spin ${55 / speed}s linear infinite`, transformOrigin: 'center' }}>
        <path d={arc(310, 110, 20)} stroke="url(#irid)" strokeWidth="2" fill="none" strokeLinecap="round" />
        <path d={arc(310, 60, 200)} stroke="url(#irid)" strokeWidth="2" fill="none" strokeLinecap="round" opacity="0.7" />
        <circle cx={C + 310} cy={C} r="4" fill="var(--accent-1)" />
      </g>

      {/* Ring 4 — small ticks */}
      <g style={{ animation: `spinR ${40 / speed}s linear infinite`, transformOrigin: 'center' }} color="var(--fg-dim)">
        <circle cx={C} cy={C} r="240" fill="none" stroke="currentColor" strokeWidth="0.6" opacity="0.6" />
        {ticks(240, 48, 5)}
      </g>

      {/* Inner orbit — small bead */}
      <g style={{ animation: `spin ${22 / speed}s linear infinite`, transformOrigin: 'center' }}>
        <circle cx={C + 180} cy={C} r="3" fill="var(--accent-2)" />
        <circle cx={C - 180} cy={C} r="2" fill="var(--accent-3)" opacity="0.7" />
      </g>

      {/* Iridescent core disc */}
      <g style={{ animation: `spin ${30 / speed}s linear infinite`, transformOrigin: 'center' }}>
        <circle cx={C} cy={C} r="140" fill="url(#irid)" opacity="0.92" />
        <circle cx={C} cy={C} r="140" fill="none" stroke="var(--bg)" strokeWidth="0.5" opacity="0.4" />
        {/* facet lines */}
        {Array.from({ length: 12 }).map((_, i) => {
          const a = (i / 12) * Math.PI * 2;
          return (
            <line
              key={i}
              x1={C}
              y1={C}
              x2={C + Math.cos(a) * 140}
              y2={C + Math.sin(a) * 140}
              stroke="var(--bg)"
              strokeWidth="0.4"
              opacity="0.35"
            />
          );
        })}
      </g>

      {/* center crosshair */}
      <g color="var(--fg)" opacity="0.95">
        <circle cx={C} cy={C} r="4" fill="currentColor" />
        <line x1={C - 24} y1={C} x2={C - 12} y2={C} stroke="currentColor" strokeWidth="1.2" />
        <line x1={C + 12} y1={C} x2={C + 24} y2={C} stroke="currentColor" strokeWidth="1.2" />
        <line x1={C} y1={C - 24} x2={C} y2={C - 12} stroke="currentColor" strokeWidth="1.2" />
        <line x1={C} y1={C + 12} x2={C} y2={C + 24} stroke="currentColor" strokeWidth="1.2" />
      </g>
    </svg>
  );
}

// ────────────────────────────────────────────────────────────────────
// PRISM — overlapping iridescent discs with screen blending
// ────────────────────────────────────────────────────────────────────
function Prism({ speed = 1 }) {
  return (
    <svg viewBox="0 0 1000 1000" style={{ width: '100%', height: '100%', overflow: 'visible' }}>
      <defs>
        <radialGradient id="p1" cx="40%" cy="40%" r="60%">
          <stop offset="0%" stopColor="var(--accent-1)" stopOpacity="1" />
          <stop offset="70%" stopColor="var(--accent-1)" stopOpacity="0" />
        </radialGradient>
        <radialGradient id="p2" cx="60%" cy="50%" r="60%">
          <stop offset="0%" stopColor="var(--accent-2)" stopOpacity="1" />
          <stop offset="70%" stopColor="var(--accent-2)" stopOpacity="0" />
        </radialGradient>
        <radialGradient id="p3" cx="50%" cy="65%" r="60%">
          <stop offset="0%" stopColor="var(--accent-3)" stopOpacity="1" />
          <stop offset="70%" stopColor="var(--accent-3)" stopOpacity="0" />
        </radialGradient>
        <linearGradient id="prismRing" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="var(--accent-1)" />
          <stop offset="50%" stopColor="var(--accent-2)" />
          <stop offset="100%" stopColor="var(--accent-3)" />
        </linearGradient>
        <filter id="prismBlur"><feGaussianBlur stdDeviation="22" /></filter>
      </defs>

      {/* drift halo */}
      <g style={{ mixBlendMode: 'screen' }}>
        <circle cx={C} cy={C} r="360" fill="url(#p1)" filter="url(#prismBlur)" style={{ animation: `prismDrift1 ${24 / speed}s ease-in-out infinite`, transformOrigin: 'center' }} />
        <circle cx={C} cy={C} r="360" fill="url(#p2)" filter="url(#prismBlur)" style={{ animation: `prismDrift2 ${30 / speed}s ease-in-out infinite`, transformOrigin: 'center' }} />
        <circle cx={C} cy={C} r="360" fill="url(#p3)" filter="url(#prismBlur)" style={{ animation: `prismDrift3 ${36 / speed}s ease-in-out infinite`, transformOrigin: 'center' }} />
      </g>

      {/* outer ring */}
      <circle cx={C} cy={C} r="440" fill="none" stroke="var(--fg-dim)" strokeWidth="0.8" opacity="0.4" />
      <circle cx={C} cy={C} r="300" fill="none" stroke="url(#prismRing)" strokeWidth="1.5" style={{ animation: `spin ${60 / speed}s linear infinite`, transformOrigin: 'center' }} strokeDasharray="2 6" />

      {/* hard core disc */}
      <circle cx={C} cy={C} r="120" fill="var(--bg)" />
      <circle cx={C} cy={C} r="120" fill="none" stroke="url(#prismRing)" strokeWidth="2" />
      <circle cx={C} cy={C} r="3" fill="var(--fg)" />
    </svg>
  );
}

// ────────────────────────────────────────────────────────────────────
// LATTICE — wireframe icosahedron-ish, slow rotation
// ────────────────────────────────────────────────────────────────────
function Lattice({ speed = 1 }) {
  // Build icosahedron vertices in 3D, project orthographically with a y-rot driven by time
  const phi = (1 + Math.sqrt(5)) / 2;
  const r = 280;
  const verts = [
    [-1,  phi, 0], [1,  phi, 0], [-1, -phi, 0], [1, -phi, 0],
    [0, -1,  phi], [0, 1,  phi], [0, -1, -phi], [0, 1, -phi],
    [ phi, 0, -1], [ phi, 0, 1], [-phi, 0, -1], [-phi, 0, 1],
  ];
  const edges = [
    [0,1],[0,5],[0,7],[0,10],[0,11],
    [1,5],[1,7],[1,8],[1,9],
    [2,3],[2,4],[2,6],[2,10],[2,11],
    [3,4],[3,6],[3,8],[3,9],
    [4,5],[4,9],[4,11],
    [5,9],[5,11],
    [6,7],[6,8],[6,10],
    [7,8],[7,10],
    [8,9],
    [10,11],
  ];

  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    let raf;
    const start = performance.now();
    const loop = (now) => {
      setT((now - start) / 1000);
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);

  const ay = t * 0.18 * speed;
  const ax = t * 0.11 * speed + 0.4;

  const project = ([x, y, z]) => {
    // rotate around Y
    let x2 = x * Math.cos(ay) - z * Math.sin(ay);
    let z2 = x * Math.sin(ay) + z * Math.cos(ay);
    // rotate around X
    let y3 = y * Math.cos(ax) - z2 * Math.sin(ax);
    let z3 = y * Math.sin(ax) + z2 * Math.cos(ax);
    return [C + x2 * r * 0.4, C + y3 * r * 0.4, z3];
  };

  const projected = verts.map(project);

  return (
    <svg viewBox="0 0 1000 1000" style={{ width: '100%', height: '100%', overflow: 'visible' }}>
      <defs>
        <radialGradient id="latGrad" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="var(--accent-1)" stopOpacity="0.5" />
          <stop offset="100%" stopColor="var(--accent-1)" stopOpacity="0" />
        </radialGradient>
        <linearGradient id="latLine" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="var(--accent-1)" />
          <stop offset="100%" stopColor="var(--accent-3)" />
        </linearGradient>
      </defs>
      <circle cx={C} cy={C} r="320" fill="url(#latGrad)" />
      <circle cx={C} cy={C} r="380" fill="none" stroke="var(--fg-dim)" strokeWidth="0.6" opacity="0.3" />
      <circle cx={C} cy={C} r="440" fill="none" stroke="var(--fg-dim)" strokeWidth="0.6" opacity="0.2" />

      {edges.map(([a, b], i) => {
        const [x1, y1, z1] = projected[a];
        const [x2, y2, z2] = projected[b];
        const depth = (z1 + z2) / 2; // -range..range
        const op = 0.35 + (depth + 2) / 8;
        return (
          <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="url(#latLine)" strokeWidth={1 + Math.max(0, depth) * 0.6} opacity={Math.max(0.15, Math.min(1, op))} strokeLinecap="round" />
        );
      })}
      {projected.map(([x, y, z], i) => (
        <circle key={i} cx={x} cy={y} r={2 + Math.max(0, z) * 0.6} fill="var(--accent-2)" opacity={0.5 + (z + 2) / 6} />
      ))}
    </svg>
  );
}

// ────────────────────────────────────────────────────────────────────
// RIBBON — parallel curved bands sweeping
// ────────────────────────────────────────────────────────────────────
function Ribbon({ speed = 1 }) {
  const lines = 28;
  return (
    <svg viewBox="0 0 1000 1000" style={{ width: '100%', height: '100%', overflow: 'visible' }}>
      <defs>
        <linearGradient id="ribGrad" x1="0" y1="0" x2="1" y2="0">
          <stop offset="0%" stopColor="var(--accent-1)" stopOpacity="0" />
          <stop offset="20%" stopColor="var(--accent-1)" stopOpacity="1" />
          <stop offset="50%" stopColor="var(--accent-2)" stopOpacity="1" />
          <stop offset="80%" stopColor="var(--accent-3)" stopOpacity="1" />
          <stop offset="100%" stopColor="var(--accent-3)" stopOpacity="0" />
        </linearGradient>
      </defs>
      <g style={{ animation: `ribbonWave ${18 / speed}s ease-in-out infinite`, transformOrigin: 'center' }}>
        {Array.from({ length: lines }).map((_, i) => {
          const t = i / (lines - 1);
          const r = 120 + t * 320;
          const yOff = Math.sin(t * Math.PI) * 60;
          return (
            <path
              key={i}
              d={`M 80 ${C + yOff} Q ${C} ${C - r * 0.5} ${1000 - 80} ${C - yOff}`}
              stroke="url(#ribGrad)"
              strokeWidth={0.6 + t * 0.6}
              fill="none"
              opacity={0.4 + t * 0.5}
            />
          );
        })}
      </g>
      <circle cx={C} cy={C} r="4" fill="var(--fg)" />
    </svg>
  );
}

window.Orbital = Orbital;
window.Prism = Prism;
window.Lattice = Lattice;
window.Ribbon = Ribbon;
