/* hero-bubbles.jsx — animated hero visualization, 3 variants */

const HeroBubbles = ({ variant = 'cloud', skin }) => {
  const [tick, setTick] = React.useState(0);

  React.useEffect(() => {
    let f;
    const loop = () => {
      setTick((t) => t + 1);
      f = requestAnimationFrame(loop);
    };
    f = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(f);
  }, []);

  // Master label set — 5 large (text shown), rest medium/small (no text)
  const labels = [
  { label: 'Premiumization & Sophistication', kind: 'teal', r: 13 }, // 0  L
  { label: 'Alcohol-Free Efficiency', kind: 'warm', r: 12 }, // 1  L
  { label: 'Mindful Drinking', kind: 'teal', r: 11 }, // 2  L
  { label: 'Functional Hydration', kind: 'warm', r: 10 }, // 3  L
  { label: 'Sensory Premium Cues', kind: 'teal', r: 10 }, // 4  L
  { label: 'Price-Value Friction', kind: 'warm', r: 6 }, // 5  M
  { label: 'Ritual & Routine', kind: 'teal', r: 6 }, // 6  M
  { label: 'Sober Curious', kind: 'warm', r: 6 }, // 7  M
  { label: 'Flavor as Identity', kind: 'teal', r: 5 }, // 8  M
  { label: 'THC as Substitute', kind: 'dim', r: 3 }, // 9  small dim
  { label: 'Occasion Substitution', kind: 'teal', r: 5 }, // 10 M
  { label: 'Glorified Juice', kind: 'warm', r: 4 }, // 11 S
  { label: 'Sleepy Girl Mocktail', kind: 'teal', r: 4 }, // 12 S
  { label: 'Adaptogens & Botanicals', kind: 'dim', r: 3 }, // 13 small dim
  { label: 'DIY Flavor', kind: 'dim', r: 2.5 }, // 14 small dim
  { label: 'Cost-of-Living Trade-offs', kind: 'dim', r: 2.5 }, // 15 small dim
  { label: 'Caffeine Crossover', kind: 'dim', r: 2 }, // 16 small dim
  { label: 'Pregnancy & Postpartum', kind: 'dim', r: 2 } // 17 small dim
  ];

  // Cloud layout — large nodes occupy core, small nodes fill periphery
  const cloud = [
  { x: 36, y: 44 }, // 0 L
  { x: 66, y: 36 }, // 1 L
  { x: 56, y: 66 }, // 2 L
  { x: 24, y: 66 }, // 3 L
  { x: 80, y: 62 }, // 4 L
  { x: 50, y: 22 }, // 5 M
  { x: 14, y: 38 }, // 6 M
  { x: 84, y: 22 }, // 7 M
  { x: 42, y: 84 }, // 8 M
  { x: 72, y: 84 }, // 9 M
  { x: 14, y: 84 }, // 10 M
  { x: 26, y: 16 }, // 11 S
  { x: 66, y: 14 }, // 12 S
  { x: 92, y: 42 }, // 13 S
  { x: 6, y: 56 }, // 14 S
  { x: 90, y: 84 }, // 15 S
  { x: 8, y: 20 }, // 16 S
  { x: 56, y: 50 } // 17 S — fills mid-right
  ];

  const layouts = {
    cloud,
    orbit: (() => {
      const arr = [{ x: 50, y: 50 }];
      const ringCount = labels.length - 1;
      for (let i = 0; i < ringCount; i++) {
        const a = i / ringCount * Math.PI * 2 - Math.PI / 2;
        const radius = i % 3 === 0 ? 38 : i % 3 === 1 ? 28 : 20;
        arr.push({ x: 50 + Math.cos(a) * radius, y: 50 + Math.sin(a) * radius });
      }
      return arr;
    })(),
    grid: (() => {
      const arr = [];
      const cols = 6,rows = 3;
      for (let r = 0; r < rows; r++) {
        for (let c = 0; c < cols; c++) {
          arr.push({ x: 10 + c * 16, y: 22 + r * 28 });
        }
      }
      return arr;
    })()
  };

  const positions = layouts[variant] || layouts.cloud;
  const bubbles = labels.map((l, i) => ({ ...l, ...(positions[i] || { x: 50, y: 50 }) }));

  const floatOffset = (i, t) => {
    if (variant === 'grid') {
      const a = t / 80 + i * 1.3;
      return { dx: Math.sin(a) * 0.4, dy: Math.cos(a) * 0.4 };
    }
    if (variant === 'orbit') {
      if (i === 0) return { dx: 0, dy: 0 };
      const ringCount = labels.length - 1;
      const speed = i % 2 === 0 ? 0.0022 : -0.0016;
      const baseA = (i - 1) / ringCount * Math.PI * 2 - Math.PI / 2;
      const a = baseA + t * speed;
      const r = (i - 1) % 3 === 0 ? 38 : (i - 1) % 3 === 1 ? 28 : 20;
      const tx = 50 + Math.cos(a) * r;
      const ty = 50 + Math.sin(a) * r;
      return { dx: tx - positions[i].x, dy: ty - positions[i].y };
    }
    const a = t / 60 + i * 1.7;
    return { dx: Math.sin(a) * 0.9, dy: Math.cos(a * 0.9) * 0.7 };
  };

  // Connection lines — between meaningful pairs
  const linesByVariant = {
    cloud: [
    [0, 1, 'warm'], [0, 2, 'teal'], [1, 4, 'warm'], [2, 3, 'teal'], [0, 3, 'warm'],
    [1, 5, 'warm'], [2, 8, 'teal'], [3, 10, 'teal'], [4, 9, 'warm'], [0, 6, 'teal'],
    [1, 7, 'warm'], [5, 11, 'warm'], [5, 12, 'teal'], [2, 17, 'teal']],

    orbit: Array.from({ length: labels.length - 1 }, (_, i) => [0, i + 1, i % 2 ? 'warm' : 'teal']),
    grid: [[0, 7, 'teal'], [2, 8, 'warm'], [3, 9, 'teal'], [4, 10, 'warm'], [6, 12, 'teal'], [7, 13, 'warm'], [8, 14, 'teal'], [9, 15, 'warm'], [10, 16, 'teal']]
  };
  const lines = linesByVariant[variant] || linesByVariant.cloud;

  // Curved-path builder — quadratic Bezier with a perpendicular control point
  const curvePath = (ax, ay, bx, by, curveIdx) => {
    const mx = (ax + bx) / 2;
    const my = (ay + by) / 2;
    const dx = bx - ax;
    const dy = by - ay;
    const len = Math.sqrt(dx * dx + dy * dy) || 1;
    // Perpendicular unit vector
    const px = -dy / len;
    const py = dx / len;
    // Alternate curve direction so bundles don't overlap
    const dir = curveIdx % 2 === 0 ? 1 : -1;
    const amount = Math.min(8, len * 0.22) * dir;
    const cx = mx + px * amount;
    const cy = my + py * amount;
    return `M ${ax} ${ay} Q ${cx} ${cy} ${bx} ${by}`;
  };

  return (
    <div className="hero-visual" data-comment-anchor="51a2672098-div-91-5">
      <div className="bubble-stage" data-comment-anchor="3b8ac134be-div-43-7"></div>
      <svg viewBox="0 0 100 100" preserveAspectRatio="none"
      style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', overflow: 'visible' }}>
        {lines.map(([a, b, kind], i) => {
          const A = bubbles[a];const B = bubbles[b];
          if (!A || !B) return null;
          const fa = floatOffset(a, tick);const fb = floatOffset(b, tick);
          return (
            <path key={i}
            d={curvePath(A.x + fa.dx, A.y + fa.dy, B.x + fb.dx, B.y + fb.dy, i)}
            fill="none"
            stroke={kind === 'warm' ? 'rgba(158,196,197,0.55)' : 'rgba(75,173,175,0.55)'}
            strokeWidth="0.22"
            strokeDasharray="0.5 0.9"
            strokeLinecap="round" />);
        })}
      </svg>
      {bubbles.map((b, i) => {
        const f = floatOffset(i, tick);
        const sizePct = b.r * 2;
        const showLabel = b.r >= 10;
        return (
          <div
            key={i}
            className={`bubble ${b.kind === 'warm' ? 'warm' : b.kind === 'dim' ? 'dim' : ''}`}
            style={{
              width: `${sizePct}%`,
              height: `${sizePct}%`,
              left: `calc(${b.x + f.dx}% - ${b.r}%)`,
              top: `calc(${b.y + f.dy}% - ${b.r}%)`,
              fontSize: `${b.r * 1.05}px`
            }}>
            {showLabel && <span style={{
              padding: '0 6px',
              maxWidth: '95%',
              fontFamily: "'Lexend Deca', sans-serif",
              fontWeight: 300
            }}>{b.label}</span>}
          </div>);
      })}
      <div className="bubble-title">Themes in Consumer Conversations</div>
      <div style={{ display: 'none' }} data-comment-anchor="64211c0bd3-div-176-7"></div>
    </div>);
};

window.HeroBubbles = HeroBubbles;