// demo-fx.jsx — Presentation layer for the product demo
// Screen frame, animated cursor, click ripples, key flashes, glow pulses,
// caption cards, scene-to-scene crossfades.

// ── SCREEN FRAME ─────────────────────────────────────────────────────────────
// Places an a1–a10 artboard inside a browser-chrome frame at a given position.
function ScreenFrame({ x = 160, y = 110, width = 1600, height = 860, url, chrome = 'browser', children, glow = false }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y, width, height,
      borderRadius: 14,
      overflow: 'hidden',
      boxShadow: glow
        ? '0 30px 80px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06), 0 0 140px 0 color-mix(in oklch, var(--primary) 35%, transparent)'
        : '0 30px 80px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06)',
      background: 'var(--bg-0)',
      transition: 'box-shadow 400ms',
    }}>
      {chrome === 'browser' && (
        <div style={{
          height: 38, background: 'oklch(0.14 0.005 80)',
          borderBottom: '1px solid rgba(255,255,255,0.06)',
          display: 'flex', alignItems: 'center', gap: 8, padding: '0 14px',
          flexShrink: 0,
        }}>
          <span style={{ width: 11, height: 11, borderRadius: 99, background: '#ff5f57' }}/>
          <span style={{ width: 11, height: 11, borderRadius: 99, background: '#febc2e' }}/>
          <span style={{ width: 11, height: 11, borderRadius: 99, background: '#28c840' }}/>
          <div style={{
            marginLeft: 20, padding: '5px 14px',
            background: 'rgba(255,255,255,0.05)',
            border: '1px solid rgba(255,255,255,0.08)',
            borderRadius: 6,
            fontFamily: 'IBM Plex Mono, monospace',
            fontSize: 11,
            color: 'rgba(246,244,239,0.65)',
            minWidth: 340,
          }}>
            <span style={{ color: 'rgba(246,244,239,0.3)' }}>🔒 </span>{url || 'coremindvault.com'}
          </div>
        </div>
      )}
      <div className="demo-screen-mount" style={{
        width: '100%',
        height: chrome === 'browser' ? 'calc(100% - 38px)' : '100%',
        overflow: 'hidden',
        position: 'relative',
      }}>
        {children}
      </div>
    </div>
  );
}

// ── CURSOR ───────────────────────────────────────────────────────────────────
// Animated cursor that moves between waypoints. waypoints: [{t, x, y}]
// Interpolates with easeInOutCubic. `clickAt` array triggers ripples at times.
function Cursor({ waypoints = [], clicks = [], scale = 1 }) {
  const t = useTime();

  // Find current & next waypoint
  let pos = { x: waypoints[0]?.x || 960, y: waypoints[0]?.y || 540 };
  let visible = t >= (waypoints[0]?.t || 0);

  for (let i = 0; i < waypoints.length - 1; i++) {
    const a = waypoints[i], b = waypoints[i + 1];
    if (t >= a.t && t <= b.t) {
      const span = b.t - a.t;
      const local = span > 0 ? (t - a.t) / span : 1;
      const eased = Easing.easeInOutCubic(local);
      pos = {
        x: a.x + (b.x - a.x) * eased,
        y: a.y + (b.y - a.y) * eased,
      };
      break;
    }
    if (t > b.t) pos = { x: b.x, y: b.y };
  }

  // Click squish animation
  let squish = 1;
  for (const c of clicks) {
    const dt = t - c.t;
    if (dt >= 0 && dt < 0.2) {
      squish = 1 - 0.22 * Math.sin((dt / 0.2) * Math.PI);
    }
  }

  if (!visible) return null;

  return (
    <>
      {/* Click ripples */}
      {clicks.map((c, i) => {
        const dt = t - c.t;
        if (dt < 0 || dt > 0.9) return null;
        const progress = dt / 0.9;
        const r = 6 + progress * 80;
        const opacity = (1 - progress) * 0.7;
        return (
          <div key={i} style={{
            position: 'absolute',
            left: c.x - r, top: c.y - r,
            width: r * 2, height: r * 2,
            border: `2px solid ${c.color || 'oklch(0.72 0.12 250)'}`,
            borderRadius: '50%',
            opacity,
            pointerEvents: 'none',
            boxShadow: `0 0 30px color-mix(in oklch, ${c.color || 'oklch(0.72 0.12 250)'} 60%, transparent)`,
          }}/>
        );
      })}
      {/* Cursor arrow */}
      <div style={{
        position: 'absolute',
        left: pos.x, top: pos.y,
        width: 28, height: 28,
        transform: `scale(${scale * squish})`,
        transformOrigin: '6px 4px',
        pointerEvents: 'none',
        filter: 'drop-shadow(0 4px 12px rgba(0,0,0,0.6))',
        zIndex: 1000,
      }}>
        <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
          <path d="M3 2.5 L3 18.5 L7.2 14.5 L10 21 L13 20 L10.3 13.5 L16.5 13.5 Z"
            fill="#ffffff" stroke="#0a0a0a" strokeWidth="1.2" strokeLinejoin="round"/>
        </svg>
      </div>
    </>
  );
}

// ── CAPTION CARD ─────────────────────────────────────────────────────────────
// Bottom-left caption card with chapter number, title, subtitle.
function Caption({ chapter, title, subtitle, position = 'bl', theme = 'dark' }) {
  const { progress, localTime, duration } = useSprite();
  const exitStart = Math.max(0, duration - 0.5);

  let opacity = 1;
  let ty = 0;
  if (localTime < 0.5) {
    const t = Easing.easeOutCubic(localTime / 0.5);
    opacity = t;
    ty = (1 - t) * 14;
  } else if (localTime > exitStart) {
    const t = Easing.easeInCubic((localTime - exitStart) / 0.5);
    opacity = 1 - t;
    ty = -t * 8;
  }

  const pos = {
    bl: { left: 64, bottom: 64 },
    br: { right: 64, bottom: 64 },
    tl: { left: 64, top: 64 },
    tr: { right: 64, top: 64 },
  }[position];

  return (
    <div style={{
      position: 'absolute', ...pos,
      opacity, transform: `translateY(${ty}px)`,
      zIndex: 500,
      background: 'rgba(14,14,14,0.78)',
      backdropFilter: 'blur(20px)',
      border: '1px solid rgba(255,255,255,0.08)',
      borderRadius: 14,
      padding: '20px 28px',
      minWidth: 360, maxWidth: 620,
      color: '#f6f4ef',
      fontFamily: 'IBM Plex Sans, system-ui, sans-serif',
      boxShadow: '0 20px 60px rgba(0,0,0,0.5)',
    }}>
      {chapter && (
        <div style={{
          fontFamily: 'IBM Plex Mono, monospace',
          fontSize: 11,
          color: 'rgba(246,244,239,0.5)',
          textTransform: 'uppercase',
          letterSpacing: '0.12em',
          marginBottom: 8,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <span style={{ width: 22, height: 1, background: 'rgba(246,244,239,0.3)' }}/>
          {chapter}
        </div>
      )}
      <div style={{
        fontSize: 24, fontWeight: 600, letterSpacing: '-0.015em',
        lineHeight: 1.2, marginBottom: subtitle ? 6 : 0,
      }}>{title}</div>
      {subtitle && (
        <div style={{
          fontSize: 14, color: 'rgba(246,244,239,0.65)',
          lineHeight: 1.45,
        }}>{subtitle}</div>
      )}
    </div>
  );
}

// ── KEY FLASH ────────────────────────────────────────────────────────────────
// Per-keystroke flash. Renders a series of small glows at (x,y) at times[].
function KeyFlashes({ times = [], x, y }) {
  const t = useTime();
  return (
    <>
      {times.map((kt, i) => {
        const dt = t - kt;
        if (dt < 0 || dt > 0.25) return null;
        const progress = dt / 0.25;
        const opacity = (1 - progress) * 0.8;
        return (
          <div key={i} style={{
            position: 'absolute',
            left: x - 14, top: y - 14,
            width: 28, height: 28,
            borderRadius: '50%',
            background: `radial-gradient(circle, color-mix(in oklch, var(--primary) 60%, transparent), transparent 70%)`,
            opacity,
            pointerEvents: 'none',
          }}/>
        );
      })}
    </>
  );
}

// ── GLOW PULSE ───────────────────────────────────────────────────────────────
// Rectangular glow highlight around a feature. Pulses in/out.
function GlowPulse({ x, y, w, h, start, end, color = 'oklch(0.72 0.12 250)', radius = 12, intensity = 1 }) {
  const t = useTime();
  if (t < start || t > end) return null;
  const dur = end - start;
  const local = (t - start) / dur;
  // Triangle pulse: fade in, hold, fade out
  let opacity;
  if (local < 0.3) opacity = local / 0.3;
  else if (local > 0.7) opacity = (1 - local) / 0.3;
  else opacity = 1;
  opacity *= intensity;

  return (
    <div style={{
      position: 'absolute', left: x, top: y, width: w, height: h,
      border: `2px solid ${color}`,
      borderRadius: radius,
      opacity,
      boxShadow: `0 0 0 4px color-mix(in oklch, ${color} 15%, transparent), 0 0 40px color-mix(in oklch, ${color} 40%, transparent)`,
      pointerEvents: 'none',
      zIndex: 900,
    }}/>
  );
}

// ── PROGRESS BAR (chapter progress at very top) ──────────────────────────────
function ChapterProgress({ chapters = [] }) {
  const { time, duration } = useTimeline();
  const active = chapters.findIndex(c => time >= c.start && time <= c.end);

  return (
    <div style={{
      position: 'absolute', top: 0, left: 0, right: 0, height: 3,
      display: 'flex', gap: 3, padding: '0 24px',
      marginTop: 18,
      zIndex: 600,
    }}>
      {chapters.map((c, i) => {
        const span = c.end - c.start;
        const local = Math.max(0, Math.min(1, (time - c.start) / span));
        const isActive = i === active;
        const isPast = time > c.end;
        return (
          <div key={i} style={{
            flex: 1, height: 3, borderRadius: 2,
            background: 'rgba(255,255,255,0.08)',
            overflow: 'hidden',
          }}>
            <div style={{
              width: `${(isPast ? 1 : isActive ? local : 0) * 100}%`,
              height: '100%',
              background: isActive || isPast ? 'oklch(0.78 0.1 250)' : 'transparent',
              transition: isPast ? 'none' : undefined,
            }}/>
          </div>
        );
      })}
    </div>
  );
}

// ── SCENE NUMBER BADGE ───────────────────────────────────────────────────────
function SceneBadge({ num, label }) {
  const { localTime, duration } = useSprite();
  const exitStart = Math.max(0, duration - 0.4);
  let opacity = 1;
  if (localTime < 0.4) opacity = Easing.easeOutCubic(localTime / 0.4);
  else if (localTime > exitStart) opacity = 1 - Easing.easeInCubic((localTime - exitStart) / 0.4);

  return (
    <div style={{
      position: 'absolute', top: 48, right: 64,
      opacity,
      zIndex: 500,
      fontFamily: 'IBM Plex Mono, monospace',
      fontSize: 12,
      color: 'rgba(246,244,239,0.55)',
      letterSpacing: '0.08em',
      textTransform: 'uppercase',
      display: 'flex', alignItems: 'center', gap: 10,
    }}>
      <span style={{ fontVariantNumeric: 'tabular-nums', color: '#f6f4ef', fontWeight: 600 }}>
        {String(num).padStart(2, '0')}
      </span>
      <span style={{ width: 1, height: 14, background: 'rgba(246,244,239,0.25)' }}/>
      <span>{label}</span>
    </div>
  );
}

Object.assign(window, {
  ScreenFrame, Cursor, Caption, KeyFlashes, GlowPulse, ChapterProgress, SceneBadge,
});
