// Cadence animations — loading loop + video intro.

const { useState: useS, useEffect: useE, useRef: useR } = React;

// ─────────────────────────────────────────────────────────────
// Live "speaking" bars — 5 asymmetric bars that breathe continuously.
// Used for: loading indicators, "agent is speaking" status, app launch.
// ─────────────────────────────────────────────────────────────
function CadenceLoader({ size = 160, color = '#0B0B0C', accent = '#2F6BFF', showAccent = false, speed = 1 }) {
  // Each bar has its own phase + amplitude so they feel like real speech,
  // not a symmetric equalizer loop.
  const bars = [
    { phase: 0.0,  min: 0.35, max: 0.92, period: 1.1 },
    { phase: 0.35, min: 0.25, max: 0.78, period: 0.9 },
    { phase: 0.15, min: 0.18, max: 0.52, period: 1.3 },
    { phase: 0.55, min: 0.28, max: 0.82, period: 1.0 },
    { phase: 0.20, min: 0.42, max: 1.00, period: 1.2 },
  ];
  const barW = 7;
  const gap = 9;
  const totalW = bars.length * barW + (bars.length - 1) * gap;
  const startX = (100 - totalW) / 2;
  const maxH = 78;
  const baseY = 90;

  const [t, setT] = useS(0);
  useE(() => {
    let raf, start;
    const loop = (ts) => {
      if (!start) start = ts;
      setT(((ts - start) / 1000) * speed);
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [speed]);

  return (
    <svg width={size} height={size} viewBox="0 0 100 100" style={{ display: 'block' }}>
      {bars.map((b, i) => {
        const x = startX + i * (barW + gap);
        // sinusoidal breathing between min and max
        const phase = (t / b.period + b.phase) * Math.PI * 2;
        const v = (Math.sin(phase) + 1) / 2; // 0..1
        const h = (b.min + v * (b.max - b.min)) * maxH;
        const y = baseY - h;
        const isPeak = i === 4;
        return (
          <rect key={i} x={x} y={y} width={barW} height={h} rx={barW / 2}
            fill={isPeak && showAccent ? accent : color} />
        );
      })}
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// Video intro — bars cascade in from bottom, stabilize, wordmark reveals.
// 2.4s total, loops on click.
// ─────────────────────────────────────────────────────────────
function CadenceIntro({
  width = 560, height = 240,
  bg = '#FAFAF7', fg = '#0B0B0C', accent = '#2F6BFF',
  onDone,
  showCaption = true, showProgress = true, clickToReplay = true,
  playId: controlledPlayId,
}) {
  // Keyframe: t=0..0.45 bars rise one-by-one; 0.45..0.85 settle to final V;
  // 0.7..1.0 wordmark fades in from the right.
  const [internalPlayId, setInternalPlayId] = useS(0);
  const playId = controlledPlayId !== undefined ? controlledPlayId : internalPlayId;
  const [t, setT] = useS(0); // 0..1 normalized
  const DURATION = 2400;

  useE(() => {
    let raf, start;
    const loop = (ts) => {
      if (!start) start = ts;
      const elapsed = ts - start;
      const k = Math.min(1, elapsed / DURATION);
      setT(k);
      if (k < 1) raf = requestAnimationFrame(loop);
      else if (onDone) onDone();
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [playId]);

  const easeOut = (x) => 1 - Math.pow(1 - x, 3);
  const easeInOut = (x) => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2;

  // Final heights (matches CadenceProMark)
  const finalHeights = [0.88, 0.62, 0.38, 0.74, 1.00];
  const barCount = finalHeights.length;
  const barW = 7;
  const gap = 9;
  const totalW = barCount * barW + (barCount - 1) * gap;
  // Mark is centered within a 100-unit viewBox on the left half
  const markViewSize = 100;
  const startX = (markViewSize - totalW) / 2;
  const maxH = 78;
  const baseY = 90;

  // Per-bar stagger: each bar enters 0.05..0.35 normalized
  const barProgress = (i) => {
    const start = 0.05 + i * 0.055;
    const end = start + 0.42;
    if (t < start) return 0;
    if (t > end) return 1;
    return easeOut((t - start) / (end - start));
  };

  // Wordmark reveal: 0.55..0.95
  const wmProg = t < 0.55 ? 0 : t > 0.95 ? 1 : easeInOut((t - 0.55) / 0.4);

  return (
    <div style={{ position: 'relative', width, height, background: bg, overflow: 'hidden',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      cursor: clickToReplay ? 'pointer' : 'default', userSelect: 'none' }}
      onClick={clickToReplay ? () => setInternalPlayId((x) => x + 1) : undefined}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 28 }}>
        <svg width={height * 0.62} height={height * 0.62} viewBox="0 0 100 100">
          {finalHeights.map((h, i) => {
            const x = startX + i * (barW + gap);
            const p = barProgress(i);
            // overshoot: grow past target then settle
            const overshoot = p < 0.7
              ? p / 0.7
              : 1 + Math.sin((p - 0.7) / 0.3 * Math.PI) * 0.08;
            const liveH = h * maxH * overshoot;
            const y = baseY - liveH;
            const isPeak = i === finalHeights.length - 1;
            return (
              <rect key={i} x={x} y={y} width={barW} height={liveH} rx={barW / 2}
                fill={isPeak ? accent : fg} opacity={Math.min(1, p * 2)} />
            );
          })}
        </svg>
        <div style={{
          fontFamily: '"General Sans", "Inter", ui-sans-serif', fontWeight: 500,
          fontSize: height * 0.38, color: fg, letterSpacing: '-0.025em', lineHeight: 1,
          opacity: wmProg,
          transform: `translateX(${(1 - wmProg) * -16}px)`,
          transition: 'none',
        }}>Voxera</div>
      </div>
      {showCaption && (
        <div style={{ position: 'absolute', bottom: 10, right: 14,
          fontFamily: '"JetBrains Mono", monospace', fontSize: 10,
          letterSpacing: '0.12em', textTransform: 'uppercase',
          color: fg, opacity: 0.35 }}>
          click to replay · {Math.round(t * DURATION)}ms
        </div>
      )}
      {showProgress && (
        <div style={{ position: 'absolute', bottom: 0, left: 0, height: 2,
          width: `${t * 100}%`, background: accent, opacity: 0.6 }} />
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Compact loader pill — for buttons / inline "agent thinking"
// ─────────────────────────────────────────────────────────────
function CadencePill({ label = 'Agent speaking', color = '#0B0B0C', bg = 'transparent' }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10,
      padding: '8px 14px', background: bg, borderRadius: 999,
      border: `1px solid ${color}22`, fontFamily: '"Inter", ui-sans-serif',
      fontSize: 12, color, letterSpacing: '-0.005em' }}>
      <CadenceLoader size={20} color={color} speed={1.4} />
      {label}
    </div>
  );
}

Object.assign(window, { CadenceLoader, CadenceIntro, CadencePill });
