// Demo overlays — Cursor, Callout, TitleCard, ProgressBar, PlayerControls

// Animated demo cursor — moves to a target [data-id="..."] within the stage
function DemoCursor({ targetId, stageRef }) {
  const [pos, setPos] = React.useState(null);
  React.useEffect(() => {
    if (!targetId || !stageRef.current) { setPos(null); return; }
    let raf;
    const tick = () => {
      const el = stageRef.current.querySelector(`[data-id="${targetId}"]`);
      if (!el) { setPos(null); raf = requestAnimationFrame(tick); return; }
      const stage = stageRef.current.getBoundingClientRect();
      const r = el.getBoundingClientRect();
      const scale = stage.width / 1920;
      const x = (r.left - stage.left) / scale + (r.width / scale) * 0.62;
      const y = (r.top - stage.top) / scale + (r.height / scale) * 0.55;
      setPos({ x, y });
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [targetId]);
  if (!pos) return null;
  return (
    <div className="absolute pointer-events-none" style={{
      left: pos.x, top: pos.y, zIndex: 80,
      transform: "translate(-4px, -4px)",
      transition: "left 0.7s cubic-bezier(0.32, 0.72, 0, 1), top 0.7s cubic-bezier(0.32, 0.72, 0, 1)",
    }}>
      {/* halo */}
      <div style={{
        position: "absolute", left: -16, top: -16, width: 56, height: 56,
        borderRadius: "50%", background: "var(--accent-1)", opacity: 0.18,
        animation: "cursorPulse 1.4s ease-out infinite",
      }}/>
      <svg width="28" height="32" viewBox="0 0 28 32">
        <path d="M2 2 L2 24 L8 19 L12 28 L16 26 L12 17 L20 17 Z" fill="white" stroke="oklch(0.16 0.012 260)" strokeWidth="1.2" strokeLinejoin="round"/>
      </svg>
    </div>
  );
}

// Callout — connects to a target rect with a small line + tooltip
function Callout({ targetId, side = "right", title, body, stageRef }) {
  const [rect, setRect] = React.useState(null);
  React.useEffect(() => {
    if (!stageRef.current) return;
    if (!targetId) { setRect(null); return; }
    let raf;
    const tick = () => {
      const el = stageRef.current.querySelector(`[data-id="${targetId}"]`);
      if (!el) { setRect(null); raf = requestAnimationFrame(tick); return; }
      const stage = stageRef.current.getBoundingClientRect();
      const r = el.getBoundingClientRect();
      const scale = stage.width / 1920;
      setRect({
        x: (r.left - stage.left) / scale,
        y: (r.top - stage.top) / scale,
        w: r.width / scale,
        h: r.height / scale,
      });
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [targetId]);

  if (side === "center" || !targetId) {
    return (
      <div className="absolute pointer-events-none" style={{
        left: "50%", top: "50%", transform: "translate(-50%,-50%)", zIndex: 75,
        animation: "calloutIn 0.45s var(--ease-spring) both",
      }}>
        <CalloutBubble title={title} body={body} arrow={null}/>
      </div>
    );
  }
  if (!rect) return null;

  let pos, arrow;
  if (side === "right") {
    pos = { left: rect.x + rect.w + 32, top: rect.y + rect.h / 2 - 50 };
    arrow = "left";
  } else if (side === "left") {
    pos = { left: rect.x - 380 - 32, top: rect.y + rect.h / 2 - 50 };
    arrow = "right";
  } else if (side === "top") {
    pos = { left: rect.x + rect.w / 2 - 190, top: rect.y - 130 };
    arrow = "bottom";
  } else {
    pos = { left: rect.x + rect.w / 2 - 190, top: rect.y + rect.h + 32 };
    arrow = "top";
  }
  return (
    <div className="absolute pointer-events-none" style={{ ...pos, zIndex: 75, animation: "calloutIn 0.5s var(--ease-spring) both" }}>
      <CalloutBubble title={title} body={body} arrow={arrow}/>
    </div>
  );
}

function CalloutBubble({ title, body, arrow }) {
  return (
    <div style={{
      width: 380,
      background: "oklch(0.16 0.012 260)",
      color: "oklch(0.99 0.003 80)",
      borderRadius: 14,
      padding: "16px 18px",
      boxShadow: "0 24px 48px -12px oklch(0.10 0.01 260 / 0.35), 0 8px 16px -4px oklch(0.10 0.01 260 / 0.20), 0 0 0 1px oklch(0.30 0.012 260 / 0.6)",
      position: "relative",
    }}>
      <div className="flex items-center gap-2 mb-1.5">
        <div style={{ width: 6, height: 6, borderRadius: 99, background: "var(--accent-1)" }}/>
        <span style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", color: "oklch(0.75 0.05 268)" }}>Demo</span>
      </div>
      <div style={{ fontSize: 17, fontWeight: 600, letterSpacing: "-0.01em", lineHeight: 1.25 }}>{title}</div>
      <div style={{ fontSize: 13.5, lineHeight: 1.5, color: "oklch(0.85 0.005 260)", marginTop: 6 }}>{body}</div>
      {arrow && <CalloutArrow arrow={arrow}/>}
    </div>
  );
}

function CalloutArrow({ arrow }) {
  const styles = {
    left:   { left: -7,  top: "50%", transform: "translateY(-50%) rotate(45deg)" },
    right:  { right: -7, top: "50%", transform: "translateY(-50%) rotate(45deg)" },
    top:    { top: -7,  left: "50%", transform: "translateX(-50%) rotate(45deg)" },
    bottom: { bottom: -7, left: "50%", transform: "translateX(-50%) rotate(45deg)" },
  };
  return <div style={{ position: "absolute", width: 14, height: 14, background: "oklch(0.16 0.012 260)", borderLeft: arrow === "left" || arrow === "top" ? "1px solid oklch(0.30 0.012 260 / 0.6)" : "none", borderTop: arrow === "left" || arrow === "top" ? "1px solid oklch(0.30 0.012 260 / 0.6)" : "none", borderRight: arrow === "right" || arrow === "bottom" ? "1px solid oklch(0.30 0.012 260 / 0.6)" : "none", borderBottom: arrow === "right" || arrow === "bottom" ? "1px solid oklch(0.30 0.012 260 / 0.6)" : "none", ...styles[arrow] }}/>;
}

// Title card — large overlay for chapter intros
function TitleCard({ line1, line2 }) {
  return (
    <div className="absolute pointer-events-none flex flex-col items-start justify-end"
      style={{ left: 80, bottom: 96, zIndex: 70, animation: "titleIn 0.6s var(--ease-out) both" }}>
      <div style={{
        background: "oklch(0.16 0.012 260 / 0.94)",
        color: "white",
        padding: "20px 28px",
        borderRadius: 16,
        boxShadow: "0 24px 64px -12px oklch(0.10 0.01 260 / 0.5)",
        backdropFilter: "blur(20px)",
        maxWidth: 760,
      }}>
        <div className="flex items-center gap-2 mb-2.5">
          <div style={{ width: 8, height: 8, borderRadius: 99, background: "var(--accent-1)", boxShadow: "0 0 16px oklch(0.54 0.21 268 / 0.8)" }}/>
          <span style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.16em", textTransform: "uppercase", color: "oklch(0.78 0.05 268)" }}>Better Inventory</span>
        </div>
        <div style={{ fontFamily: "var(--font-display)", fontSize: 42, fontWeight: 500, letterSpacing: "-0.025em", lineHeight: 1.05 }}>{line1}</div>
        {line2 && <div style={{ fontFamily: "var(--font-display)", fontSize: 26, fontWeight: 400, letterSpacing: "-0.018em", lineHeight: 1.15, color: "oklch(0.78 0.05 268)", marginTop: 6 }}>{line2}</div>}
      </div>
    </div>
  );
}

// Progress bar at top
function ProgressBar({ t, scenes, duration }) {
  return (
    <div className="absolute top-0 left-0 right-0 h-1 z-[90] pointer-events-none">
      <div className="h-full bg-[var(--accent-1)] transition-[width] duration-200 ease-linear"
        style={{ width: `${(t / duration) * 100}%`, boxShadow: "0 0 12px oklch(0.54 0.21 268 / 0.6)" }}/>
    </div>
  );
}

// Player Controls — bottom bar with play/pause, scrubber, scene markers, time
function PlayerControls({ t, duration, playing, onTogglePlay, onSeek, onReset, scenes, isDemo, onToggleMode }) {
  return (
    <div className="fixed bottom-0 left-0 right-0 z-[100] pointer-events-none"
      style={{ padding: "0 24px 20px" }}>
      <div className="pointer-events-auto mx-auto" style={{ maxWidth: 1100 }}>
        <div style={{
          background: "oklch(0.16 0.012 260 / 0.92)",
          backdropFilter: "blur(20px)",
          borderRadius: 14,
          boxShadow: "0 24px 48px -12px oklch(0.10 0.01 260 / 0.4), 0 0 0 1px oklch(0.30 0.012 260 / 0.5)",
          padding: "10px 14px",
          display: "flex",
          alignItems: "center",
          gap: 14,
        }}>
          {/* Mode toggle */}
          <div className="flex items-center gap-1 p-0.5 rounded-md" style={{ background: "oklch(0.22 0.012 260)" }}>
            <button onClick={() => onToggleMode("demo")} className={cn("h-7 px-2.5 rounded text-[11.5px] font-medium transition-colors flex items-center gap-1.5", isDemo ? "bg-[var(--accent-1)] text-white" : "text-[oklch(0.75_0.01_260)] hover:text-white")}>
              <Icon name="play" size={11}/>Auto
            </button>
            <button onClick={() => onToggleMode("clickable")} className={cn("h-7 px-2.5 rounded text-[11.5px] font-medium transition-colors flex items-center gap-1.5", !isDemo ? "bg-white text-[var(--ink)]" : "text-[oklch(0.75_0.01_260)] hover:text-white")}>
              <Icon name="mouse-pointer-click" size={11}/>Click
            </button>
          </div>

          {isDemo && (
            <>
              <button onClick={onTogglePlay} className="w-9 h-9 rounded-full grid place-items-center text-white hover:bg-white/10">
                <Icon name={playing ? "pause" : "play"} size={15} strokeWidth={2.2}/>
              </button>
              <button onClick={onReset} className="w-8 h-8 rounded grid place-items-center text-white/70 hover:text-white hover:bg-white/10">
                <Icon name="rotate-ccw" size={13}/>
              </button>
              <div className="text-[11px] tabular-nums text-white/80 mono w-[70px] text-center">{fmtTime(t)} / {fmtTime(duration)}</div>

              {/* Scrubber */}
              <div className="flex-1 relative h-9 flex items-center" onClick={(e) => {
                const rect = e.currentTarget.getBoundingClientRect();
                const pct = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
                onSeek(pct * duration);
              }}>
                <div className="absolute left-0 right-0 h-1.5 rounded-full pointer-events-none" style={{ background: "oklch(0.30 0.012 260)" }}/>
                <div className="absolute left-0 h-1.5 rounded-full pointer-events-none"
                  style={{ width: `${(t / duration) * 100}%`, background: "var(--accent-1)" }}/>
                {/* scene markers */}
                {scenes.map((s, i) => (
                  <button key={i}
                    onClick={(e) => { e.stopPropagation(); onSeek(s.t); }}
                    title={s.label}
                    className="absolute -translate-x-1/2 w-1 h-3 rounded-sm hover:scale-y-150 transition-transform z-10"
                    style={{ left: `${(s.t / duration) * 100}%`, background: t >= s.t ? "var(--accent-1)" : "oklch(0.45 0.012 260)" }}/>
                ))}
                {/* thumb */}
                <div className="absolute w-3.5 h-3.5 rounded-full bg-white shadow-md pointer-events-none -translate-x-1/2"
                  style={{ left: `${(t / duration) * 100}%` }}/>
              </div>
            </>
          )}
          {!isDemo && (
            <div className="flex-1 flex items-center justify-between text-[12px] text-white/85 px-1 whitespace-nowrap">
              <span className="flex items-center gap-2 whitespace-nowrap"><Icon name="mouse-pointer-click" size={12}/>Click freely · navigate via sidebar</span>
              <span className="text-white/50 whitespace-nowrap">Switch to <span className="font-semibold text-white">Auto</span> for the 90s walkthrough</span>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function fmtTime(s) {
  const m = Math.floor(s / 60);
  const sec = Math.floor(s % 60);
  return `${m}:${sec.toString().padStart(2, "0")}`;
}

Object.assign(window, { DemoCursor, Callout, CalloutBubble, TitleCard, ProgressBar, PlayerControls });
