/* global React, PetSprite, TOOLS */
const { useState: useStateHF, useEffect: useEffectHF, useRef: useRefHF, useCallback: useCallbackHF } = React;

/* ============================================================
   HIGH-FIDELITY NOTCH — collapsed pill + expanded panel
   Realistic MacBook geometry; integrates with site's PetSprite
   and TOOLS systems.
   ============================================================ */

/* State vocabulary — 6 canonical states */
const HF_STATE_KEYS = ["idle", "running", "approval", "rate", "done", "error"];
const HF_STATE_LABELS = {
  idle: "Idle", running: "Running", approval: "Approval",
  rate: "Rate limit", done: "Done", error: "Error",
};
const HF_STATE_MAP = {
  idle:     { tool: "claude-code", toolLabel: "Claude",       ticker: "Idle",                          color: "#9aa0a6", petState: "idle" },
  running:  { tool: "trae",        toolLabel: "Trae",         ticker: "Analyzing codebase · 47 files…", color: "#8b5cf6", petState: "running" },
  approval: { tool: "claude-code", toolLabel: "Claude",       ticker: "2 need approval",               color: "#f5b301", petState: "waitingInput" },
  rate:     { tool: "cursor",      toolLabel: "Cursor",       ticker: "Rate limit · GPT-4o",           color: "#ff9b3d", petState: "rateLimit" },
  done:     { tool: "factory",     toolLabel: "Factory Droid",ticker: "Branch ready · 17 commits",     color: "#00d6a3", petState: "running" },
  error:    { tool: "codex",       toolLabel: "Codex",        ticker: "Hook error · auth expired",     color: "#ff4d5e", petState: "error" },
};

/* ToolLogo — uses website's TOOLS palette */
function HfToolLogo({ tool, size = 16 }) {
  const t = (typeof TOOLS !== 'undefined' && TOOLS[tool]) || { mark: "··", tint: "#666" };
  return (
    <span
      className="tool-logo"
      style={{
        width: size, height: size,
        background: t.tint,
        color: textForBg ? textForBg(t.tint) : '#fff',
        fontSize: Math.round(size * 0.55),
        overflow: 'hidden',
      }}
    >
      {t.icon
        ? <img src={t.icon} alt="" style={{ width: '82%', height: '82%', objectFit: 'contain', display: 'block' }} />
        : t.mark}
    </span>
  );
}

/* Pet icon at island scale — uses the site's PetSprite, but capped tiny */
function HfPetIcon({ size = 18, state = "idle" }) {
  // PetSprite renders a 14x14 grid of box-shadows. To get an 18px pet we
  // request size ~= 18 (PixelSprite divides by max(rows,cols)=14, floors to
  // 1px — which gives a 14x14 dot grid that reads as a pet at this scale).
  return (
    <div className="pet-img" style={{ width: size, height: size, display: 'inline-grid', placeItems: 'center' }}>
      <PetSprite pet="capy" state={state} size={size} framed={false} />
    </div>
  );
}

/* Usage mini bar */
const HF_USAGE_PRESETS = {
  "5h":      { label: "5h",      pct: 62, color: "#f5b301" },
  "7d":      { label: "7d",      pct: 90, color: "#ff4d5e" },
  "context": { label: "Context", pct: 60, color: "#4d8eff" },
};
function HfUsageMini({ mode = "5h" }) {
  const u = HF_USAGE_PRESETS[mode] || HF_USAGE_PRESETS["5h"];
  if (mode === "context") {
    return (
      <div className="hf-usage-mini stacked">
        <span className="lbl">{u.label}</span>
        <div className="row">
          <div className="bar"><span style={{ width: `${u.pct}%`, background: u.color }} /></div>
          <span style={{ color: u.color }}>{u.pct}%</span>
        </div>
      </div>
    );
  }
  return (
    <div className="hf-usage-mini">
      <span style={{ color: u.color }}>{u.label}</span>
      <div className="bar"><span style={{ width: `${u.pct}%`, background: u.color }} /></div>
      <span style={{ color: u.color }}>{u.pct}%</span>
    </div>
  );
}

/* ─── Collapsed island (macbook-unified or virtual) ─────── */
function HfCollapsedIsland({
  scenario = "macbook",
  state = "running",
  variant = "pet+ticker",       // macbook: pet+ticker | name+usage
  density = "full",             // external: full | compact | usage
  usageMode = "5h",
  notchWidth = 120,
}) {
  const isVirtual = scenario === "external" || scenario === "virtual";
  const s = HF_STATE_MAP[state] || HF_STATE_MAP.idle;
  const accent = s.color;

  if (isVirtual) {
    return (
      <div className={`hf-island collapsed virtual state-${state}`}>
        <HfPetIcon size={16} state={s.petState} />
        <span className="tool-dot" style={{ background: accent }} />
        <span className="ticker tool-name" style={{ color: accent }}>{s.toolLabel}</span>
        {density === "usage" ? (
          <HfUsageMini mode={usageMode} />
        ) : (
          <>
            <span className="ticker label">{s.ticker}</span>
            {density === "full" && state === "approval" && <span className="approval-chip">⚡ 2</span>}
            {density === "full" && state === "rate"     && <span className="time-tag">8m</span>}
          </>
        )}
      </div>
    );
  }

  // MacBook unified — pill swallowing the physical notch
  return (
    <div className={`hf-island collapsed macbook-unified state-${state}`}>
      <div className="wing left">
        {variant === "pet+ticker" ? (
          <HfPetIcon size={14} state={s.petState} />
        ) : (
          <>
            <span className="tool-dot" style={{ background: accent }} />
            <span className="ticker tool-name" style={{ color: accent, fontSize: 10 }}>{s.toolLabel}</span>
          </>
        )}
      </div>
      <div className="notch-cutout" style={{ width: notchWidth, flex: `0 0 ${notchWidth}px` }} aria-hidden="true" />
      <div className="wing right">
        {variant === "pet+ticker" ? (
          <span className="ticker" style={{ color: accent, fontSize: 10, fontWeight: 600, maxWidth: 60 }}>
            {s.ticker.length > 8 ? s.ticker.slice(0, 8) + "…" : s.ticker}
          </span>
        ) : (
          <HfUsageMini mode={usageMode} />
        )}
      </div>
    </div>
  );
}

/* ─── Expanded panel ─────────────────────────────────────── */
const HF_INITIAL_MSGS = [
  { id: "1", type: "rate_limit",  tool: "cursor",      title: "Rate limit reached · GPT-4o",                  detail: "Claude Sonnet 4 available as fallback",       risk: null,   actions: ["mark_read", "ignore", "configure"], time: "8m ago" },
  { id: "2", type: "completion",  tool: "codex",       title: "Added Express auth middleware — 14 files, +247", detail: "~/dev/express-api · branch: feat/auth",      risk: null,   actions: ["mark_read", "jump"],                time: "5m ago" },
  { id: "3", type: "working",     tool: "trae",        title: "Analyzing codebase · 47 files…",                detail: "Est. 3–5 min remaining · ~12k tokens",        risk: null,   actions: ["ignore"],                            time: "now" },
];

const HF_APPROVAL_MSGS = [
  { id: "a1", type: "permission_request", tool: "claude-code", title: "Write to /dev/my-app/config.json",     detail: "cwd: ~/dev/my-app · shell: write file",       risk: "high",   actions: ["authorize", "reject", "ignore"], time: "2m ago" },
  { id: "a2", type: "permission_request", tool: "claude-code", title: 'Execute: git commit -am "feat: auth"', detail: "cwd: ~/dev/my-app · shell: exec command",     risk: "medium", actions: ["authorize", "reject", "ignore"], time: "3m ago" },
  { id: "a3", type: "rate_limit",         tool: "cursor",      title: "Rate limit reached · GPT-4o",          detail: "Claude Sonnet 4 available as fallback",       risk: null,     actions: ["mark_read", "ignore"],            time: "8m ago" },
];

const HF_RATE_MSGS = [
  { id: "r1", type: "rate_limit", tool: "cursor",      title: "Rate limit reached · GPT-4o", detail: "Resets in 23 minutes · 47 msgs queued",   risk: null, actions: ["configure", "ignore"], time: "just now" },
  { id: "r2", type: "rate_limit", tool: "codex",       title: "Quota cooldown — 6 min",      detail: "27 messages queued · resume at 15:30",    risk: null, actions: ["mark_read", "configure"], time: "2m ago" },
  { id: "r3", type: "completion", tool: "factory",     title: "Droid finished branch",       detail: "feat/onboard-flow · 17 commits ready",     risk: null, actions: ["mark_read", "jump"], time: "7m ago" },
];

const HF_DONE_MSGS = [
  { id: "d1", type: "completion", tool: "claude-code", title: "Wrote tests for 6 routes",     detail: "17 passed · 0 failed · 2 skipped",        risk: null, actions: ["mark_read", "jump"], time: "now" },
  { id: "d2", type: "completion", tool: "factory",     title: "Droid finished feat/onboard", detail: "17 commits · 4 tests passing",            risk: null, actions: ["mark_read", "jump"], time: "5m ago" },
  { id: "d3", type: "completion", tool: "cursor",      title: "Review ready · 6 files",      detail: "src/api/* · 3 suggestions, 1 risk",       risk: null, actions: ["mark_read", "jump"], time: "12m ago" },
];

const HF_ERROR_MSGS = [
  { id: "e1", type: "error",      tool: "codex",       title: "Hook error · auth expired",    detail: "Re-authorize codex-cli · token 31d old",  risk: "high",   actions: ["authorize", "ignore"], time: "now" },
  { id: "e2", type: "error",      tool: "gemini",      title: "Auth expired · gemini-cli",    detail: "Token rotated 31 days ago",                risk: "medium", actions: ["authorize", "ignore"], time: "11m ago" },
];

function HfExpandedIsland({ headerState = "running" }) {
  const initialFor = (st) =>
    st === "approval" ? HF_APPROVAL_MSGS :
    st === "rate"     ? HF_RATE_MSGS :
    st === "done"     ? HF_DONE_MSGS :
    st === "error"    ? HF_ERROR_MSGS :
    HF_INITIAL_MSGS;

  const [msgs, setMsgs] = useStateHF(() => initialFor(headerState));
  const [feedback, setFeedback] = useStateHF(null);
  const fbTimer = useRefHF(null);

  useEffectHF(() => { setMsgs(initialFor(headerState)); }, [headerState]);

  const showFb = (text) => {
    setFeedback(text);
    if (fbTimer.current) clearTimeout(fbTimer.current);
    fbTimer.current = setTimeout(() => setFeedback(null), 1400);
  };

  const handle = (id, action) => {
    if (action === "authorize")  { setMsgs(p => p.filter(m => m.id !== id)); showFb("Authorized"); }
    else if (action === "reject")  { setMsgs(p => p.filter(m => m.id !== id)); showFb("Rejected"); }
    else if (action === "ignore" || action === "mark_read") { setMsgs(p => p.filter(m => m.id !== id)); showFb("Marked read"); }
    else if (action === "jump")      showFb("Jumped to source");
    else if (action === "configure") showFb("Open AI Tools settings");
  };

  const head = HF_STATE_MAP[headerState] || HF_STATE_MAP.running;
  const approvalCount = msgs.filter(m => m.type === "permission_request").length;
  const petStateLabel =
    headerState === "approval" ? "waiting input" :
    headerState === "running"  ? "analyzing" :
    headerState === "rate"     ? "rate-limited" :
    headerState === "done"     ? "ready" :
    headerState === "error"    ? "error" : "idle";

  return (
    <div className="hf-island expanded" onClick={(e) => e.stopPropagation()}>
      {/* Top status bar */}
      <div className="exp-top">
        <div className="exp-top-left">
          <span className="exp-pulse" style={{ color: head.color, background: head.color }} />
          <span className="exp-top-tool" style={{ color: head.color }}>{head.toolLabel}</span>
          <span className="exp-top-text">· {head.ticker}</span>
        </div>
        <div className="exp-top-right">
          <button className="exp-icon-btn" title="Settings" onClick={(e) => { e.stopPropagation(); showFb("Settings"); }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="12" cy="12" r="3"/>
              <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
            </svg>
          </button>
        </div>
      </div>

      {/* Pet rail + tools tabs + usage bars */}
      <div className="exp-status">
        <div className="exp-pet-rail">
          <div className="pet-stage">
            <PetSprite pet="capy" state={head.petState} size={92} framed={false} />
          </div>
          <div className="exp-pet-state">{petStateLabel}</div>
        </div>
        <div>
          <div className="exp-tools-tabs">
            <span className="tab active">
              <span className="logo" style={{ background: '#d97757' }}>A</span>
              Claude
            </span>
            <span className="tab">
              <span className="logo" style={{ background: 'rgba(170,178,200,0.3)', color: '#aab2c8' }}>⚙</span>
              Codex
            </span>
            <span className="tab">
              <span className="logo" style={{ background: 'rgba(77,142,255,0.22)', color: '#4d8eff' }}>↖</span>
              Cursor
            </span>
            <span className="pager">
              <span className="active" />
              <span />
              <span />
            </span>
          </div>
          <div className="usage-row ok">
            <span className="label">Context window</span>
            <span className="value">48.2k / 200k <span className="pct">(24%)</span></span>
            <div className="bar-bg"><span style={{ width: "24%" }} /></div>
          </div>
          <div className="usage-row warn">
            <span className="label">5-hour limit</span>
            <span className="value">62% · resets 2h</span>
            <div className="bar-bg"><span style={{ width: "62%" }} /></div>
          </div>
          <div className="usage-row danger">
            <span className="label">Weekly · all models</span>
            <span className="value">Near limit</span>
            <div className="bar-bg"><span style={{ width: "92%" }} /></div>
          </div>
        </div>
      </div>

      {/* Messages header */}
      <div className="msgs-header">
        <span>Messages · {msgs.length} unread</span>
        <span className="actions">
          {approvalCount > 0 && (
            <span className="approval-pill">⚡ {approvalCount} need approval</span>
          )}
          <button className="exp-icon-btn small" title="Mark all read" onClick={(e) => { e.stopPropagation(); setMsgs([]); showFb("All marked read"); }}>
            <svg width="11" height="11" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M2 6l3 3 5-6"/></svg>
          </button>
          <button className="exp-icon-btn small danger" title="Clear all" onClick={(e) => { e.stopPropagation(); setMsgs([]); showFb("All cleared"); }}>
            <svg width="11" height="11" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4">
              <path d="M3 4h6M5 4v-1h2v1M4 4l.5 6h3L8 4"/>
            </svg>
          </button>
        </span>
      </div>

      {feedback && (
        <div style={{
          margin: "0 14px 6px", padding: "5px 10px",
          fontSize: 11, color: "#00d6a3",
          background: "rgba(0,214,163,0.10)",
          border: "1px solid rgba(0,214,163,0.25)",
          borderRadius: 8,
        }}>{feedback}</div>
      )}

      {/* Messages list */}
      <div className="msg-list">
        {msgs.length === 0 && <div className="msg-empty">✓ All clear</div>}
        {msgs.map(msg => <HfMessageCard key={msg.id} msg={msg} onAction={handle} />)}
      </div>

      {/* Footer */}
      <div className="exp-footer">
        <span>VibePet · agent pulse</span>
        <button className="quit" onClick={(e) => { e.stopPropagation(); showFb("Quit"); }}>
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M6 1v5M3 3a4 4 0 1 0 6 0"/></svg>
        </button>
      </div>
    </div>
  );
}

function HfMessageCard({ msg, onAction }) {
  const cls =
    msg.risk === "high"        ? "hf-msg high" :
    msg.risk === "medium"      ? "hf-msg warn" :
    msg.type === "rate_limit"  ? "hf-msg rate" :
    msg.type === "completion"  ? "hf-msg done" :
    msg.type === "working"     ? "hf-msg working" :
    msg.type === "error"       ? "hf-msg high" :
                                 "hf-msg";

  const typeLabel =
    msg.type === "permission_request" ? "Approval" :
    msg.type === "rate_limit"         ? "Rate Limit" :
    msg.type === "completion"         ? "Done" :
    msg.type === "working"            ? "Working" :
    msg.type === "error"              ? "Error" : "Notice";

  const badgeCls =
    msg.risk === "high"        ? "badge high" :
    msg.risk === "medium"      ? "badge warn" :
    msg.type === "rate_limit"  ? "badge rate" :
    msg.type === "completion"  ? "badge done" :
    msg.type === "working"     ? "badge working" :
    msg.type === "error"       ? "badge high" :
                                 "badge";

  const tDef = (typeof TOOLS !== 'undefined' && TOOLS[msg.tool]) || { name: msg.tool, mark: "··", tint: "#aaa" };

  const cfg = {
    authorize: { label: "Authorize", icon: "🛡", cls: "hf-btn primary" },
    reject:    { label: "Reject",    icon: "✕",  cls: "hf-btn danger" },
    ignore:    { label: "Ignore",    icon: "⊘",  cls: "hf-btn" },
    mark_read: { label: "Mark Read", icon: "✓✓", cls: "hf-btn" },
    configure: { label: "Configure", icon: "⚙",  cls: "hf-btn" },
    jump:      { label: "Jump",      icon: "↗",  cls: "hf-btn" },
  };

  return (
    <div className={cls}>
      <div className="hf-msg-row1">
        <span className="tool-logo" style={{ background: tDef.tint, color: textForBg ? textForBg(tDef.tint) : '#fff', overflow: 'hidden' }}>
          {tDef.icon
            ? <img src={tDef.icon} alt="" style={{ width: '82%', height: '82%', objectFit: 'contain', display: 'block' }} />
            : tDef.mark}
        </span>
        <span className="tool-name">{tDef.name}</span>
        <span className={badgeCls}>{typeLabel}</span>
        {msg.risk === "high" && <span className="badge high">⚠ HIGH</span>}
        <span className="time">{msg.time}</span>
      </div>
      <div className="hf-msg-title">{msg.title}</div>
      <div className="hf-msg-detail">{msg.detail}</div>
      <div className="hf-msg-actions">
        {msg.actions.map(a => {
          const c = cfg[a];
          if (!c) return null;
          return (
            <button key={a} className={c.cls} onClick={(e) => { e.stopPropagation(); onAction(msg.id, a); }}>
              <span>{c.icon}</span> {c.label}
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ─── Live island: hoverable + clickable, swaps collapsed/expanded ─ */
function HfLiveIsland({
  scenario = "macbook",
  initialState = "running",
  defaultExpanded = false,
  hoverEnabled = true,
  variant = "pet+ticker",
  density = "full",
  usageMode = "5h",
  notchWidth = 120,
  state: stateProp,
  onStateChange,
  onExpandedChange,
  forceExpanded,
}) {
  const [internalState, setInternalState] = useStateHF(initialState);
  const state = stateProp ?? internalState;
  const setState = (s) => {
    if (stateProp === undefined) setInternalState(s);
    onStateChange?.(s);
  };

  const [expanded, setExpanded] = useStateHF(defaultExpanded);
  useEffectHF(() => { onExpandedChange?.(expanded); }, [expanded]);

  // External / programmatic control (e.g. cursor demo). Each change forces a flip.
  useEffectHF(() => {
    if (forceExpanded === undefined) return;
    if (collapseTimer.current) { clearTimeout(collapseTimer.current); collapseTimer.current = null; }
    if (hoverTimer.current) { clearTimeout(hoverTimer.current); hoverTimer.current = null; }
    setExpanded(!!forceExpanded);
  }, [forceExpanded]);

  const hoverTimer = useRefHF(null);
  const collapseTimer = useRefHF(null);
  const wrapRef = useRefHF(null);

  const expand = useCallbackHF(() => {
    if (collapseTimer.current) { clearTimeout(collapseTimer.current); collapseTimer.current = null; }
    setExpanded(true);
  }, []);
  const collapse = useCallbackHF(() => {
    if (hoverTimer.current) { clearTimeout(hoverTimer.current); hoverTimer.current = null; }
    collapseTimer.current = setTimeout(() => setExpanded(false), 240);
  }, []);
  const onEnter = () => {
    if (!hoverEnabled) return;
    if (collapseTimer.current) { clearTimeout(collapseTimer.current); collapseTimer.current = null; }
    hoverTimer.current = setTimeout(expand, 280);
  };
  const onLeave = () => {
    if (!hoverEnabled) return;
    if (hoverTimer.current) { clearTimeout(hoverTimer.current); hoverTimer.current = null; }
    collapse();
  };
  const onClick = (e) => {
    e.stopPropagation();
    if (!expanded) {
      if (hoverTimer.current) { clearTimeout(hoverTimer.current); hoverTimer.current = null; }
      if (collapseTimer.current) { clearTimeout(collapseTimer.current); collapseTimer.current = null; }
      setExpanded(true);
    }
  };

  useEffectHF(() => {
    if (!expanded) return;
    const onDocClick = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setExpanded(false);
    };
    document.addEventListener("mousedown", onDocClick);
    return () => document.removeEventListener("mousedown", onDocClick);
  }, [expanded]);

  useEffectHF(() => () => {
    if (hoverTimer.current) clearTimeout(hoverTimer.current);
    if (collapseTimer.current) clearTimeout(collapseTimer.current);
  }, []);

  return (
    <div
      ref={wrapRef}
      className="hf-live-island"
      onMouseEnter={onEnter}
      onMouseLeave={onLeave}
      onClick={onClick}
      style={{ cursor: expanded ? "default" : "pointer" }}
    >
      {expanded
        ? <HfExpandedIsland headerState={state} />
        : <HfCollapsedIsland scenario={scenario} state={state} variant={variant} density={density} usageMode={usageMode} notchWidth={notchWidth} />
      }
    </div>
  );
}

/* ─── State chips control ────────────────────────────────── */
function HfStateChips({ state, onChange }) {
  return (
    <div className="hf-state-chips" onClick={(e) => e.stopPropagation()}>
      <span className="lbl">state</span>
      {HF_STATE_KEYS.map(k => (
        <button
          key={k}
          className={`chip ${state === k ? `active ${k}` : ""}`}
          onClick={() => onChange(k)}
        >
          {HF_STATE_LABELS[k]}
        </button>
      ))}
    </div>
  );
}

/* ─── Display chrome ─────────────────────────────────────── */
function HfMenuBar({ scenario = "macbook" }) {
  return (
    <div className="hf-menubar">
      <div className="hf-menubar-left">
        <span className="apple-glyph" aria-hidden="true">
          <svg width="11" height="11" viewBox="0 0 14 14" fill="currentColor">
            <path d="M9.8 7.2c0-1.9 1.6-2.8 1.6-2.8s-.9-1.3-2.3-1.3c-1 0-1.9.5-2.4.5s-1.2-.5-2.1-.5c-1.4 0-2.7 1.1-2.7 3.2 0 2 1.5 4.4 2.7 4.4.5 0 .9-.3 1.6-.3.7 0 1.1.3 1.7.3 1.2 0 2-1.8 2-1.8s-.1-.7-.1-1.7zM8.4 2.5c.5-.6.8-1.4.7-2.2-.7 0-1.5.5-2 1-.4.5-.8 1.3-.7 2.1.8.1 1.5-.4 2-.9z"/>
          </svg>
        </span>
        <span className="item">Finder</span>
        <span className="item dim">File</span>
        <span className="item dim">Edit</span>
        <span className="item dim">View</span>
        <span className="item dim">Window</span>
      </div>
      <div className="hf-menubar-right">
        <span>🔋 92%</span>
        <span>Wed 16:42</span>
      </div>
    </div>
  );
}

function HfCodeWindow({ style }) {
  return (
    <div className="hf-window" style={style}>
      <div className="titlebar">
        <span className="dot r" /><span className="dot y" /><span className="dot g" />
        <span className="name">~/dev/my-app — auth.ts</span>
      </div>
      <div className="body">
        <div><span className="k">import</span> {"{ Request, Response, NextFunction }"} <span className="k">from</span> <span className="s">"express"</span>;</div>
        <div><span className="k">import</span> jwt <span className="k">from</span> <span className="s">"jsonwebtoken"</span>;</div>
        <div>&nbsp;</div>
        <div><span className="c">// Verify caller has a valid bearer token</span></div>
        <div><span className="k">export const</span> <span className="f">authMiddleware</span> = (</div>
        <div>&nbsp;&nbsp;req: Request, res: Response, next: NextFunction</div>
        <div>) =&gt; {"{"}</div>
        <div>&nbsp;&nbsp;<span className="k">const</span> token = req.headers.authorization?.split(<span className="s">" "</span>)[<span className="n">1</span>];</div>
        <div>&nbsp;&nbsp;<span className="k">if</span> (!token) <span className="k">return</span> res.status(<span className="n">401</span>).json({"{ error: "}<span className="s">"Unauthorized"</span>{" }"});</div>
        <div>&nbsp;&nbsp;<span className="k">try</span> {"{"}</div>
        <div>&nbsp;&nbsp;&nbsp;&nbsp;<span className="k">const</span> payload = jwt.verify(token, <span className="f">env</span>.JWT_SECRET);</div>
        <div>&nbsp;&nbsp;&nbsp;&nbsp;(req <span className="k">as any</span>).user = payload;</div>
        <div>&nbsp;&nbsp;&nbsp;&nbsp;<span className="f">next</span>();</div>
        <div>&nbsp;&nbsp;{"}"} <span className="k">catch</span> {"{"}</div>
        <div>&nbsp;&nbsp;&nbsp;&nbsp;res.status(<span className="n">401</span>).json({"{ error: "}<span className="s">"Invalid token"</span>{" }"});</div>
      </div>
    </div>
  );
}

function HfDock({ apps = 5 }) {
  const cls = ["", "b", "c", "d", "e"];
  return (
    <div className="hf-dock">
      {Array.from({ length: apps }).map((_, i) => <span key={i} className={`app ${cls[i % cls.length]}`} />)}
    </div>
  );
}

/* ─── MacBook scene ──────────────────────────────────────── */
function HfMacBookScene({
  width = 1080, height = 680,
  scale = 1,
  scenario = "macbook",
  islandState = "running",
  defaultExpanded = false,
  showChips = true,
  hoverEnabled = true,
  variant = "pet+ticker",
  usageMode = "5h",
  notchWidth = 120,
  caption,
  showCodeWindow = true,
  showDock = true,
  showMenuBar = true,
  size = "default",   // default | mini
  demo = false,       // animated cursor demo overlay
}) {
  const [state, setState] = useStateHF(islandState);
  const [expanded, setExpanded] = useStateHF(defaultExpanded);
  const [forceExpand, setForceExpand] = useStateHF(undefined);
  useEffectHF(() => { setState(islandState); }, [islandState]);
  useEffectHF(() => { setExpanded(defaultExpanded); }, [defaultExpanded]);

  const padX = size === "mini" ? 24 : 36;
  const padTop = size === "mini" ? 36 : 56;
  const padBottom = size === "mini" ? 8 : 56;

  // When scale != 1, render the display at natural size, scale it, and
  // reserve the scaled-down layout box on the wrapper so siblings flow correctly.
  const scaledW = width * scale;
  const scaledH = height * scale;

  return (
    <div className="hf-display-wrap" style={{ width: scaledW }}>
      {caption && <div className="hf-display-caption">{caption}</div>}
      <div
        className="hf-display-scaler"
        style={{
          width: scaledW,
          height: scaledH,
          position: "relative",
          overflow: "visible",
        }}
      >
        <div
          className={`hf-display macbook ${size === "mini" ? "mini" : ""}`}
          style={{
            width,
            height,
            transform: scale === 1 ? undefined : `scale(${scale})`,
            transformOrigin: "top left",
          }}
        >
          <div className="wallpaper" />
          {showMenuBar && <HfMenuBar scenario={scenario} />}
          <div className="hf-notch-wrap">
            <HfLiveIsland
              scenario={scenario}
              initialState={state}
              state={state}
              defaultExpanded={defaultExpanded}
              variant={variant}
              usageMode={usageMode}
              notchWidth={notchWidth}
              hoverEnabled={hoverEnabled}
              key={`${state}-${variant}-${usageMode}`}
              onExpandedChange={setExpanded}
              forceExpanded={forceExpand}
            />
          </div>
          {showCodeWindow && (
            <HfCodeWindow style={{
              left: padX, top: padTop,
              width: width - padX * 2, height: height - padTop - padBottom,
            }} />
          )}
          {showDock && <HfDock />}
          {showChips && <HfStateChips state={state} onChange={setState} />}
          {demo && (
            <HfCursorDemo
              width={width}
              height={height}
              onForceExpand={setForceExpand}
            />
          )}
        </div>
      </div>
    </div>
  );
}

/* ─── Cursor demo overlay ───────────────────────────────────
   Animated white cursor that scrolls in, hovers the notch to expand it,
   "grabs" the pet, and drags it onto the desktop. Bails as soon as the
   user moves their real pointer over the scene. */
function HfCursorDemo({ width, height, onForceExpand }) {
  const rootRef = useRefHF(null);
  const [armed, setArmed] = useStateHF(false);   // intersected viewport
  const [cancelled, setCancelled] = useStateHF(false); // user took over
  const [cycle, setCycle] = useStateHF(0);       // loop counter
  const [pose, setPose] = useStateHF({
    x: -80, y: height * 0.85,
    visible: false, clicking: false, dragging: false,
  });
  const [landed, setLanded] = useStateHF(null);  // {x,y} where pet rests

  // Waypoints in unscaled scene coordinates.
  // Pet is inside the expanded panel near its top-left; lift it UP and OUT of the panel
  // before sliding diagonally to the desktop, so the extraction is unambiguous.
  const panelTop = 30;                    // panel sits flush below the notch (y ~30)
  const panelBottom = panelTop + 440;     // expanded panel min-height
  const wp = {
    start:  { x: width * 0.06,           y: height * 0.78 },
    notch:  { x: width / 2 + 6,          y: 24 },
    pet:    { x: width / 2 - 195,        y: panelTop + 88 },     // inside the panel, on the pet sprite
    lifted: { x: width / 2 - 195,        y: panelTop - 36 },     // above the panel, out in open air
    desk:   { x: width * 0.18,           y: panelBottom + 36 },  // bottom-left desktop
    offX:   { x: -80,                    y: height * 0.85 },
  };

  // IntersectionObserver: arm on first scroll-into-view
  useEffectHF(() => {
    if (!rootRef.current) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting && !armed && !cancelled) setArmed(true);
    }, { threshold: 0.3 });
    io.observe(rootRef.current);
    return () => io.disconnect();
  }, [armed, cancelled]);

  // User pointer takes over → cancel demo
  useEffectHF(() => {
    if (!rootRef.current || cancelled) return;
    const scene = rootRef.current.closest('.hf-display');
    if (!scene) return;
    const handler = () => setCancelled(true);
    scene.addEventListener('pointerenter', handler);
    return () => scene.removeEventListener('pointerenter', handler);
  }, [cancelled]);

  // Timeline
  useEffectHF(() => {
    if (!armed || cancelled) return;
    const timers = [];
    const rafs = [];
    let stopped = false;
    const at = (t, fn) => timers.push(setTimeout(() => { if (!stopped) fn(); }, t));
    const ease = (u) => u < 0.5 ? 2*u*u : 1 - Math.pow(-2*u + 2, 2) / 2;
    const tween = (from, to, dur) => {
      const t0 = performance.now();
      const step = () => {
        if (stopped) return;
        const u = Math.min(1, (performance.now() - t0) / dur);
        const e = ease(u);
        setPose(p => ({ ...p, x: from.x + (to.x - from.x) * e, y: from.y + (to.y - from.y) * e }));
        if (u < 1) rafs.push(requestAnimationFrame(step));
      };
      rafs.push(requestAnimationFrame(step));
    };

    // 0ms — cursor fades in down-left
    at(0,    () => setPose(p => ({ ...p, ...wp.start, visible: true, clicking: false, dragging: false, popping: false })));
    // 350ms — glide up toward notch
    at(350,  () => tween(wp.start, wp.notch, 1100));
    // 1500ms — trigger hover/expand
    at(1500, () => onForceExpand?.(true));
    // 2200ms — move down to the pet inside the expanded panel
    at(2200, () => tween(wp.notch, wp.pet, 700));
    // 2950ms — click flash on the panel pet
    at(2950, () => setPose(p => ({ ...p, clicking: true })));
    // 3150ms — grab: dragged pet appears AT panel-pet location with a "popping" scale
    at(3150, () => setPose(p => ({ ...p, clicking: false, dragging: true, popping: true })));
    // 3450ms — lift the pet UP and OUT of the panel (vertical extraction)
    at(3450, () => { setPose(p => ({ ...p, popping: false })); tween(wp.pet, wp.lifted, 450); });
    // 3950ms — now slide diagonally to the desktop drop zone
    at(3950, () => tween(wp.lifted, wp.desk, 1100));
    // 5100ms — release; pet lands
    at(5100, () => {
      setPose(p => ({ ...p, dragging: false }));
      setLanded({ ...wp.desk });
    });
    // 5400ms — collapse the island back
    at(5400, () => onForceExpand?.(false));
    // 6000ms — move cursor away
    at(6000, () => tween(wp.desk, wp.offX, 900));
    // 7000ms — hide cursor; cycle done
    at(7000, () => setPose(p => ({ ...p, visible: false })));
    // 7800ms — clear landed pet, then loop
    at(7800, () => setLanded(null));
    at(8300, () => { if (!stopped && !cancelled) setCycle(c => c + 1); });

    return () => {
      stopped = true;
      timers.forEach(clearTimeout);
      rafs.forEach(cancelAnimationFrame);
    };
  }, [armed, cancelled, cycle, width, height]);

  return (
    <div ref={rootRef} className="hf-cursor-demo" aria-hidden="true">
      {landed && (
        <div className="hf-landed-pet" style={{ left: landed.x - 32, top: landed.y - 50 }}>
          <PetSprite pet="capy" state="idle" size={64} framed={false} />
        </div>
      )}
      {pose.visible && !cancelled && (
        <>
          {pose.dragging && (
            <div
              className={`hf-dragged-pet ${pose.popping ? 'popping' : ''}`}
              style={{ left: pose.x - 26, top: pose.y - 30 }}
            >
              <PetSprite pet="capy" state="running" size={52} framed={false} />
            </div>
          )}
          <div
            className={`hf-demo-cursor ${pose.clicking ? 'clicking' : ''} ${pose.dragging ? 'dragging' : ''}`}
            style={{ left: pose.x, top: pose.y }}
          >
            <svg width="26" height="32" viewBox="0 0 24 28" fill="none">
              <path
                d="M3 2 L3 22 L8.5 17.5 L11.5 24 L15 22.5 L12 16 L19 15 Z"
                fill="#fff"
                stroke="#0a0a0a"
                strokeWidth="1.2"
                strokeLinejoin="round"
              />
            </svg>
            <span className="hf-click-ring" />
          </div>
        </>
      )}
    </div>
  );
}

Object.assign(window, {
  HF_STATE_KEYS, HF_STATE_LABELS, HF_STATE_MAP,
  HfCollapsedIsland, HfExpandedIsland, HfLiveIsland, HfStateChips,
  HfMacBookScene, HfMenuBar, HfCodeWindow, HfDock,
  HfUsageMini, HfPetIcon, HfToolLogo,
  HfCursorDemo,
});
