// =====================================================================
// Research Workspace v2 (Phase 13)
//
// Max navigation depth:
//   Project → Research → Study Detail
// No tabs-inside-tabs, no drawers, no sub-sidebars.
//
// Three primary views (segmented control at the top):
//   • Overview   — what's happening now, tied to the current stage
//   • Studies    — canonical library of research work
//   • Insights   — editorial synthesized statements
//
// The workspace reads canonical pdata.research + pdata.insights.
// Nothing is duplicated. Stage/Mission/Feature/Decision links are
// derived from the Phase-12 canonical link model.
// =====================================================================

function ResearchWorkspaceV2({ pdata, subId, sub2 }) {
  // Route shape:
  //   /research                     → subId=null,      sub2=null   → Overview
  //   /research/studies             → subId='studies', sub2=null   → Studies library
  //   /research/insights            → subId='insights',sub2=null   → Insights view
  //   /research/study/:studyId      → subId='study',   sub2=studyId → Study Detail
  const [view, setView] = React.useState(() => {
    if (subId === 'study') return 'study';
    if (subId === 'studies' || subId === 'insights') return subId;
    return 'overview';
  });
  const [openStudyId, setOpenStudyId] = React.useState(subId === 'study' ? sub2 : null);

  // React to hash changes
  React.useEffect(() => {
    if (subId === 'study' && sub2) {
      setOpenStudyId(sub2);
      setView('study');
    } else if (subId === 'studies' || subId === 'insights') {
      setView(subId);
      setOpenStudyId(null);
    } else {
      setView('overview');
      setOpenStudyId(null);
    }
  }, [subId, sub2]);

  const setViewAndRoute = (v) => {
    setView(v);
    setOpenStudyId(null);
    location.hash = `#/projects/${pdata.id}/research${v === 'overview' ? '' : '/' + v}`;
  };

  const openStudy = (id) => {
    setOpenStudyId(id);
    setView('study');
    location.hash = `#/projects/${pdata.id}/research/study/${id}`;
  };

  const backToLibrary = () => {
    setOpenStudyId(null);
    setView('studies');
    location.hash = `#/projects/${pdata.id}/research/studies`;
  };

  // -----------------------------------------------------------------
  // Header — clear page title + 3 primary views
  // -----------------------------------------------------------------
  return (
    <div className="rv2" data-screen-label="ResearchWorkspaceV2">
      {view !== 'study' && (
        <div className="rv2-head">
          <div className="rv2-head-title">
            <h2>Research</h2>
            <span className="rv2-head-sub">
              {pdata.research.length} studies · {(pdata.insights || []).length} insights · linked to project stages &amp; features
            </span>
          </div>
          <nav className="rv2-tabs" role="tablist">
            <button
              className={`rv2-tab${view === 'overview' ? ' active' : ''}`}
              onClick={() => setViewAndRoute('overview')}
              role="tab" aria-selected={view === 'overview'}
            >
              <Icon name="compass" size={13} strokeWidth={1.75} />
              <span>Overview</span>
            </button>
            <button
              className={`rv2-tab${view === 'studies' ? ' active' : ''}`}
              onClick={() => setViewAndRoute('studies')}
              role="tab" aria-selected={view === 'studies'}
            >
              <Icon name="flask" size={13} strokeWidth={1.75} />
              <span>Studies</span>
              <span className="rv2-tab-count mono">{pdata.research.length}</span>
            </button>
            <button
              className={`rv2-tab${view === 'insights' ? ' active' : ''}`}
              onClick={() => setViewAndRoute('insights')}
              role="tab" aria-selected={view === 'insights'}
            >
              <Icon name="spark" size={13} strokeWidth={1.75} />
              <span>Insights</span>
              <span className="rv2-tab-count mono">{(pdata.insights || []).length}</span>
            </button>
          </nav>
        </div>
      )}

      {view === 'overview' && <ResearchOverview pdata={pdata} openStudy={openStudy} />}
      {view === 'studies'  && <StudiesLibrary  pdata={pdata} openStudy={openStudy} />}
      {view === 'insights' && <InsightsView    pdata={pdata} openStudy={openStudy} />}
      {view === 'study'    && openStudyId && (
        <StudyDetail
          pdata={pdata}
          study={pdata.research.find(r => r.id === openStudyId)}
          onBack={backToLibrary}
          openStudy={openStudy}
        />
      )}
    </div>
  );
}

// =====================================================================
// 1. RESEARCH OVERVIEW
// =====================================================================
function ResearchOverview({ pdata, openStudy }) {
  const stage = pdata.stages.find(s => s.status === 'now');
  const mission = stage?.missions?.find(m => m.key === 'research');
  const missionChecks = mission?.checklist || [];
  const requiredDone   = missionChecks.filter(c => c.required && c.done).length;
  const requiredTotal  = missionChecks.filter(c => c.required).length;
  const nextRequired   = missionChecks.find(c => c.required && !c.done);
  const nextRequiredStudy = nextRequired?.studyId && pdata.research.find(r => r.id === nextRequired.studyId);

  const active = pdata.research.filter(r => ['in-progress','recruiting','synthesizing'].includes(r.status));
  const recent = [...pdata.research].sort((a, b) => (b.endDate || b.date || '').localeCompare(a.endDate || a.date || '')).slice(0, 4);
  const pinnedInsights = (pdata.insights || []).filter(i => i.pinned);
  const otherInsights  = (pdata.insights || []).filter(i => !i.pinned).slice(0, 2);

  return (
    <div className="rv2-overview">
      <MGWorkspaceBanner
        kind="research"
        eyebrow="Research · MY GENI"
        title="Signal, not slides"
        sub="Every study, finding, and interview quote — connected to the features and decisions they feed."
      />
      {/* CURRENT STAGE CONTEXT — derived from Phase-12 mission link, never duplicated */}
      <div className="rv2-stage-ctx">
        <div className="rv2-ctx-left">
          <div className="rv2-ctx-eyebrow">
            <Icon name="stages" size={11} strokeWidth={1.75} style={{ color: 'var(--primary-01)' }} />
            <span>Current stage · research mission</span>
          </div>
          <div className="rv2-ctx-title">
            Stage {String(stage.n).padStart(2, '0')} · {stage.name}
          </div>
          <div className="rv2-ctx-progress">
            <div className="rv2-ctx-count mono">{requiredDone} of {requiredTotal} required studies complete</div>
            <div className="rv2-ctx-bar">
              <div className="rv2-ctx-fill" style={{ width: `${Math.round((requiredDone / Math.max(requiredTotal,1)) * 100)}%` }} />
            </div>
          </div>
          {nextRequiredStudy && (
            <div className="rv2-ctx-next">
              <div className="rv2-ctx-next-label">Next required</div>
              <a
                onClick={(e) => { e.preventDefault(); openStudy(nextRequiredStudy.id); }}
                href={`#/projects/${pdata.id}/research/study/${nextRequiredStudy.id}`}
                className="rv2-ctx-next-study"
              >
                <span className="title">{nextRequiredStudy.title}</span>
                <Label tone="gray" dot size="sm">Planned</Label>
                {nextRequiredStudy.startDate && <span className="mono">Starts {nextRequiredStudy.startDate}</span>}
              </a>
            </div>
          )}
        </div>
        <a href={`#/projects/${pdata.id}/plan`} className="rv2-ctx-action">
          <Icon name="stages" size={13} strokeWidth={1.75} />
          <span>View Research Mission</span>
        </a>
      </div>

      {/* ACTIVE + NEXT REQUIRED — one editorial section */}
      {(active.length > 0 || nextRequiredStudy) && (
        <section className="rv2-sec">
          <div className="rv2-sec-head">
            <h3>What we're learning now</h3>
            <span className="rv2-sec-sub">{active.length + (nextRequiredStudy ? 1 : 0)} active or upcoming</span>
          </div>
          <div className="rv2-active-list">
            {[...active, ...(nextRequiredStudy && !active.includes(nextRequiredStudy) ? [nextRequiredStudy] : [])].map((r) => (
              <ActiveStudyRow key={r.id} r={r} pdata={pdata} openStudy={openStudy} />
            ))}
          </div>
        </section>
      )}

      {/* RECENT EVIDENCE — from the flagship study, editorial pull quotes */}
      <section className="rv2-sec">
        <div className="rv2-sec-head">
          <h3>Recent evidence</h3>
          <a className="rv2-sec-link" onClick={() => openStudy('r1')}>Open Onboarding-context study →</a>
        </div>
        <div className="rv2-evidence-strip">
          {(pdata.research.find(r => r.id === 'r1')?.evidence || []).slice(0, 3).map((e, i) => (
            <EvidenceQuoteCard key={e.id} e={e} studyId="r1" openStudy={openStudy} compact={i > 0} />
          ))}
        </div>
      </section>

      {/* INSIGHTS AFFECTING CURRENT FEATURES */}
      {pinnedInsights.length + otherInsights.length > 0 && (
        <section className="rv2-sec">
          <div className="rv2-sec-head">
            <h3>Insights affecting current features</h3>
            <a className="rv2-sec-link" href={`#/projects/${pdata.id}/research/insights`} onClick={(e) => { e.preventDefault(); location.hash = `#/projects/${pdata.id}/research/insights`; }}>All insights →</a>
          </div>
          <div className="rv2-insights-list">
            {[...pinnedInsights, ...otherInsights].slice(0, 3).map((ins) => (
              <InsightRow key={ins.id} insight={ins} pdata={pdata} openStudy={openStudy} />
            ))}
          </div>
        </section>
      )}

      {/* RECENTLY UPDATED STUDIES */}
      <section className="rv2-sec">
        <div className="rv2-sec-head">
          <h3>Recently updated</h3>
          <a className="rv2-sec-link" onClick={() => location.hash = `#/projects/${pdata.id}/research/studies`}>Browse all studies →</a>
        </div>
        <div className="rv2-recent-grid">
          {recent.map((r) => (
            <StudyCard key={r.id} r={r} pdata={pdata} openStudy={openStudy} />
          ))}
        </div>
      </section>
    </div>
  );
}

// =====================================================================
// 2. STUDIES LIBRARY
// =====================================================================
function StudiesLibrary({ pdata, openStudy }) {
  const [query, setQuery] = React.useState('');
  const [typeFilter, setTypeFilter] = React.useState('all');
  const [statusFilter, setStatusFilter] = React.useState('all');
  const [featureFilter, setFeatureFilter] = React.useState('all');

  const types = [
    { key: 'all',        label: 'All types',   n: pdata.research.length },
    { key: 'user',       label: 'User',        n: pdata.research.filter(r => r.type === 'user').length },
    { key: 'competitor', label: 'Competitor',  n: pdata.research.filter(r => r.type === 'competitor').length },
    { key: 'market',     label: 'Market',      n: pdata.research.filter(r => r.type === 'market').length },
    { key: 'technical',  label: 'Technical',   n: pdata.research.filter(r => r.type === 'technical').length },
    { key: 'experiment', label: 'Experiment',  n: pdata.research.filter(r => r.type === 'experiment').length },
    { key: 'insight',    label: 'Insight',     n: pdata.research.filter(r => r.type === 'insight').length },
  ].filter(t => t.n > 0);

  const statuses = [
    { key: 'all',           label: 'Any status' },
    { key: 'planned',       label: 'Planned' },
    { key: 'recruiting',    label: 'Recruiting' },
    { key: 'in-progress',   label: 'In progress' },
    { key: 'synthesizing',  label: 'Synthesizing' },
    { key: 'complete',      label: 'Complete' },
  ];

  const features = [
    { key: 'all', label: 'Any feature' },
    ...pdata.features.map(f => ({ key: f.id, label: f.title })),
  ];

  const filtered = pdata.research.filter((r) => {
    if (typeFilter !== 'all'    && r.type !== typeFilter) return false;
    if (statusFilter !== 'all'  && (r.status || 'complete') !== statusFilter) return false;
    if (featureFilter !== 'all' && !(r.connects?.features || []).includes(featureFilter)) return false;
    if (query.trim()) {
      const q = query.toLowerCase();
      if (!(
        r.title.toLowerCase().includes(q) ||
        (r.by || '').toLowerCase().includes(q) ||
        (r.insight || '').toLowerCase().includes(q)
      )) return false;
    }
    return true;
  });

  return (
    <div className="rv2-studies">
      <div className="rv2-filter-bar">
        <div className="rv2-search">
          <Icon name="search" size={13} strokeWidth={1.75} />
          <input
            type="text"
            placeholder="Search studies, owners, findings…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
          />
        </div>
        <div className="rv2-filter-group">
          {types.map(t => (
            <button
              key={t.key}
              className={`rv2-filter-chip${typeFilter === t.key ? ' active' : ''}`}
              onClick={() => setTypeFilter(t.key)}
            >
              {t.label}
              {t.key !== 'all' && <span className="n mono">{t.n}</span>}
            </button>
          ))}
        </div>
        <div className="rv2-filter-secondary">
          <select className="rv2-filter-select" value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
            {statuses.map(s => <option key={s.key} value={s.key}>{s.label}</option>)}
          </select>
          <select className="rv2-filter-select" value={featureFilter} onChange={(e) => setFeatureFilter(e.target.value)}>
            {features.map(f => <option key={f.key} value={f.key}>{f.label}</option>)}
          </select>
        </div>
      </div>

      {filtered.length === 0 ? (
        <div className="rv2-empty">
          <div className="rv2-empty-title">No studies match those filters.</div>
          <div className="rv2-empty-sub">Try clearing search or a filter chip.</div>
        </div>
      ) : (
        <div className="rv2-studies-grid">
          {filtered.map((r) => (
            <StudyCard key={r.id} r={r} pdata={pdata} openStudy={openStudy} />
          ))}
        </div>
      )}
    </div>
  );
}

// =====================================================================
// 3. INSIGHTS VIEW
// =====================================================================
function InsightsView({ pdata, openStudy }) {
  const insights = pdata.insights || [];
  const pinned = insights.filter(i => i.pinned);
  const rest   = insights.filter(i => !i.pinned);

  return (
    <div className="rv2-insights">
      <div className="rv2-insights-lead">
        <div className="rv2-insights-lead-eyebrow">The through-line</div>
        <p>
          These are the synthesised statements the team believes strongly enough to build against.
          Each one cites its studies and links to the features and decisions it should affect.
        </p>
      </div>

      {pinned.length > 0 && (
        <section className="rv2-sec">
          <div className="rv2-sec-head">
            <h3>Pinned</h3>
          </div>
          <div className="rv2-insights-editorial">
            {pinned.map((ins) => (
              <InsightEditorialCard key={ins.id} insight={ins} pdata={pdata} openStudy={openStudy} />
            ))}
          </div>
        </section>
      )}

      {rest.length > 0 && (
        <section className="rv2-sec">
          <div className="rv2-sec-head">
            <h3>All insights</h3>
            <span className="rv2-sec-sub">{rest.length}</span>
          </div>
          <div className="rv2-insights-list">
            {rest.map((ins) => (
              <InsightRow key={ins.id} insight={ins} pdata={pdata} openStudy={openStudy} />
            ))}
          </div>
        </section>
      )}
    </div>
  );
}

// =====================================================================
// 4. STUDY DETAIL
// =====================================================================
function StudyDetail({ pdata, study, onBack, openStudy }) {
  const [aiOpen, setAiOpen] = React.useState(null); // null | 'themes' | 'summary' | 'contradictions' | 'features' | 'missing'
  if (!study) {
    return (
      <div className="rv2-empty">
        <div className="rv2-empty-title">Study not found.</div>
        <a className="link" onClick={onBack}>← Back to Studies</a>
      </div>
    );
  }
  const statusInfo = studyStatusInfo(study.status);
  const feature = (study.connects?.features || []).map(fid => pdata.features.find(f => f.id === fid)).filter(Boolean)[0];
  const stage   = study.links?.stage && pdata.stages.find(s => s.n === study.links.stage);

  const evidence = study.evidence || [];
  const findings = study.findings || [];
  const attachments = study.attachments || [];
  const checklist = study.checklist || [];

  return (
    <div className="rv2-study" data-screen-label="StudyDetail">
      {/* Back link — never a whole breadcrumb, just a return path */}
      <div className="rv2-study-back">
        <a onClick={onBack} href={`#/projects/${pdata.id}/research/studies`}>
          <Icon name="chevronL" size={13} strokeWidth={2} />
          <span>Back to Research</span>
        </a>
      </div>

      {/* Header — compact */}
      <header className="rv2-study-head">
        <div className="rv2-study-head-main">
          <div className="rv2-study-typechip">
            <TypeGlyph type={study.type} />
            <span>{typeLabel(study.type)}</span>
          </div>
          <h1 className="rv2-study-title">{study.title}</h1>
          <p className="rv2-study-purpose">{study.question || study.insight}</p>
          <div className="rv2-study-meta">
            <div className="rv2-study-owner">
              <Avatar name={study.by} size="sm" />
              <span><b>{study.by}</b> · owner</span>
            </div>
            <span className="rv2-meta-sep" />
            <Label tone={statusInfo.tone} dot size="sm">{statusInfo.label}</Label>
            {study.participants ? (
              <>
                <span className="rv2-meta-sep" />
                <span className="rv2-study-meta-item">
                  <Icon name="users" size={12} strokeWidth={1.75} />
                  <span>{study.participants} participants</span>
                </span>
              </>
            ) : null}
            {study.startDate && (
              <>
                <span className="rv2-meta-sep" />
                <span className="rv2-study-meta-item">
                  <Icon name="calendar" size={12} strokeWidth={1.75} />
                  <span>{study.startDate}{study.endDate ? ` → ${study.endDate}` : ''}</span>
                </span>
              </>
            )}
          </div>
        </div>
        {(stage || feature) && (
          <div className="rv2-study-head-context">
            {stage && (
              <a href={`#/projects/${pdata.id}/plan`} className="rv2-study-ctx-chip">
                <div className="k">Stage</div>
                <div className="v">{String(stage.n).padStart(2,'0')} · {stage.name}</div>
              </a>
            )}
            {feature && (
              <a href={`#/projects/${pdata.id}/features/${feature.id}`} className="rv2-study-ctx-chip">
                <div className="k">Feature</div>
                <div className="v">{feature.title}</div>
              </a>
            )}
          </div>
        )}
      </header>

      <div className="rv2-study-body">
        {/* Main article */}
        <article className="rv2-study-article">
          {/* Editorial summary — question, why, method, conclusion */}
          <section className="rv2-study-sec">
            <div className="rv2-study-eyebrow">Research question</div>
            <p className="rv2-study-lead">{study.question || study.insight}</p>
            {study.whyItMatters && (
              <>
                <div className="rv2-study-eyebrow" style={{ marginTop: 24 }}>Why this matters</div>
                <p className="rv2-study-para">{study.whyItMatters}</p>
              </>
            )}
            {study.method && (
              <>
                <div className="rv2-study-eyebrow" style={{ marginTop: 24 }}>Method</div>
                <ul className="rv2-study-method">
                  {study.method.map((m, i) => <li key={i}>{m}</li>)}
                </ul>
              </>
            )}
            {study.conclusion && (
              <>
                <div className="rv2-study-eyebrow" style={{ marginTop: 24 }}>Current conclusion</div>
                <p className="rv2-study-conclusion">{study.conclusion}</p>
              </>
            )}
          </section>

          {/* Findings — synthesised statements */}
          {findings.length > 0 && (
            <section className="rv2-study-sec">
              <div className="rv2-study-sec-head">
                <h3>Findings</h3>
                <span className="rv2-sec-sub">{findings.length} synthesised from {evidence.length} pieces of evidence</span>
              </div>
              <div className="rv2-findings">
                {findings.map((f) => (
                  <FindingBlock key={f.id} f={f} pdata={pdata} />
                ))}
              </div>
            </section>
          )}

          {/* Evidence — first-class, per-kind previews */}
          {evidence.length > 0 && (
            <section className="rv2-study-sec">
              <div className="rv2-study-sec-head">
                <h3>Evidence</h3>
                <span className="rv2-sec-sub">{evidence.length} items · organized by kind</span>
              </div>
              <div className="rv2-evidence-grid">
                {evidence.map((e) => (
                  <EvidenceCard key={e.id} e={e} findings={findings} />
                ))}
              </div>
            </section>
          )}

          {/* Attachments */}
          {attachments.length > 0 && (
            <section className="rv2-study-sec">
              <div className="rv2-study-sec-head">
                <h3>Attachments</h3>
                <span className="rv2-sec-sub">{attachments.length} files &amp; links</span>
              </div>
              <div className="rv2-attach-grid">
                {attachments.map((a, i) => <StudyAttachmentCard key={i} a={a} />)}
              </div>
            </section>
          )}
        </article>

        {/* Rail */}
        <aside className="rv2-study-rail">
          {/* Study checklist */}
          {checklist.length > 0 && (
            <div className="rv2-rail-block">
              <div className="rv2-rail-head">
                <h4>Study checklist</h4>
                <span className="rv2-rail-count mono">
                  {checklist.filter(c => c.done).length}/{checklist.length}
                </span>
              </div>
              <ul className="rv2-checklist">
                {checklist.map((c, i) => (
                  <li key={i} className={c.done ? 'done' : 'pending'}>
                    <div className="mark">{c.done && <Icon name="check" size={11} strokeWidth={2.5}/>}</div>
                    <div>
                      <div className="t">{c.title}</div>
                      {(c.owner || c.due) && (
                        <div className="m">
                          {c.owner && <><Avatar name={c.owner} size="xs" /> {c.owner.split(' ')[0]}</>}
                          {c.owner && c.due && <span className="dot" />}
                          {c.due && <span>{c.due}</span>}
                        </div>
                      )}
                      {c.note && <div className="n">{c.note}</div>}
                      {c.attachment && (
                        <a className="a">
                          <Icon name="paperclip" size={10} strokeWidth={1.75}/>
                          {c.attachment}
                        </a>
                      )}
                    </div>
                  </li>
                ))}
              </ul>
              <div className="rv2-rail-foot">
                <a href="#/my-work" className="rv2-rail-link">Complex work · open in My Work →</a>
              </div>
            </div>
          )}

          {/* Related items (canonical) */}
          <div className="rv2-rail-block">
            <div className="rv2-rail-head"><h4>Related</h4></div>
            <RelatedTo links={study.links} pdata={pdata} compact />
            {(study.connects?.decisions || []).length > 0 && (
              <div className="rv2-rail-related">
                <div className="rv2-rail-sublabel">Decisions</div>
                {study.connects.decisions.map((idx, i) => {
                  const d = pdata.decisions?.[idx];
                  if (!d) return null;
                  return (
                    <a key={i} href={`#/projects/${pdata.id}/overview`} className="rv2-rail-related-row">
                      <Icon name="decisions" size={12} strokeWidth={1.75} />
                      <span className="t">{d.title}</span>
                      <Label tone={d.tone === 'green' ? 'green' : 'yellow'} dot size="sm">{d.status}</Label>
                    </a>
                  );
                })}
              </div>
            )}
            {(study.connects?.features || []).length > 0 && (
              <div className="rv2-rail-related">
                <div className="rv2-rail-sublabel">Features</div>
                {study.connects.features.map((fid, i) => {
                  const f = pdata.features.find(x => x.id === fid);
                  if (!f) return null;
                  return (
                    <a key={i} href={`#/projects/${pdata.id}/features/${f.id}`} className="rv2-rail-related-row">
                      <Icon name="features" size={12} strokeWidth={1.75} />
                      <span className="t">{f.title}</span>
                    </a>
                  );
                })}
              </div>
            )}
          </div>

          {/* AI assist — cite evidence */}
          <div className="rv2-rail-block rv2-assist">
            <div className="rv2-rail-head">
              <h4>Assist</h4>
            </div>
            <div className="rv2-assist-actions">
              {[
                { key: 'summary',        label: 'Summarize evidence' },
                { key: 'themes',         label: 'Extract themes' },
                { key: 'cluster',        label: 'Cluster similar evidence' },
                { key: 'insights',       label: 'Turn findings into insights' },
                { key: 'contradictions', label: 'Find contradictions' },
                { key: 'features',       label: 'Suggest related features' },
                { key: 'missing',        label: 'Identify missing evidence' },
              ].map(a => (
                <a
                  key={a.key}
                  onClick={() => setAiOpen(aiOpen === a.key ? null : a.key)}
                  className={aiOpen === a.key ? 'active' : ''}
                >
                  {a.label}
                </a>
              ))}
            </div>
            {aiOpen && (
              <AssistPanel action={aiOpen} study={study} onClose={() => setAiOpen(null)} />
            )}
          </div>
        </aside>
      </div>
    </div>
  );
}

// =====================================================================
// SUPPORT COMPONENTS
// =====================================================================

function studyStatusInfo(status) {
  const map = {
    'planned':      { label: 'Planned',       tone: 'gray'   },
    'recruiting':   { label: 'Recruiting',    tone: 'purple' },
    'in-progress':  { label: 'In progress',   tone: 'blue'   },
    'synthesizing': { label: 'Synthesizing',  tone: 'yellow' },
    'complete':     { label: 'Complete',      tone: 'green'  },
  };
  return map[status] || map.complete;
}

function typeLabel(t) {
  return { user: 'User research', competitor: 'Competitor', market: 'Market', technical: 'Technical', experiment: 'Experiment', insight: 'Insight' }[t] || 'Research';
}

function TypeGlyph({ type }) {
  const icon = { user: 'users', competitor: 'grid', market: 'chartBar', technical: 'stack', experiment: 'flask', insight: 'spark' }[type] || 'flask';
  return <Icon name={icon} size={11} strokeWidth={1.75} />;
}

// ---- Study card (grid + row) ----
function StudyCard({ r, pdata, openStudy }) {
  const statusInfo = studyStatusInfo(r.status);
  return (
    <a
      href={`#/projects/${pdata.id}/research/study/${r.id}`}
      onClick={(e) => { e.preventDefault(); openStudy(r.id); }}
      className={`rv2-study-card rv2-type-${r.type}`}
    >
      <div className="rv2-study-card-visual">
        <StudyPreview r={r} />
        <span className="rv2-study-card-typechip">
          <TypeGlyph type={r.type} />
          <span>{typeLabel(r.type)}</span>
        </span>
        {r.pinned && (
          <span className="rv2-study-card-pin" title="Pinned">
            <Icon name="pin" size={12} strokeWidth={1.75} />
          </span>
        )}
      </div>
      <div className="rv2-study-card-body">
        <div className="rv2-study-card-titlerow">
          <div className="rv2-study-card-title">{r.title}</div>
          <Label tone={statusInfo.tone} dot size="sm">{statusInfo.label}</Label>
        </div>
        {r.insight && (
          <div className="rv2-study-card-finding">{r.insight}</div>
        )}
        <div className="rv2-study-card-foot">
          <div className="rv2-study-card-owner">
            <Avatar name={r.by} size="xs" />
            <span>{r.by}</span>
          </div>
          <span className="rv2-study-card-date">{r.endDate || r.date}</span>
        </div>
        {r.links && <RelatedTo links={r.links} pdata={pdata} compact asSpan />}
      </div>
    </a>
  );
}

// ---- Active study row ----
function ActiveStudyRow({ r, pdata, openStudy }) {
  const statusInfo = studyStatusInfo(r.status);
  return (
    <a
      href={`#/projects/${pdata.id}/research/study/${r.id}`}
      onClick={(e) => { e.preventDefault(); openStudy(r.id); }}
      className="rv2-active-row"
    >
      <div className="rv2-active-typemark">
        <TypeGlyph type={r.type} />
      </div>
      <div className="rv2-active-body">
        <div className="rv2-active-title">{r.title}</div>
        <div className="rv2-active-sub">
          <span>{r.by}</span>
          {r.participants ? <><span>·</span><span>{r.participants} participants</span></> : null}
          {r.startDate ? <><span>·</span><span>{r.startDate}{r.endDate ? ` → ${r.endDate}` : ' → ongoing'}</span></> : null}
        </div>
      </div>
      <Label tone={statusInfo.tone} dot size="sm">{statusInfo.label}</Label>
      <Icon name="chevronRight" size={13} strokeWidth={2} style={{ color: 'var(--text-tertiary)' }} />
    </a>
  );
}

// ---- Per-type card preview ----
function StudyPreview({ r }) {
  if (r.type === 'user') {
    if (r.quote) {
      return (
        <div className="rv2-prev rv2-prev-user">
          <div className="rv2-prev-quote">{r.quote}</div>
          <div className="rv2-prev-quoteby">— {r.quoteBy || 'participant'}</div>
        </div>
      );
    }
    return (
      <div className="rv2-prev rv2-prev-user">
        <div className="rv2-prev-participants mono">{r.participants || '—'} participants</div>
        <div className="rv2-prev-role">{r.participantsNote || 'User research'}</div>
      </div>
    );
  }
  if (r.type === 'competitor') {
    return (
      <div className="rv2-prev rv2-prev-competitor">
        <div className="rv2-mini-frame">
          <div className="rv2-mf-topbar" />
          <div className="rv2-mf-body">
            <div className="rv2-mf-line" style={{ width: '55%' }} />
            <div className="rv2-mf-line" style={{ width: '80%' }} />
            <div className="rv2-mf-line" style={{ width: '70%' }} />
            <div className="rv2-mf-block" />
          </div>
        </div>
        <div className="rv2-mini-frame accent">
          <div className="rv2-mf-topbar" />
          <div className="rv2-mf-body">
            <div className="rv2-mf-line" style={{ width: '65%' }} />
            <div className="rv2-mf-line" style={{ width: '50%' }} />
            <div className="rv2-mf-block" />
          </div>
        </div>
      </div>
    );
  }
  if (r.type === 'market') {
    return (
      <div className="rv2-prev rv2-prev-market">
        <svg viewBox="0 0 280 140" width="100%" height="100%" preserveAspectRatio="none">
          <line x1="20" y1="120" x2="260" y2="120" stroke="rgba(0,0,0,0.06)" strokeWidth="1"/>
          {[42, 58, 74, 92, 102, 88, 116].map((h, i) => (
            <rect key={i} x={26 + i*34} y={120 - h} width="20" height={h} rx="3" fill="var(--primary-01)" opacity={0.20 + i * 0.09}/>
          ))}
        </svg>
      </div>
    );
  }
  if (r.type === 'technical') {
    return (
      <div className="rv2-prev rv2-prev-technical">
        <svg viewBox="0 0 280 140" width="100%" height="100%" preserveAspectRatio="none">
          <rect x="24" y="30" width="70" height="30" rx="8" fill="white" stroke="rgba(16,16,16,0.10)" strokeWidth="1.5"/>
          <rect x="24" y="80" width="70" height="30" rx="8" fill="white" stroke="rgba(16,16,16,0.10)" strokeWidth="1.5"/>
          <rect x="118" y="55" width="70" height="30" rx="8" fill="var(--primary-01)" stroke="rgba(42,133,255,0.55)" strokeWidth="1.5"/>
          <rect x="212" y="30" width="46" height="30" rx="8" fill="white" stroke="rgba(16,16,16,0.10)" strokeWidth="1.5"/>
          <rect x="212" y="80" width="46" height="30" rx="8" fill="white" stroke="rgba(16,16,16,0.10)" strokeWidth="1.5"/>
          <path d="M94 45 L118 62" stroke="rgba(16,16,16,0.30)" strokeWidth="1.5" fill="none"/>
          <path d="M94 95 L118 78" stroke="rgba(16,16,16,0.30)" strokeWidth="1.5" fill="none"/>
          <path d="M188 65 L212 45" stroke="var(--primary-01)" strokeWidth="1.75" fill="none"/>
          <path d="M188 75 L212 95" stroke="var(--primary-01)" strokeWidth="1.75" fill="none"/>
        </svg>
      </div>
    );
  }
  if (r.type === 'experiment') {
    return (
      <div className="rv2-prev rv2-prev-experiment">
        <div className="rv2-exp-row">
          <div className="rv2-exp-label">A</div>
          <div className="rv2-exp-bar"><div style={{ width: '52%' }} /></div>
        </div>
        <div className="rv2-exp-row">
          <div className="rv2-exp-label winner">B</div>
          <div className="rv2-exp-bar winner"><div style={{ width: '86%' }} /></div>
        </div>
        <div className="rv2-exp-note mono">B +34% · p&lt;0.05</div>
      </div>
    );
  }
  if (r.type === 'insight') {
    return (
      <div className="rv2-prev rv2-prev-insight">
        <div className="rv2-prev-insight-text">{r.insight}</div>
      </div>
    );
  }
  return <div className="rv2-prev rv2-prev-user" />;
}

// ---- Evidence quote card (compact, for overview strip) ----
function EvidenceQuoteCard({ e, studyId, openStudy, compact }) {
  return (
    <a
      onClick={() => openStudy(studyId)}
      className={`rv2-ev-quote${compact ? ' compact' : ''}`}
    >
      <div className="rv2-ev-kind">
        <Icon name={e.kind === 'clip' ? 'play' : e.kind === 'screenshot' ? 'image' : e.kind === 'survey' ? 'chartBar' : 'message'} size={11} strokeWidth={1.75} />
        <span>{e.kind}</span>
      </div>
      <div className="rv2-ev-text">{e.text}</div>
      <div className="rv2-ev-foot">
        {e.participant ? (
          <>
            <Avatar name={e.participant} size="xs" />
            <div>
              <div className="p">{e.participant}</div>
              {e.participantRole && <div className="r">{e.participantRole}</div>}
            </div>
          </>
        ) : (
          <span className="src">{e.participantRole || 'evidence'}</span>
        )}
        <span className="rv2-ev-date mono">{e.captured}</span>
      </div>
    </a>
  );
}

// ---- Evidence card (full grid on Study Detail) ----
function EvidenceCard({ e, findings }) {
  const linkedFindings = findings.filter(f => (e.findingIds || []).includes(f.id));
  return (
    <div className={`rv2-ev-card rv2-ev-${e.kind}`}>
      <div className="rv2-ev-card-head">
        <span className="rv2-ev-card-kind">
          <Icon name={e.kind === 'clip' ? 'play' : e.kind === 'screenshot' ? 'image' : e.kind === 'survey' ? 'chartBar' : e.kind === 'note' ? 'fileText' : 'message'} size={11} strokeWidth={1.75}/>
          <span>{e.kind}</span>
        </span>
        <span className="rv2-ev-card-date mono">{e.captured}</span>
      </div>
      <div className="rv2-ev-card-body">
        {e.kind === 'quote' && <div className="rv2-ev-card-quote">"{e.text}"</div>}
        {e.kind === 'clip' && (
          <div className="rv2-ev-card-clip">
            <div className="clip-glyph"><Icon name="play" size={20} strokeWidth={2}/></div>
            <div className="clip-text">
              <div className="t">{e.text}</div>
              {e.duration && <div className="d mono">{e.duration}</div>}
            </div>
          </div>
        )}
        {e.kind === 'note' && <div className="rv2-ev-card-note">{e.text}</div>}
        {e.kind === 'screenshot' && (
          <div className="rv2-ev-card-shot">
            <div className="rv2-shot-visual">
              <div className="rv2-shot-tabs">
                {Array.from({ length: 7 }).map((_, i) => <span key={i} />)}
              </div>
              <div className="rv2-shot-body">
                <div className="line" style={{ width: '60%' }} />
                <div className="line" style={{ width: '80%' }} />
                <div className="line" style={{ width: '45%' }} />
              </div>
            </div>
            <div className="rv2-ev-card-note">{e.text}</div>
          </div>
        )}
        {e.kind === 'survey' && (
          <div className="rv2-ev-card-survey">
            <svg viewBox="0 0 240 88" width="100%" height="88" preserveAspectRatio="none">
              {[62, 44, 78, 30, 66, 52].map((h, i) => (
                <rect key={i} x={20 + i*36} y={80 - h} width="22" height={h} rx="3" fill="var(--primary-01)" opacity={0.25 + i * 0.08}/>
              ))}
            </svg>
            <div className="rv2-ev-card-note">{e.text}</div>
          </div>
        )}
      </div>
      {(e.participant || e.participantRole || linkedFindings.length > 0) && (
        <div className="rv2-ev-card-foot">
          {e.participant && (
            <div className="rv2-ev-card-src">
              <Avatar name={e.participant} size="xs" />
              <div>
                <div className="p">{e.participant}</div>
                {e.participantRole && <div className="r">{e.participantRole}</div>}
              </div>
            </div>
          )}
          {linkedFindings.length > 0 && (
            <div className="rv2-ev-card-findings">
              {linkedFindings.map(f => (
                <span key={f.id} className="rv2-ev-card-finding" title={f.statement}>
                  <Icon name="link" size={10} strokeWidth={2}/>
                  <span>Finding {f.id.replace('fd', '')}</span>
                </span>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ---- Finding block ----
function FindingBlock({ f, pdata }) {
  const confMap = { high: 'green', medium: 'yellow', low: 'gray' };
  return (
    <div className="rv2-finding">
      <div className="rv2-finding-marker">
        <Icon name="target" size={10} strokeWidth={2} />
      </div>
      <div className="rv2-finding-body">
        <div className="rv2-finding-statement">{f.statement}</div>
        <div className="rv2-finding-meta">
          <span className="rv2-finding-ev mono">{(f.evidenceIds || []).length} pieces of evidence</span>
          {f.confidence && (
            <>
              <span className="rv2-meta-sep" />
              <Label tone={confMap[f.confidence] || 'gray'} dot size="sm">{f.confidence} confidence</Label>
            </>
          )}
        </div>
        {((f.features && f.features.length > 0) || (f.decisions && f.decisions.length > 0)) && (
          <div className="rv2-finding-links">
            <span className="rv2-finding-linkslabel">Affects</span>
            {(f.features || []).map(fid => {
              const feat = pdata.features.find(x => x.id === fid);
              if (!feat) return null;
              return (
                <a key={fid} href={`#/projects/${pdata.id}/features/${feat.id}`} className="rv2-finding-linkchip">
                  <Icon name="features" size={10} strokeWidth={1.75} />
                  <span>{feat.title}</span>
                </a>
              );
            })}
            {(f.decisions || []).map((didx, i) => {
              const d = pdata.decisions?.[didx];
              if (!d) return null;
              return (
                <a key={i} href={`#/projects/${pdata.id}/overview`} className="rv2-finding-linkchip">
                  <Icon name="decisions" size={10} strokeWidth={1.75} />
                  <span>{d.title}</span>
                </a>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}

// ---- Insight card (compact row) ----
function InsightRow({ insight: ins, pdata, openStudy }) {
  return (
    <div className="rv2-insight-row">
      <div className="rv2-insight-statement">{ins.statement}</div>
      <div className="rv2-insight-meta">
        <span className="mono"><b>{ins.evidenceCount}</b> pieces of evidence</span>
        <span className="rv2-meta-sep" />
        <span>From {ins.studyIds.length} stud{ins.studyIds.length === 1 ? 'y' : 'ies'}</span>
        <span className="rv2-meta-sep" />
        <Avatar name={ins.owner} size="xs" />
        <span>{ins.owner}</span>
        <span className="rv2-meta-sep" />
        <span className="mono">{ins.date}</span>
      </div>
      <div className="rv2-insight-links">
        {ins.features.map(fid => {
          const f = pdata.features.find(x => x.id === fid);
          if (!f) return null;
          return (
            <a key={fid} href={`#/projects/${pdata.id}/features/${f.id}`} className="rv2-finding-linkchip">
              <Icon name="features" size={10} strokeWidth={1.75}/>
              <span>{f.title}</span>
            </a>
          );
        })}
        {(ins.decisions || []).map((didx, i) => {
          const d = pdata.decisions?.[didx];
          if (!d) return null;
          return (
            <a key={i} href={`#/projects/${pdata.id}/overview`} className="rv2-finding-linkchip">
              <Icon name="decisions" size={10} strokeWidth={1.75}/>
              <span>{d.title}</span>
            </a>
          );
        })}
        {ins.studyIds.map(sid => (
          <a key={sid} onClick={() => openStudy(sid)} className="rv2-finding-linkchip">
            <Icon name="flask" size={10} strokeWidth={1.75}/>
            <span>{pdata.research.find(r => r.id === sid)?.title || sid}</span>
          </a>
        ))}
      </div>
    </div>
  );
}

// ---- Editorial insight card (pinned) ----
function InsightEditorialCard({ insight: ins, pdata, openStudy }) {
  return (
    <div className="rv2-insight-editorial">
      <div className="rv2-insight-editorial-eyebrow">
        <Icon name="spark" size={11} strokeWidth={1.75} />
        <span>Insight</span>
        {ins.pinned && <span className="mono" style={{ marginLeft: 8, color: 'var(--text-tertiary)' }}>· pinned</span>}
      </div>
      <div className="rv2-insight-editorial-statement">{ins.statement}</div>
      {ins.summary && <p className="rv2-insight-editorial-summary">{ins.summary}</p>}
      <div className="rv2-insight-editorial-footer">
        <div className="rv2-insight-editorial-facts">
          <div>
            <div className="k">Evidence</div>
            <div className="v mono">{ins.evidenceCount} items</div>
          </div>
          <div>
            <div className="k">Studies</div>
            <div className="v">{ins.studyIds.length}</div>
          </div>
          <div>
            <div className="k">Owner</div>
            <div className="v">
              <Avatar name={ins.owner} size="xs" /> {ins.owner}
            </div>
          </div>
        </div>
        <div className="rv2-insight-editorial-links">
          {ins.features.map(fid => {
            const f = pdata.features.find(x => x.id === fid);
            if (!f) return null;
            return (
              <a key={fid} href={`#/projects/${pdata.id}/features/${f.id}`} className="rv2-finding-linkchip">
                <Icon name="features" size={10} strokeWidth={1.75}/>
                <span>{f.title}</span>
              </a>
            );
          })}
          {ins.studyIds.map(sid => (
            <a key={sid} onClick={() => openStudy(sid)} className="rv2-finding-linkchip">
              <Icon name="flask" size={10} strokeWidth={1.75}/>
              <span>{pdata.research.find(r => r.id === sid)?.title || sid}</span>
            </a>
          ))}
        </div>
      </div>
    </div>
  );
}

// ---- Attachment card ----
function StudyAttachmentCard({ a }) {
  const iconMap = { pdf: 'fileText', doc: 'fileText', image: 'image', link: 'externalLink', sheet: 'grid' };
  return (
    <div className="rv2-attach">
      <div className={`rv2-attach-prev rv2-attach-${a.kind}`}>
        {a.kind === 'image' ? (
          <div className="rv2-attach-image">
            <div className="rv2-shot-tabs">
              {Array.from({ length: 7 }).map((_, i) => <span key={i} />)}
            </div>
            <div className="rv2-shot-body">
              <div className="line" style={{ width: '55%' }} />
              <div className="line" style={{ width: '70%' }} />
            </div>
          </div>
        ) : (
          <Icon name={iconMap[a.kind] || 'paperclip'} size={22} strokeWidth={1.5} />
        )}
        <span className="rv2-attach-kind">{a.kind.toUpperCase()}</span>
      </div>
      <div className="rv2-attach-meta">
        <div className="rv2-attach-name">{a.name}</div>
        <div className="rv2-attach-sub">
          {a.size && <span>{a.size}</span>}
          {a.size && <span className="dot" />}
          {a.updated && <span>{a.updated}</span>}
          {a.participant && <><span className="dot" /><span>{a.participant}</span></>}
        </div>
      </div>
    </div>
  );
}

// ---- Assist panel (evidence-cited) ----
function AssistPanel({ action, study, onClose }) {
  const content = React.useMemo(() => {
    const ev = study.evidence || [];
    switch (action) {
      case 'summary':
        return {
          title: 'Evidence summary',
          bullets: [
            'Nine new-teammate interviews (design-partner archetypes).',
            'Two synthetic runs with a structured brief cut context recovery to under 10 minutes.',
            '5 of 9 participants opened Slack search first, not their docs.',
          ],
          cites: ev.slice(0, 5).map(e => e.id),
        };
      case 'themes':
        return {
          title: 'Themes extracted',
          bullets: [
            'Context is scattered across ≥5 surfaces on first day.',
            'Freshness of the brief is the biggest single predictor of use.',
            'Ownership beats structure — teams with a designated brief owner drift 3× slower.',
          ],
          cites: ev.map(e => e.id).slice(0, 6),
        };
      case 'cluster':
        return {
          title: 'Evidence clusters',
          bullets: [
            'Cluster A — first-day tab-recovery: 3 quotes + 1 screenshot.',
            'Cluster B — decision hunt: 2 quotes + 1 note.',
            'Cluster C — synthetic-run measurement: 1 note + 1 survey.',
          ],
          cites: ev.map(e => e.id),
        };
      case 'insights':
        return {
          title: 'Suggested insights',
          bullets: [
            'The brief should be a living, connected surface — not a static document.',
            'Structured briefs cut new-teammate context recovery from 30–45 min to under 10.',
          ],
          cites: ev.slice(0, 4).map(e => e.id),
        };
      case 'contradictions':
        return {
          title: 'Contradictions found',
          bullets: [
            'One participant reported briefs were only ever read on kickoff week; three others read weekly. Cohort-size difference suggests team maturity is the split.',
          ],
          cites: [ev[1]?.id, ev[6]?.id].filter(Boolean),
        };
      case 'features':
        return {
          title: 'Related features',
          bullets: [
            'Smart Project Brief — 6 evidence hits',
            'Semantic search v2 — 3 evidence hits',
            'Decisions inbox — 2 evidence hits',
          ],
          cites: ev.slice(0, 5).map(e => e.id),
        };
      case 'missing':
        return {
          title: 'Missing evidence',
          bullets: [
            'No enterprise-tier team represented — recruit 2 from Enterprise plan.',
            'No engineer-only teams — most engineers were on cross-functional teams.',
            'No longitudinal data — currently only first-day observations.',
          ],
          cites: [],
        };
      default:
        return null;
    }
  }, [action, study]);
  if (!content) return null;
  return (
    <div className="rv2-assist-panel">
      <div className="rv2-assist-panel-head">
        <div className="t">{content.title}</div>
        <a onClick={onClose} className="close"><Icon name="x" size={13} strokeWidth={2}/></a>
      </div>
      <ul className="rv2-assist-bullets">
        {content.bullets.map((b, i) => <li key={i}>{b}</li>)}
      </ul>
      {content.cites.length > 0 && (
        <div className="rv2-assist-cites">
          <span>Cited evidence</span>
          {content.cites.map(id => <span key={id} className="rv2-assist-cite mono">{id}</span>)}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { ResearchWorkspaceV2 });
