// Agentic Review Center — main orchestrator (manual → scan → triage → resolve → trust → payoff).
const APP = window.RP;

function ReviewApp() {
  const { Sidebar, TopBar, Tabs, AgentBanner, TrustLevel, Tag, Avatar, Flag, Icon, Button, Switch } = APP;
  const D = window.RC_DATA;
  const { IssueDetail, SeverityPill, CountUp, rcNow } = window;

  const [phase, setPhase] = React.useState("manual");   // manual | scanning | triaged
  const [view, setView] = React.useState("review");      // review | trust | playbooks
  const [nav, setNav] = React.useState("review");
  const [bucket, setBucket] = React.useState("clarify");
  const [selIssue, setSelIssue] = React.useState(null);
  const [status, setStatus] = React.useState({});        // issueId -> state
  const [autoAt, setAutoAt] = React.useState({});
  // Trust Levels — risk-tier × autonomy model (the user owns both axes)
  const [autonomy, setAutonomy] = React.useState({ low: "suggest", med: "suggest", high: "ask" });
  const [signals, setSignals] = React.useState({ amount: 25000, frequency: true, novelty: true, baseline: true });
  const [catOverride, setCatOverride] = React.useState({}); // category -> "ask" (stricter override)
  const [drafts, setDrafts] = React.useState(() => Object.fromEntries(D.issues.filter(i => i.draft).map(i => [i.id, i.draft])));
  const [toast, setToast] = React.useState(null);
  const [askOpen, setAskOpen] = React.useState(false);
  const [pbPrompt, setPbPrompt] = React.useState(false);
  const [pbAdded, setPbAdded] = React.useState(false);
  const [playbooks, setPlaybooks] = React.useState(D.playbooks);
  const [profile, setProfile] = React.useState(D.reviewerProfile);  // Reviewer Profile (memory)
  const [editIdx, setEditIdx] = React.useState(-1);
  const [editText, setEditText] = React.useState("");
  const [resolvedRounding, setResolvedRounding] = React.useState(0);
  const [autoHiddenGroups, setAutoHiddenGroups] = React.useState([]); // routine groups the user undid

  // ---- Manual (pre-agent) interactivity: clickable categories + transparent learning ----
  const [cat, setCat] = React.useState("payroll");          // active category tab
  const [manualResolved, setManualResolved] = React.useState({}); // itemId -> "approved" | "declined"
  const [patternCount, setPatternCount] = React.useState({});     // patternKey -> # approvals
  const [learnPrompt, setLearnPrompt] = React.useState(null);     // { patternKey, pattern, category }
  const [learnings, setLearnings] = React.useState([]);           // accepted implicit rules (transparent)

  // ---- Guided demo tour + custom rules ----
  const [tourOn, setTourOn] = React.useState(true);
  const [newRule, setNewRule] = React.useState("");

  // Restart the whole walkthrough so the full 18 always come back (no reload needed).
  function resetDemo() {
    setPhase("manual"); setView("review"); setNav("review"); setBucket("clarify"); setSelIssue(null);
    setStatus({}); setAutoAt({}); setAutonomy({ low: "suggest", med: "suggest", high: "ask" });
    setSignals({ amount: 25000, frequency: true, novelty: true, baseline: true });
    setCatOverride({}); setDrafts(Object.fromEntries(D.issues.filter(i => i.draft).map(i => [i.id, i.draft])));
    setToast(null); setAskOpen(false); setPbPrompt(false); setPbAdded(false);
    setPlaybooks(D.playbooks); setProfile(D.reviewerProfile); setEditIdx(-1); setEditText("");
    setResolvedRounding(0); setAutoHiddenGroups([]); setCat("payroll"); setManualResolved({}); setPatternCount({});
    setLearnPrompt(null); setLearnings([]); setNewRule(""); setTourOn(true);
    flash("Demo reset. All 132 items are back.");
  }

  const catLabel = (k) => (D.tabs.find(t => t.key === k) || {}).label || k;
  function catResolvedCount(k) { return (D.reviewQueues[k] || []).filter(it => manualResolved[it.id]).length; }

  function manualResolve(item, decision) {
    setManualResolved(m => ({ ...m, [item.id]: decision }));
    flash(decision === "approved" ? "Approved" : "Declined");
    if (decision === "approved" && item.patternKey && item.band === "low") {
      setPatternCount(pc => {
        const n = (pc[item.patternKey] || 0) + 1;
        const already = learnings.some(l => l.patternKey === item.patternKey);
        if (n >= 2 && !already) setLearnPrompt({ patternKey: item.patternKey, pattern: item.pattern, category: cat });
        return { ...pc, [item.patternKey]: n };
      });
    }
  }

  function acceptLearning() {
    const lp = learnPrompt; if (!lp) return;
    const n = patternCount[lp.patternKey] || 2;
    const rule = { patternKey: lp.patternKey, name: "Auto-approve " + lp.pattern, scope: catLabel(lp.category) + " · low-risk only", auto: "your last " + n + " approvals", on: true, system: false, confidence: "High" };
    setLearnings(ls => [rule, ...ls]);
    setPlaybooks(p => [rule, ...p]);
    setProfile(pr => [{ text: "You auto-approve " + lp.pattern + ".", source: "your last " + n + " approvals" }, ...pr]);
    setLearnPrompt(null);
    flash("Saved to your Reviewer Profile and Playbooks. Edit it any time");
  }

  const toastTimer = React.useRef(null);
  function flash(msg) { setToast(msg); clearTimeout(toastTimer.current); toastTimer.current = setTimeout(() => setToast(null), 2600); }

  // Trust-driven auto handling: when Low-risk autonomy = Auto, low-risk items auto-resolve (reversible).
  React.useEffect(() => {
    const enable = autonomy.low === "auto" && catOverride["Expenses"] !== "ask";
    setStatus(prev => {
      const next = { ...prev }; const at = {}; let changed = false;
      D.issues.forEach(i => {
        if (!i.lowExpense) return;
        if (enable && (next[i.id] === undefined || next[i.id] === "open")) { next[i.id] = "auto"; at[i.id] = rcNow(); changed = true; }
        else if (!enable && next[i.id] === "auto") { next[i.id] = "open"; changed = true; }
      });
      if (Object.keys(at).length) setAutoAt(a => ({ ...a, ...at }));
      return changed ? next : prev;
    });
  }, [autonomy.low, catOverride]);

  function st(id) { return status[id] || "open"; }
  const open = (i) => st(i.id) === "open";

  // bucket membership
  function inBucket(i, b) {
    const s = st(i.id);
    if (s === "auto") return b === "auto";
    if (s === "approved" || s === "declined" || s === "dismissed") return false;
    if (s === "waiting") return b === "clarify";
    return i.bucket === b; // open
  }
  const list = (b) => D.issues.filter(i => inBucket(i, b));

  // headline counts. Auto = the 114 routine items the agent cleared + any flagged low-risk it auto-handled.
  const visibleGroups = D.routineGroups.filter(g => !autoHiddenGroups.includes(g.label));
  const routineCount = visibleGroups.reduce((s, g) => s + g.count, 0);
  const base = { decide: 7, clarify: 4 };
  const counts = {
    auto: routineCount + list("auto").length,
    decide: base.decide + list("decide").length,
    clarify: base.clarify + list("clarify").length,
  };

  const selectedIssue = D.issues.find(i => i.id === selIssue);
  const resolvedCount = D.issues.filter(i => ["approved", "declined", "dismissed", "auto", "waiting"].includes(st(i.id))).length;
  const protectedAmt = D.issues.filter(i => ["approved", "declined", "dismissed", "auto", "waiting"].includes(st(i.id))).reduce((s, i) => s + (i.riskNum || 0), 0);

  function resolve(id, state) {
    const iss = D.issues.find(x => x.id === id);
    setStatus(s => ({ ...s, [id]: state }));
    if (iss && iss.lowExpense && (state === "approved" || state === "dismissed")) {
      setResolvedRounding(c => {
        const n = c + 1;
        if (n >= 1 && !pbAdded) setTimeout(() => setPbPrompt(true), 500);
        return n;
      });
    }
    // advance selection to next open issue in bucket
    const b = iss ? (iss.bucket) : bucket;
    const nextOpen = D.issues.find(x => x.bucket === b && st(x.id) === "open" && x.id !== id);
    if (nextOpen) setSelIssue(nextOpen.id);
  }

  function addPlaybook() {
    setPbAdded(true); setPbPrompt(false);
    setPlaybooks(p => [{ name: "Auto-approve sub-$5 currency rounding", scope: "Expenses · |diff| < $5", auto: "your last 3 decisions", on: true, system: false }, ...p]);
    // auto-resolve remaining rounding items
    setStatus(prev => { const next = { ...prev }; const at = {}; D.issues.forEach(i => { if (i.lowExpense && (next[i.id] === undefined || next[i.id] === "open")) { next[i.id] = "auto"; at[i.id] = rcNow(); } }); setAutoAt(a => ({ ...a, ...at })); return next; });
    flash("Playbook added. Applied to 3 items");
  }

  function undo(id) {
    setStatus(s => { const n = { ...s }; delete n[id]; return n; });
    flash("Action undone");
  }

  function runAgent() {
    setPhase("scanning");
    setTimeout(() => { setPhase("triaged"); setBucket("clarify"); flash("132 scanned. 114 routine items cleared, 18 need you."); }, 2000);
  }

  // ---- Sidebar nav ----
  const navItems = [
    { key: "activity", label: "Activity", icon: "House" },
    { key: "people", label: "People", icon: "Users" },
    { key: "payroll", label: "Payroll", icon: "DollarSign" },
    { key: "review", label: "Review", icon: "ListChecks" },
    { key: "documents", label: "Documents", icon: "Paperclip" },
    { key: "reports", label: "Reports", icon: "ChartPie" },
    { key: "trust", label: "Agent", icon: "WandSparkles" },
  ];
  function onNav(k) { setNav(k); if (k === "trust") setView("trust"); else if (k === "review") setView("review"); else setView("other"); }

  // ---- Guided tour: which step are we on, and what to point at ----
  const TOUR_TOTAL = 6;
  function currentTour() {
    if (!tourOn || nav === "other") return null;
    if (view === "review" && phase !== "triaged")
      return { step: "run", idx: 1, text: "Start here. Run the agent on your 132-item queue and watch it triage." };
    if (view === "review" && phase === "triaged") {
      if (!selIssue)
        return { step: "issue-list", idx: 2, text: "The agent cleared 114 routine items and surfaced 18. Open the first one to see its evidence." };
      if (resolvedCount === 0)
        return { step: "issue-actions", idx: 3, text: "Read the evidence, then send the agent's drafted question, or approve / decline." };
      if (autonomy.low !== "auto")
        return { step: "trust-btn", idx: 4, text: "Now open Trust Levels to decide how much the agent may handle on its own." };
      return { step: "playbooks-btn", idx: 6, text: "Last step. Open Playbooks to see what it learned, and add a rule of your own." };
    }
    if (view === "trust") {
      if (autonomy.low !== "auto")
        return { step: "low-tier", idx: 5, text: "Set Low risk to Auto. Routine low-risk items clear themselves, and every one is reversible." };
      return { step: "back", idx: 5, text: "Done. Go back to the queue to see them auto-handled, then open Playbooks." };
    }
    if (view === "playbooks")
      return { step: "addrule", idx: 6, text: "This is what the agent learned from you. Add your own rule in plain words and it will follow it." };
    return null;
  }
  const tourInfo = currentTour();

  return (
    <div className="rp-shell">
      <Sidebar items={navItems} active={nav} onSelect={onNav} onAdd={() => {}} />
      <div className="rp-main">
        <TopBar logo={<img src={(window.__resources && window.__resources.logo) || "assets/logo-remotepass.png"} alt="RemotePass" style={{ height: 26 }} />} user={{ name: D.user.name }} onAskAi={() => setAskOpen(true)} />
        <div className="rp-scroll">
          {view === "review" && (phase === "triaged" ? Triaged() : Manual())}
          {view === "trust" && TrustView()}
          {view === "playbooks" && PlaybooksView()}
          {view === "other" && Other()}
          <window.AskAiDrawer open={askOpen} onClose={() => setAskOpen(false)} />
        </div>
      </div>
      {toast && (
        <div style={{ position: "absolute", bottom: 24, left: "50%", transform: "translateX(-50%)", zIndex: 60, background: "var(--rp-ink)", color: "#fff", fontWeight: 700, fontSize: 14, padding: "12px 20px", borderRadius: 8, boxShadow: "var(--rp-shadow-pop)", display: "flex", alignItems: "center", gap: 10 }}>
          <Icon name="Check" size={16} color="#fff" stroke={2.6} />{toast}
        </div>
      )}

      {/* Demo controls: restart + guide toggle */}
      <div style={{ position: "absolute", bottom: 16, right: 16, zIndex: 62, display: "flex", gap: 8 }}>
        <button onClick={() => setTourOn(t => !t)} title="Toggle the guided walkthrough"
          style={{ display: "inline-flex", alignItems: "center", gap: 6, background: tourOn ? "var(--rp-ai-soft)" : "#fff", border: "1px solid " + (tourOn ? "#E3D8FA" : "var(--rp-border-strong)"), color: tourOn ? "var(--rp-ai-indigo)" : "var(--rp-muted)", borderRadius: 9999, padding: "7px 13px", fontWeight: 700, fontSize: 12.5, cursor: "pointer", fontFamily: "var(--font-sans)", boxShadow: "var(--rp-shadow-card)" }}>
          <Icon name="Compass" size={14} color={tourOn ? "var(--rp-ai-indigo)" : "var(--rp-muted)"} />{tourOn ? "Guide on" : "Guide off"}
        </button>
        <button onClick={resetDemo} title="Restart the demo so all 18 issues come back"
          style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "#fff", border: "1px solid var(--rp-border-strong)", color: "var(--rp-muted)", borderRadius: 9999, padding: "7px 13px", fontWeight: 700, fontSize: 12.5, cursor: "pointer", fontFamily: "var(--font-sans)", boxShadow: "var(--rp-shadow-card)" }}>
          <Icon name="RotateCcw" size={14} color="var(--rp-muted)" />Restart demo
        </button>
      </div>

      {tourInfo && <window.TourCoach step={tourInfo.step} text={tourInfo.text} idx={tourInfo.idx} total={TOUR_TOTAL} onSkip={() => setTourOn(false)} />}
    </div>
  );

  // ===== MANUAL (pre-agent) =====
  function Manual() {
    const items = (D.reviewQueues[cat] || []).filter(it => !manualResolved[it.id]);
    const remaining = D.tabs.reduce((s, t) => s + (t.count - catResolvedCount(t.key)), 0);
    const dynTabs = D.tabs.map(t => ({ ...t, count: t.count - catResolvedCount(t.key) }));
    return (
      <div style={{ padding: "24px 32px 48px" }}>
        <h1 style={{ fontSize: 28, marginBottom: 16 }}>Items to review</h1>

        {/* Prominent agent CTA — the way out of the manual toil */}
        <div style={{ display: "flex", alignItems: "center", gap: 18, background: "var(--rp-ai-gradient)", borderRadius: 12, padding: "18px 22px", marginBottom: 18, color: "#fff", boxShadow: "var(--rp-shadow-ai)" }}>
          <span style={{ width: 46, height: 46, borderRadius: "50%", background: "rgba(255,255,255,.18)", display: "grid", placeItems: "center", flex: "none" }}><Icon name="WandSparkles" size={22} color="#fff" stroke={2.2} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 17, fontWeight: 800 }}>{remaining} items waiting. Reviewing them one at a time is slow.</div>
            <div style={{ fontSize: 13.5, opacity: .9, marginTop: 2 }}>The Review Agent scans all 8 categories at once, then triages what's left into three clear buckets.</div>
          </div>
          <button onClick={runAgent} disabled={phase === "scanning"} data-tour="run" style={{ display: "inline-flex", alignItems: "center", gap: 9, background: "#fff", color: "var(--rp-ai-indigo)", border: "none", borderRadius: 8, padding: "13px 22px", fontWeight: 800, fontSize: 15, fontFamily: "var(--font-sans)", cursor: phase === "scanning" ? "default" : "pointer", flex: "none", boxShadow: "0 4px 14px rgba(15,16,53,.18)" }}>
            <Icon name={phase === "scanning" ? "LoaderCircle" : "WandSparkles"} size={18} color="var(--rp-ai-indigo)" stroke={2.4} />
            {phase === "scanning" ? "Scanning for issues…" : "Run Review Agent"}
          </button>
        </div>

        <div style={{ background: "#fff", borderRadius: 8, boxShadow: "var(--rp-shadow-card)", padding: "4px 16px 0", marginBottom: 18 }}>
          <div style={{ overflowX: "auto" }}><Tabs value={cat} onChange={setCat} tabs={dynTabs} /></div>
        </div>

        <div style={{ background: "#fff", borderRadius: 8, boxShadow: "var(--rp-shadow-card)", padding: 16 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 12 }}>
            <div style={{ flex: 1, display: "flex", alignItems: "center", gap: 8, border: "1px solid var(--rp-border-strong)", borderRadius: 4, padding: "0 12px", height: 40, color: "var(--rp-faint)", minWidth: 0 }}>
              <Icon name="Search" size={17} color="var(--rp-faint)" /><span style={{ fontSize: 14, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>Search by contract reference or contractor name</span>
            </div>
            <span style={{ fontSize: 12.5, color: "var(--rp-muted)", whiteSpace: "nowrap", fontWeight: 700 }}>{items.length} in {catLabel(cat)}</span>
          </div>

          {/* Transparent learning prompt — the agent asks before remembering anything */}
          {learnPrompt && (
            <div style={{ display: "flex", alignItems: "flex-start", gap: 13, background: "var(--rp-ai-soft)", border: "1px solid #E3D8FA", borderRadius: 8, padding: "14px 16px", marginBottom: 12 }}>
              <span style={{ width: 32, height: 32, borderRadius: "50%", background: "var(--rp-ai-gradient)", display: "grid", placeItems: "center", flex: "none" }}><Icon name="Sparkles" size={16} color="#fff" /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 700, lineHeight: 1.4 }}>You've approved {patternCount[learnPrompt.patternKey]} {learnPrompt.pattern} in a row. Want me to handle these for you from now on?</div>
                <div style={{ fontSize: 12.5, color: "var(--rp-muted)", marginTop: 4, lineHeight: 1.5 }}>I only ever auto-handle <b>low-risk</b> items, every rule shows up in <b>Playbooks</b> so you can see exactly what I've learned, and you can switch it off in one click. Nothing is learned silently.</div>
                <div style={{ display: "flex", gap: 8, marginTop: 11, flexWrap: "wrap" }}>
                  <Button variant="ai" size="sm" icon="Check" onClick={acceptLearning}>Yes, remember this</Button>
                  <Button variant="ghost" size="sm" onClick={() => { setView("playbooks"); setNav("review"); }}>See what you've learned</Button>
                  <Button variant="ghost" size="sm" onClick={() => setLearnPrompt(null)}>Not now</Button>
                </div>
              </div>
              <button onClick={() => setLearnPrompt(null)} style={{ background: "none", border: "none", cursor: "pointer", flex: "none" }}><Icon name="X" size={18} color="var(--rp-muted)" /></button>
            </div>
          )}

          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            {items.length === 0 && (
              <div style={{ padding: "30px 0", textAlign: "center", color: "var(--rp-muted)", fontSize: 14 }}>All {catLabel(cat)} items cleared. Try another tab, or run the agent.</div>
            )}
            {items.map(it => (
              <div key={it.id} style={{ display: "flex", alignItems: "center", gap: 14, background: "#fff", borderRadius: 8, border: "1px solid var(--rp-border)", padding: 14 }}>
                <Avatar name={it.who} flag={it.flag} size={40} />
                <span style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <span style={{ fontSize: 15, fontWeight: 700, whiteSpace: "nowrap" }}>{it.who}</span>
                    <SeverityPill s={it.band.toUpperCase()} />
                  </span>
                  <span style={{ display: "block", fontSize: 13, color: "var(--rp-muted)", marginTop: 2 }}>{it.line} · #{it.ref}</span>
                </span>
                <span style={{ fontSize: 15, fontWeight: 700, whiteSpace: "nowrap", marginRight: 4 }}>{it.amount}</span>
                <div style={{ display: "flex", gap: 8, flex: "none" }}>
                  <Button variant="danger" size="sm" onClick={() => manualResolve(it, "declined")}>Decline</Button>
                  <Button variant="success" size="sm" onClick={() => manualResolve(it, "approved")}>Approve</Button>
                </div>
              </div>
            ))}
          </div>
          <div style={{ fontSize: 12, color: "var(--rp-muted)", margin: "14px 2px 6px", display: "flex", alignItems: "flex-start", gap: 7 }}>
            <Icon name="Info" size={13} color="var(--rp-muted)" style={{ marginTop: 2, flex: "none" }} />
            <span style={{ lineHeight: 1.5 }}>Severity is the agent's risk read. <b>Only LOW</b> items can ever be auto-handled. See <span style={{ color: "var(--rp-ai-indigo)", fontWeight: 700, cursor: "pointer" }} onClick={() => setView("trust")}>Trust levels</span>.</span>
          </div>
        </div>
      </div>
    );
  }

  // ===== TRIAGED =====
  function Triaged() {
    const items = list(bucket);
    const bucketLabel = { auto: "Auto-handled · undo", decide: "Needs your decision", clarify: "Needs clarification" }[bucket];
    return (
      <div style={{ padding: "24px 32px 48px" }}>
        <div style={{ display: "flex", alignItems: "center", marginBottom: 16, gap: 12 }}>
          <h1 style={{ fontSize: 28 }}>Items to review</h1>
          <span style={{ flex: 1 }} />
          <button onClick={() => setView("trust")} data-tour="trust-btn" style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "none", border: "none", cursor: "pointer", color: "var(--rp-ai-indigo)", fontWeight: 700, fontSize: 13 }}><Icon name="SlidersHorizontal" size={15} color="var(--rp-ai-indigo)" />Trust levels</button>
          <button onClick={() => setView("playbooks")} data-tour="playbooks-btn" style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "none", border: "none", cursor: "pointer", color: "var(--rp-ai-indigo)", fontWeight: 700, fontSize: 13 }}><Icon name="BookOpen" size={15} color="var(--rp-ai-indigo)" />Playbooks</button>
        </div>

        {resolvedCount >= 1 && PayoffStrip()}

        <div style={{ margin: "0 0 16px" }}>
          <AgentBanner
            title="Review Agent triaged your queue"
            subtitle="I scanned all 132 items. 114 were routine, so I checked and cleared them (open Auto-handled to inspect). 18 need your eyes."
            active={bucket} onPick={setBucket}
            buckets={[
              { key: "auto", tone: "auto", count: counts.auto, label: "Auto-handled", hint: "routine, cleared · undo anytime" },
              { key: "decide", tone: "decide", count: counts.decide, label: "Needs your decision", hint: "recommended action ready" },
              { key: "clarify", tone: "clarify", count: counts.clarify, label: "Needs clarification", hint: "agent drafted a question" },
            ]}
          />
        </div>

        {pbPrompt && !pbAdded && (
          <div style={{ display: "flex", alignItems: "center", gap: 14, background: "var(--rp-ai-soft)", border: "1px solid #E3D8FA", borderRadius: 8, padding: "14px 18px", marginBottom: 16 }}>
            <span style={{ width: 34, height: 34, borderRadius: "50%", background: "var(--rp-ai-gradient)", display: "grid", placeItems: "center", flex: "none" }}><Icon name="Sparkles" size={17} color="#fff" /></span>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 700 }}>You've resolved sub-$5 currency-rounding expenses the same way. Add this as a rule?</div>
              <div style={{ fontSize: 12.5, color: "var(--rp-muted)" }}>Most teams auto-approve these; kept manual for you.</div>
            </div>
            <Button variant="ai" size="sm" icon="Plus" onClick={addPlaybook}>Add rule</Button>
            <button onClick={() => setPbPrompt(false)} style={{ background: "none", border: "none", cursor: "pointer" }}><Icon name="X" size={18} color="var(--rp-muted)" /></button>
          </div>
        )}

        <div style={{ display: "grid", gridTemplateColumns: bucket === "auto" ? "1fr" : "1fr 440px", gap: 20, alignItems: "start" }}>
          <div style={{ background: "#fff", borderRadius: 8, boxShadow: "var(--rp-shadow-card)", padding: 16 }}>
            <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: ".04em", textTransform: "uppercase", color: "var(--rp-faint)", margin: "2px 2px 12px" }}>{bucketLabel} · {counts[bucket]}</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {bucket === "auto"
                ? <React.Fragment>
                    <div style={{ fontSize: 13, color: "var(--rp-muted)", lineHeight: 1.5, margin: "0 2px 4px" }}>I checked these against your past decisions and your Trust Levels and found nothing to flag. Open a group to see why, or undo to send any of them back to the queue.</div>
                    {visibleGroups.map(g => (
                      <div key={g.label} style={{ display: "flex", alignItems: "center", gap: 12, background: "var(--rp-ai-soft)", borderRadius: 8, padding: "12px 14px" }}>
                        <span style={{ width: 34, height: 34, borderRadius: 8, background: "#fff", display: "grid", placeItems: "center", flex: "none" }}><Icon name={g.icon} size={17} color="var(--rp-ai-indigo)" /></span>
                        <span style={{ flex: 1, minWidth: 0 }}>
                          <span style={{ fontSize: 14, fontWeight: 700 }}>{g.count} {g.label}</span>
                          <span style={{ display: "block", fontSize: 12.5, color: "var(--rp-muted)" }}>{g.category} · {g.note}</span>
                        </span>
                        <span style={{ fontSize: 11, fontWeight: 800, letterSpacing: ".03em", color: "var(--rp-success)", whiteSpace: "nowrap" }}>CLEARED</span>
                        <button onClick={() => { setAutoHiddenGroups(a => [...a, g.label]); flash("Sent " + g.count + " " + g.label.toLowerCase() + " back to the queue"); }} style={{ display: "inline-flex", alignItems: "center", gap: 5, background: "#fff", border: "1px solid var(--rp-border-strong)", borderRadius: 4, padding: "5px 10px", cursor: "pointer", color: "var(--rp-ai-indigo)", fontWeight: 700, fontSize: 12.5 }}><Icon name="Undo2" size={14} color="var(--rp-ai-indigo)" />Undo</button>
                      </div>
                    ))}
                    {items.map(i => (
                      <div key={i.id} style={{ display: "flex", alignItems: "center", gap: 12, background: "var(--rp-ai-soft)", borderRadius: 8, padding: "12px 14px" }}>
                        <Avatar name={i.who} flag={i.flag} size={34} />
                        <span style={{ flex: 1, minWidth: 0 }}>
                          <span style={{ fontSize: 14, fontWeight: 700 }}>{i.title}</span>
                          <span style={{ display: "block", fontSize: 12.5, color: "var(--rp-muted)" }}>{i.who} · approved · {autoAt[i.id] || rcNow()}</span>
                        </span>
                        <span style={{ fontSize: 13.5, fontWeight: 700, whiteSpace: "nowrap" }}>{i.risk}</span>
                        <button onClick={() => undo(i.id)} style={{ display: "inline-flex", alignItems: "center", gap: 5, background: "#fff", border: "1px solid var(--rp-border-strong)", borderRadius: 4, padding: "5px 10px", cursor: "pointer", color: "var(--rp-ai-indigo)", fontWeight: 700, fontSize: 12.5 }}><Icon name="Undo2" size={14} color="var(--rp-ai-indigo)" />Undo</button>
                      </div>
                    ))}
                    {visibleGroups.length === 0 && items.length === 0 && <div style={{ padding: "26px 0", textAlign: "center", color: "var(--rp-muted)", fontSize: 14 }}>You sent everything back to the queue.</div>}
                  </React.Fragment>
                : <React.Fragment>
                    {items.length === 0 && <div style={{ padding: "26px 0", textAlign: "center", color: "var(--rp-muted)", fontSize: 14 }}>All clear in this bucket.</div>}
                    {items.map((i, idx) => {
                    const on = i.id === selIssue;
                    const waiting = st(i.id) === "waiting";
                    return (
                      <button key={i.id} onClick={() => setSelIssue(i.id)} data-tour={idx === 0 ? "issue-list" : undefined} style={{ textAlign: "left", cursor: "pointer", background: "#fff", borderRadius: 8, border: on ? "2px solid var(--rp-blue)" : "1px solid var(--rp-border)", padding: 14, display: "flex", alignItems: "center", gap: 13 }}>
                        <span style={{ width: 38, height: 38, borderRadius: "50%", background: bucket === "clarify" ? "var(--rp-warning-soft)" : "var(--rp-blue-soft)", display: "grid", placeItems: "center", flex: "none" }}>
                          <Icon name={bucket === "clarify" ? "MessageCircleQuestion" : "Gavel"} size={17} color={bucket === "clarify" ? "#9A7400" : "var(--rp-blue)"} />
                        </span>
                        <span style={{ flex: 1, minWidth: 0 }}>
                          <span style={{ display: "flex", alignItems: "center", gap: 7 }}><SeverityPill s={i.severity} /><span style={{ fontSize: 14.5, fontWeight: 700 }}>{i.title}</span></span>
                          <span style={{ display: "block", fontSize: 12.5, color: "var(--rp-muted)", marginTop: 3 }}>{i.who} · {i.category} · {i.risk} at risk{waiting ? " · waiting" : ""}</span>
                        </span>
                        <Icon name="ChevronRight" size={18} color="var(--rp-faint)" />
                      </button>
                    );
                  })}
                  </React.Fragment>}
            </div>
          </div>

          {bucket !== "auto" && selectedIssue && inBucket(selectedIssue, bucket) && (
            <IssueDetail issue={selectedIssue} status={st(selectedIssue.id)}
              draft={drafts[selectedIssue.id]} setDraft={(v) => setDrafts(d => ({ ...d, [selectedIssue.id]: v }))}
              onSend={() => { resolve(selectedIssue.id, "waiting"); flash("Message sent to " + selectedIssue.who.split(" ")[0]); }}
              onApprove={() => { resolve(selectedIssue.id, "approved"); flash("Approved"); }}
              onDecline={() => { resolve(selectedIssue.id, "declined"); flash("Declined"); }}
              onDismiss={() => { resolve(selectedIssue.id, "dismissed"); flash("Dismissed"); }} />
          )}
          {bucket !== "auto" && (!selectedIssue || !inBucket(selectedIssue, bucket)) && (
            <div style={{ background: "#fff", borderRadius: 8, boxShadow: "var(--rp-shadow-card)", padding: 40, textAlign: "center", color: "var(--rp-muted)", fontSize: 14 }}>Select an item to see the agent's insight.</div>
          )}
        </div>
      </div>
    );
  }

  function PayoffStrip() {
    const prevented = resolvedCount;
    const mins = resolvedCount * 6;
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 0, background: "var(--rp-ink)", borderRadius: 12, padding: "18px 24px", marginBottom: 16, color: "#fff", overflow: "hidden" }}>
        {Metric({ n: <CountUp value={prevented} />, label: "Issues prevented" })}
        {Sep()}{Metric({ n: <CountUp value={Math.round(protectedAmt)} prefix="$" />, label: "Value protected" })}
        {Sep()}{Metric({ n: <><CountUp value={mins} />m</>, label: "Time saved" })}
        <span style={{ flex: 1 }} />
        <a href="index.html" style={{ display: "inline-flex", alignItems: "center", gap: 8, background: "var(--rp-ai-gradient)", color: "#fff", fontWeight: 700, fontSize: 14, padding: "11px 18px", borderRadius: 6, textDecoration: "none" }}>See the full vision <span style={{ fontSize: 16 }}>→</span></a>
      </div>
    );
  }
  function Metric({ n, label }) { return <div><div style={{ fontSize: 28, fontWeight: 800, fontVariantNumeric: "tabular-nums" }}>{n}</div><div style={{ fontSize: 12.5, opacity: .7, fontWeight: 700 }}>{label}</div></div>; }
  function Sep() { return <div style={{ width: 1, height: 38, background: "rgba(255,255,255,.18)", margin: "0 26px" }} />; }

  // ===== TRUST LEVELS (risk-tier × autonomy) =====
  function TrustView() {
    const tierMeta = {
      low: { label: "Low risk", icon: "ShieldCheck" },
      med: { label: "Medium risk", icon: "ShieldAlert" },
      high: { label: "High risk", icon: "OctagonAlert" },
    };
    function setTier(t, v) {
      setAutonomy(a => ({ ...a, [t]: v }));
      if (t === "low" && v === "auto") flash("Low-risk items now auto-handled, with undo");
    }
    const sigRows = [
      { key: "frequency", title: "Approvals lower risk", desc: "If you've approved a pattern 3+ times, treat it as low-risk. This is how the agent learns what you trust.", star: true },
      { key: "novelty", title: "Novelty raises risk", desc: "First-time payees and documents are never auto-handled." },
      { key: "baseline", title: "Deviation from baseline", desc: "Flag anything that departs from the worker's usual amount or cadence." },
    ];
    return (
      <div style={{ padding: "24px 32px 48px", maxWidth: 980 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 18 }}>
          {BackToReview()}
          <button onClick={() => setView("playbooks")} style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "none", border: "none", cursor: "pointer", color: "var(--rp-ai-indigo)", fontWeight: 700, fontSize: 13, marginBottom: 8, padding: 0 }}><Icon name="BookOpen" size={15} color="var(--rp-ai-indigo)" />Playbooks</button>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 12, margin: "6px 0 4px" }}>
          <span style={{ width: 36, height: 36, borderRadius: "50%", background: "var(--rp-ai-gradient)", display: "grid", placeItems: "center" }}><Icon name="WandSparkles" size={18} color="#fff" stroke={2.2} /></span>
          <h1 style={{ fontSize: 28 }}>Trust levels</h1>
        </div>
        <div style={{ fontSize: 15, color: "var(--rp-muted)", marginBottom: 20, maxWidth: 680 }}>Two questions, both yours to answer: <b>what counts as risky</b>, and <b>how much the agent may do</b> at each risk level. Human-in-the-loop by default · reversible · audit-logged · <b>never auto-pays</b>.</div>

        {/* AXIS 1 — risk signals (editable) */}
        <div style={{ background: "#fff", borderRadius: 10, border: "1px solid var(--rp-border)", boxShadow: "var(--rp-shadow-card)", padding: "18px 20px", marginBottom: 16 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <span style={{ width: 24, height: 24, borderRadius: 7, background: "var(--rp-blue-soft)", display: "grid", placeItems: "center" }}><Icon name="SlidersHorizontal" size={14} color="var(--rp-blue)" /></span>
            <span style={{ fontSize: 16, fontWeight: 800 }}>1 · What counts as risky</span>
          </div>
          <div style={{ fontSize: 13, color: "var(--rp-muted)", margin: "6px 0 16px" }}>You own the signals. Transparent and adjustable, not a black box. They define which items land in each tier.</div>
          <div style={{ paddingBottom: 14, borderBottom: "1px solid var(--rp-border)" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 8 }}>
              <span style={{ fontSize: 14, fontWeight: 700, whiteSpace: "nowrap" }}>Above this $-at-risk, never low-risk</span>
              <span style={{ fontSize: 15, fontWeight: 800, color: "var(--rp-blue)", fontVariantNumeric: "tabular-nums" }}>AED {signals.amount.toLocaleString("en-US")}</span>
            </div>
            <input type="range" min="5000" max="50000" step="1000" value={signals.amount} onChange={(e) => setSignals(s => ({ ...s, amount: +e.target.value }))} style={{ width: "100%", accentColor: "var(--rp-blue)" }} />
          </div>
          {sigRows.map((s, i) => (
            <div key={s.key} style={{ display: "flex", alignItems: "center", gap: 14, padding: "13px 0", borderBottom: i < 2 ? "1px solid var(--rp-border)" : "none" }}>
              <span style={{ flex: 1, minWidth: 0 }}>
                <span style={{ display: "inline-flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}><span style={{ fontSize: 14, fontWeight: 700, whiteSpace: "nowrap" }}>{s.title}</span>{s.star && <Tag tone="ai">self-learning</Tag>}</span>
                <span style={{ display: "block", fontSize: 12.5, color: "var(--rp-muted)", marginTop: 2, lineHeight: 1.5 }}>{s.desc}</span>
              </span>
              <Switch checked={signals[s.key]} onChange={(v) => setSignals(x => ({ ...x, [s.key]: v }))} />
            </div>
          ))}
        </div>

        {/* AXIS 2 — autonomy per tier */}
        <div style={{ background: "#fff", borderRadius: 10, border: "1px solid var(--rp-border)", boxShadow: "var(--rp-shadow-card)", padding: "18px 20px", marginBottom: 16 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <span style={{ width: 24, height: 24, borderRadius: 7, background: "var(--rp-ai-soft)", display: "grid", placeItems: "center" }}><Icon name="WandSparkles" size={14} color="var(--rp-ai-indigo)" /></span>
            <span style={{ fontSize: 16, fontWeight: 800 }}>2 · How much the agent may do</span>
          </div>
          <div style={{ fontSize: 13, color: "var(--rp-muted)", margin: "6px 0 14px" }}>Pick an autonomy level for each tier. <b>Ask</b> = only flag · <b>Suggest</b> = recommend, you click · <b>Auto</b> = handle it, with undo.</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            {["low", "med", "high"].map(t => {
              const m = tierMeta[t];
              const isAuto = autonomy[t] === "auto";
              return (
                <div key={t} data-tour={t === "low" ? "low-tier" : undefined}>
                  <TrustLevel category={m.label} icon={m.icon} value={autonomy[t]} onChange={(v) => setTier(t, v)}
                    style={{ border: isAuto && t === "low" ? "1px solid #E3D8FA" : "1px solid var(--rp-border)" }} />
                  {t === "low" && autonomy.low !== "auto" && (
                    <div style={{ fontSize: 12, color: "var(--rp-ai-indigo)", fontWeight: 700, margin: "6px 0 0 48px" }}>Recommended: Auto. Clears routine items, fully reversible.</div>
                  )}
                  {t !== "low" && isAuto && (
                    <div style={{ fontSize: 12, color: "#9A7400", margin: "6px 0 0 48px", display: "flex", alignItems: "center", gap: 6 }}><Icon name="TriangleAlert" size={13} color="#9A7400" /><span>{m.label} autonomy stays gated by your guardrails in beta — and never auto-pays.</span></div>
                  )}
                </div>
              );
            })}
          </div>
        </div>

        {/* Per-category exceptions */}
        <div style={{ background: "#fff", borderRadius: 10, border: "1px solid var(--rp-border)", boxShadow: "var(--rp-shadow-card)", padding: "16px 20px" }}>
          <div style={{ fontSize: 14, fontWeight: 800 }}>Per-category exceptions</div>
          <div style={{ fontSize: 12.5, color: "var(--rp-muted)", margin: "2px 0 12px" }}>By default every category follows the tiers above. Force any one to always ask.</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
            {D.trustCategories.map(c => {
              const strict = catOverride[c.category] === "ask";
              return (
                <button key={c.category} onClick={() => setCatOverride(o => ({ ...o, [c.category]: strict ? null : "ask" }))}
                  style={{ display: "inline-flex", alignItems: "center", gap: 7, background: strict ? "var(--rp-blue-soft)" : "#fff", border: strict ? "1px solid var(--rp-blue)" : "1px solid var(--rp-border-strong)", color: strict ? "var(--rp-blue)" : "var(--rp-muted)", borderRadius: 9999, padding: "7px 13px", fontWeight: 700, fontSize: 13, cursor: "pointer", fontFamily: "var(--font-sans)" }}>
                  <Icon name={strict ? "Lock" : c.icon} size={14} color={strict ? "var(--rp-blue)" : "var(--rp-muted)"} />{c.category}{strict ? " · always ask" : ""}
                </button>
              );
            })}
          </div>
        </div>

        <div style={{ marginTop: 16, display: "flex", alignItems: "flex-start", gap: 8, color: "var(--rp-muted)", fontSize: 12.5 }}>
          <Icon name="Info" size={14} color="var(--rp-muted)" style={{ marginTop: 1, flex: "none" }} /><span style={{ lineHeight: 1.5 }}>Set <b>Low risk → Auto</b> to watch the agent clear its low-risk items into "Auto-handled" (reversible). Then head back to the queue.</span>
        </div>
      </div>
    );
  }

  // ===== PLAYBOOKS — Rules + Reviewer Profile (memory) =====
  function PlaybooksView() {
    function saveEdit(i) {
      setProfile(p => p.map((x, j) => j === i ? { ...x, text: editText || x.text, edited: true } : x));
      setEditIdx(-1); setEditText(""); flash("Profile updated");
    }
    function addCustomRule() {
      const t = newRule.trim();
      if (!t) return;
      setPlaybooks(p => [{ name: t, scope: "Your own rule", auto: "you", on: true, system: false, custom: true }, ...p]);
      setProfile(pr => [{ text: t, source: "a rule you wrote", edited: true }, ...pr]);
      setNewRule("");
      // Adding your own rule is the final guided step — completing it closes the tour.
      if (tourOn) { setTourOn(false); flash("That's the full walkthrough — you're all set. Rule added; the agent will follow it on its next run."); }
      else { flash("Rule added. The agent will follow it on its next run."); }
    }
    return (
      <div style={{ padding: "24px 32px 48px", maxWidth: 920 }}>
        {BackToReview()}
        <div style={{ display: "flex", alignItems: "center", gap: 8, margin: "6px 0 4px" }}>
          <h1 style={{ fontSize: 28 }}>Playbooks</h1><Tag tone="ai">Self-learning · you stay in control</Tag>
        </div>
        <div style={{ fontSize: 15, color: "var(--rp-muted)", marginBottom: 20, maxWidth: 680 }}>Your decisions teach the agent. It keeps a plain-English profile of how you work, plus the structured rules that follow from it. All visible, all editable.</div>

        {/* Reviewer Profile (memory) */}
        <div style={{ display: "flex", alignItems: "center", gap: 8, margin: "4px 0 8px" }}>
          <Icon name="BookUser" size={18} color="var(--rp-ai-indigo)" />
          <span style={{ fontSize: 17, fontWeight: 800 }}>Reviewer Profile</span><Tag tone="ai">memory</Tag>
        </div>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 12, background: "var(--rp-ai-soft)", border: "1px solid #E3D8FA", borderRadius: 10, padding: "13px 16px", marginBottom: 12 }}>
          <Icon name="Sparkles" size={16} color="var(--rp-ai-indigo)" style={{ marginTop: 1 }} />
          <span style={{ fontSize: 13, color: "var(--rp-ink)", lineHeight: 1.55 }}>I built this from your decisions. <b>Edit anything.</b> Nothing is learned silently, and I'll never act outside the Trust Levels you set.</span>
        </div>
        <div style={{ background: "#fff", borderRadius: 8, boxShadow: "var(--rp-shadow-card)", overflow: "hidden", marginBottom: 26 }}>
          {profile.map((p, i) => (
            <div key={i} style={{ display: "flex", alignItems: "flex-start", gap: 12, padding: "14px 18px", borderBottom: i < profile.length - 1 ? "1px solid var(--rp-border)" : "none" }}>
              <Icon name="Quote" size={15} color="var(--rp-ai-indigo)" style={{ marginTop: 3, flex: "none" }} />
              <span style={{ flex: 1, minWidth: 0 }}>
                {editIdx === i
                  ? <textarea autoFocus value={editText} onChange={(e) => setEditText(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); saveEdit(i); } }} style={{ width: "100%", boxSizing: "border-box", minHeight: 54, resize: "vertical", border: "1px solid #E3D8FA", borderRadius: 6, padding: "8px 10px", fontFamily: "var(--font-sans)", fontSize: 14, color: "var(--rp-ink)", lineHeight: 1.5 }} />
                  : <span style={{ fontSize: 14.5, color: "var(--rp-ink)", lineHeight: 1.5 }}>{p.text}</span>}
                <span style={{ display: "block", fontSize: 12, color: "var(--rp-muted)", marginTop: 4 }}>Learned from {p.source}{p.edited ? " · edited by you" : ""}</span>
              </span>
              {editIdx === i
                ? <button onClick={() => saveEdit(i)} style={{ background: "none", border: "none", cursor: "pointer", color: "var(--rp-ai-indigo)", fontWeight: 700, fontSize: 13, flex: "none" }}>Save</button>
                : <button onClick={() => { setEditIdx(i); setEditText(p.text); }} title="Edit" style={{ background: "none", border: "none", cursor: "pointer", flex: "none", padding: 4 }}><Icon name="Pencil" size={15} color="var(--rp-muted)" /></button>}
              <button onClick={() => { setProfile(ps => ps.filter((_, j) => j !== i)); flash("Removed from profile"); }} title="Remove" style={{ background: "none", border: "none", cursor: "pointer", flex: "none", padding: 4 }}><Icon name="X" size={16} color="var(--rp-muted)" /></button>
            </div>
          ))}
          {profile.length === 0 && <div style={{ padding: "22px", textAlign: "center", color: "var(--rp-muted)", fontSize: 13.5 }}>Profile cleared. The agent will start learning again from your next decisions.</div>}
        </div>

        {/* Rules */}
        <div style={{ display: "flex", alignItems: "center", gap: 8, margin: "4px 0 6px" }}>
          <Icon name="ListChecks" size={18} color="var(--rp-ink)" /><span style={{ fontSize: 17, fontWeight: 800 }}>Rules</span>
        </div>
        <div style={{ fontSize: 13, color: "var(--rp-muted)", marginBottom: 12 }}>Structured playbooks the profile produces. Suggested ones stay off until you turn them on.</div>

        {/* Write your own rule, in plain words */}
        <div data-tour="addrule" style={{ marginBottom: 14, background: "#fff", borderRadius: 8, boxShadow: "var(--rp-shadow-card)", border: "1px solid #E3D8FA", padding: "16px 18px" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
            <Icon name="PenLine" size={16} color="var(--rp-ai-indigo)" />
            <span style={{ fontSize: 14.5, fontWeight: 800 }}>Add your own rule</span>
          </div>
          <div style={{ fontSize: 12.5, color: "var(--rp-muted)", marginBottom: 10 }}>Write it the way you'd tell a colleague. The agent treats it like the rules it learned, and you can switch it off any time.</div>
          <div style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
            <textarea value={newRule} onChange={(e) => setNewRule(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); addCustomRule(); } }}
              placeholder="e.g. Always send AWS and Notion bills straight through if they match the purchase order."
              style={{ flex: 1, boxSizing: "border-box", minHeight: 52, resize: "vertical", border: "1px solid var(--rp-border-strong)", borderRadius: 6, padding: "10px 12px", fontFamily: "var(--font-sans)", fontSize: 13.5, color: "var(--rp-ink)", lineHeight: 1.5 }} />
            <Button variant="ai" icon="Plus" onClick={addCustomRule}>Add rule</Button>
          </div>
        </div>
        <div style={{ background: "#fff", borderRadius: 8, boxShadow: "var(--rp-shadow-card)", overflow: "hidden" }}>
          {playbooks.map((p, i) => (
            <div key={i} style={{ display: "flex", alignItems: "center", gap: 14, padding: "15px 18px", borderBottom: i < playbooks.length - 1 ? "1px solid var(--rp-border)" : "none" }}>
              <span style={{ width: 34, height: 34, borderRadius: 8, background: p.suggested ? "var(--rp-app-bg)" : "var(--rp-ai-soft)", display: "grid", placeItems: "center", flex: "none" }}><Icon name="Sparkles" size={16} color={p.suggested ? "var(--rp-muted)" : "var(--rp-ai-indigo)"} /></span>
              <span style={{ flex: 1, minWidth: 0 }}>
                <span style={{ display: "inline-flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}><span style={{ fontSize: 14.5, fontWeight: 700 }}>{p.name}</span>{p.suggested ? <Tag tone="warning">suggested</Tag> : (p.system ? <Tag tone="neutral">policy</Tag> : (p.custom ? <Tag tone="ai">your rule</Tag> : <Tag tone="ai">learned from you</Tag>))}</span>
                <span style={{ display: "block", fontSize: 12.5, color: "var(--rp-muted)", marginTop: 2 }}>{p.custom ? p.scope + " · added by you" : p.scope + " · " + (p.system ? "from " + p.auto : "learned from " + p.auto) + (p.confidence ? " · " + p.confidence + " confidence" : "")}</span>
              </span>
              <Switch checked={p.on} onChange={(v) => setPlaybooks(ps => ps.map((x, j) => j === i ? { ...x, on: v, suggested: v ? false : x.suggested } : x))} />
              {!p.system && (
                <button onClick={() => { setPlaybooks(ps => ps.filter((_, j) => j !== i)); setLearnings(ls => ls.filter(l => l.name !== p.name)); flash("Rule removed"); }} title="Remove rule" style={{ background: "none", border: "none", cursor: "pointer", flex: "none", padding: 4 }}><Icon name="Trash2" size={16} color="var(--rp-muted)" /></button>
              )}
            </div>
          ))}
        </div>
      </div>
    );
  }

  function BackToReview() {
    return <button onClick={() => { setView("review"); setNav("review"); }} data-tour="back" style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "none", border: "none", cursor: "pointer", color: "var(--rp-muted)", fontWeight: 700, fontSize: 13, marginBottom: 8, padding: 0 }}><Icon name="ChevronLeft" size={16} color="var(--rp-muted)" />Back to the queue</button>;
  }

  function Other() {
    return <div style={{ height: "100%", display: "grid", placeItems: "center" }}><APP.EmptyState icon="Hammer" title="Not in this demo" message="This area isn't part of the prototype. Head to Review to run the agent." action={{ label: "Go to Review", icon: "ListChecks", onClick: () => onNav("review") }} /></div>;
  }
}

window.ReviewApp = ReviewApp;

// ---- Guided-tour coach: pulsing ring + pointer tooltip anchored to a [data-tour] element ----
function TourCoach({ step, text, idx, total, onSkip }) {
  const { Icon } = window.RP;
  const [box, setBox] = React.useState(null);
  React.useEffect(() => {
    let t;
    function measure() {
      const el = document.querySelector('[data-tour="' + step + '"]');
      if (el) {
        const r = el.getBoundingClientRect();
        setBox(prev => (prev && Math.abs(prev.top - r.top) < 1 && Math.abs(prev.left - r.left) < 1 && prev.width === r.width && prev.height === r.height)
          ? prev : { top: r.top, left: r.left, width: r.width, height: r.height });
      } else { setBox(null); }
      t = setTimeout(measure, 240);
    }
    measure();
    return () => clearTimeout(t);
  }, [step]);
  // On step change, bring the target into view if it's off-screen (scrolls the rp-scroll container, not the page).
  // Instant scroll only — smooth scroll is blocked in some embeds. Retry a few times so late layout settles.
  React.useEffect(() => {
    let tries = 0, timer;
    function bring() {
      const el = document.querySelector('[data-tour="' + step + '"]');
      if (el) {
        let p = el.parentElement;
        while (p && p !== document.body) {
          const oy = getComputedStyle(p).overflowY;
          if (oy === "auto" || oy === "scroll") break;
          p = p.parentElement;
        }
        if (p && p !== document.body && p.scrollHeight > p.clientHeight) {
          const r = el.getBoundingClientRect();
          if (r.bottom > window.innerHeight - 150 || r.top < 90) {
            const pr = p.getBoundingClientRect();
            // place the target's centre at ~42% of the container so the tooltip below it stays clear of the bottom pills
            const target = p.scrollTop + (r.top - pr.top) - (pr.height * 0.42 - r.height / 2);
            p.scrollTop = Math.max(0, Math.min(target, p.scrollHeight - p.clientHeight));
          }
        }
      }
      if (++tries < 4) timer = setTimeout(bring, 120);
    }
    timer = setTimeout(bring, 60);
    return () => clearTimeout(timer);
  }, [step]);
  if (!box) return null;
  const tipW = 290, tipH = 150, margin = 14;
  const vw = window.innerWidth, vh = window.innerHeight;
  const tipLeft = Math.min(Math.max(margin, box.left + box.width / 2 - tipW / 2), vw - tipW - margin);
  // keep the tooltip out of the bottom band where the demo pills live
  const maxTop = vh - tipH - 70;
  let placeBelow = (vh - (box.top + box.height)) > (tipH + 70);
  let tipTop = placeBelow ? box.top + box.height + 16 : box.top - 16 - tipH;
  if (tipTop > maxTop) { tipTop = Math.max(margin, box.top - 16 - tipH); placeBelow = false; }
  if (tipTop < margin) { tipTop = margin; }
  const arrowLeft = Math.min(Math.max(16, box.left + box.width / 2 - tipLeft - 7), tipW - 30);
  return (
    <div style={{ position: "fixed", inset: 0, zIndex: 80, pointerEvents: "none" }}>
      <div style={{ position: "fixed", top: box.top - 6, left: box.left - 6, width: box.width + 12, height: box.height + 12, border: "2px solid var(--rp-ai-indigo)", borderRadius: 12, animation: "rp-coach-pulse 1.8s ease-out infinite", pointerEvents: "none" }} />
      <div style={{ position: "fixed", top: tipTop, left: tipLeft, width: tipW, pointerEvents: "auto", background: "var(--rp-ink)", color: "#fff", borderRadius: 12, padding: "14px 16px", boxShadow: "var(--rp-shadow-pop)" }}>
        <div style={{ position: "absolute", left: arrowLeft, [placeBelow ? "top" : "bottom"]: -7, width: 14, height: 14, background: "var(--rp-ink)", transform: "rotate(45deg)" }} />
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 7 }}>
          <span style={{ width: 22, height: 22, borderRadius: "50%", background: "var(--rp-ai-gradient)", display: "grid", placeItems: "center", flex: "none" }}><Icon name="WandSparkles" size={12} color="#fff" stroke={2.4} /></span>
          <span style={{ fontSize: 11.5, fontWeight: 800, letterSpacing: ".04em", textTransform: "uppercase", color: "#b69cff", whiteSpace: "nowrap" }}>Step {idx} of {total}</span>
          <span style={{ flex: 1 }} />
          <button onClick={onSkip} style={{ background: "none", border: "none", cursor: "pointer", color: "rgba(255,255,255,.6)", fontSize: 12, fontWeight: 700, fontFamily: "var(--font-sans)" }}>Skip</button>
        </div>
        <div style={{ fontSize: 13.5, lineHeight: 1.5, fontWeight: 600 }}>{text}</div>
        <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 9, color: "#b69cff", fontSize: 11.5, fontWeight: 700 }}>
          <Icon name="MousePointerClick" size={13} color="#b69cff" /><span>Click the highlighted control to go on</span>
        </div>
      </div>
    </div>
  );
}
window.TourCoach = TourCoach;
