// Surveys list + New Survey intake form (step 0 of the merged flow)

const { useState: useStateSL } = React;

// `mins` is how long ago the row was updated, and the list sorts on it. The
// "Updated" column already implied an order; before this the render ignored it,
// so the newest study sat third. A study you publish in-session gets -1 and
// lands above everything.
const SEED_STUDIES = [
  { id:'sv-gsc', name:'Men\'s & Women\'s Global Style / Color Test', owner:'Lucy Sandford', updated:'Today · just now', mins: 0, status:'Closed', responses: 1517, profiles: 5, badge:'neutral',
    cas: ['ca-age','ca-gender','ca-activity','ca-purchasefreq'] },
  { id:'sv-apparel', name:'Women\'s Apparel — FW26', owner:'Lucy Sandford', updated:'Today · 1h ago', mins: 60, status:'Live', responses: 222, profiles: 5, badge:'mint',
    cas: ['ca-age','ca-gender','ca-income'] },
  { id:'sv-gola', name:'MakerSights Women\'s Sneaker Study', owner:'Lucy Sandford', updated:'Today · 3h ago', mins: 180, status:'Live', responses: 1240, profiles: 3, badge:'mint',
    cas: ['ca-age','ca-gender','ca-activity','ca-purchasefreq','ca-social'] },
  { id:'sv-gola-closed', name:'MakerSights Women\'s Sneaker Study', owner:'Lucy Sandford', updated:'Today · 3h ago', mins: 185, status:'Closed', responses: 1240, profiles: 3, badge:'neutral',
    cas: ['ca-age','ca-gender','ca-activity','ca-purchasefreq','ca-social'] },
  { id:'sv-1', name:'FW\'25 running silo — launch tracker', owner:'Lucy Sandford', updated:'Today · 2h ago', mins: 120, status:'Live',     responses: 1842, profiles: 4, badge:'mint',
    cas: ['ca-age','ca-gender','ca-activity','ca-mileage','ca-purchasefreq','ca-spend'] },
  { id:'sv-2', name:'Receptivity Study', owner:'Lucy Sandford',     updated:'Yesterday', mins: 1440,     status:'Closed',    responses: 612,  profiles: 3, badge:'neutral',
    cas: ['ca-age','ca-gender','ca-income','ca-purchasefreq','ca-social'] },
  { id:'sv-3', name:'Design Validation Study',    owner:'Lucy Sandford',    updated:'3d ago', mins: 4320,        status:'Draft',     responses: 0,    profiles: 2, badge:'amber',
    cas: ['ca-age','ca-gender','ca-lastadidas','ca-social'] },
];

function byRecency(a, b) {
  const av = a.mins == null ? Number.MAX_SAFE_INTEGER : a.mins;
  const bv = b.mins == null ? Number.MAX_SAFE_INTEGER : b.mins;
  return av - bv;
}


// Product thumbnails per study — the real assets tested in it, from the
// account's asset library. Falls back to the collection the study belongs to.
const STUDY_COLLECTION = {
  'sv-gsc': "Global Run Lab AW27",
  'sv-apparel': "Women's Apparel FW26",
  'demo-study': "Women's Apparel FW26",
  'sv-gola': "Women's Sneaker Lab",
  'sv-gola-closed': "Women's Sneaker Lab",
  'sv-1': "Women's Sneaker Lab",
  'sv-2': "Women's Apparel FW26",
  'sv-3': "Women's Sneaker Lab",
};
function StudyThumbs({ studyId }) {
  const all = window.DEMO_ASSETS || [];
  if (!all.length) return null;
  const coll = STUDY_COLLECTION[studyId];
  const pool = coll ? all.filter(a => a.collection === coll) : all;
  if (!pool.length) return null;
  // Deterministic per-study offset so two studies on the same collection differ.
  let h = 0; for (let i = 0; i < String(studyId).length; i++) h = (h * 31 + String(studyId).charCodeAt(i)) % 9973;
  const pick = [0, 1, 2].map(k => pool[(h + k * 3) % pool.length]);
  return (
    <div style={{ display: 'inline-flex', flex: 'none', paddingTop: 2 }}>
      {pick.map((a, j) => (
        <div key={j} style={{
          width: 34, height: 34, borderRadius: 6, background: '#fafcfe',
          border: '1px solid #e5ebf1', overflow: 'hidden', marginLeft: j === 0 ? 0 : -10,
          boxShadow: '0 1px 2px rgba(4,12,21,0.06)', zIndex: 3 - j
        }}>
          <img src={a.img} alt="" loading="lazy" style={{ width: '100%', height: '100%', objectFit: 'contain', display: 'block' }}/>
        </div>
      ))}
    </div>
  );
}

function StudiesList({ onNewStudy, onOpenStudy, clickableIds = [], showChips = false, extraSurveys = [], justPublishedId = null }) {
  const [studies, setStudies] = useStateSL(() => [...extraSurveys, ...SEED_STUDIES].sort(byRecency));
  const [justDuplicated, setJustDuplicated] = useStateSL(null);
  const [openMenuId, setOpenMenuId] = useStateSL(null);
  const [statusFilter, setStatusFilter] = useStateSL('All');
  const [query, setQuery] = useStateSL('');
  const [caFilter, setCaFilter] = useStateSL([]); // array of CA ids — survey must cover ALL
  const [caPopOpen, setCaPopOpen] = useStateSL(false);

  const cas = window.CONSUMER_ATTRIBUTES || [];

  const filtered = studies.filter(s => {
    if (statusFilter !== 'All' && s.status !== statusFilter) return false;
    if (query && !s.name.toLowerCase().includes(query.toLowerCase())) return false;
    if (caFilter.length > 0) {
      const sCas = s.cas || [];
      // AND match: survey must cover every selected CA
      for (const cid of caFilter) if (!sCas.includes(cid)) return false;
    }
    return true;
  });

  const statusCounts = (() => {
    const out = { All: studies.length };
    ['Live','Draft','Closed','Archived'].forEach(s => out[s] = studies.filter(x => x.status === s).length);
    return out;
  })();

  const handleDuplicate = (s, e) => {
    if (e) e.stopPropagation();
    setOpenMenuId(null);
    const srcIdx = studies.findIndex(x => x.id === s.id);
    if (srcIdx < 0) return;
    const newId = `sv-${Date.now()}`;
    // Strip the trailing "(copy)" or "(copy N)" so we don't stack them indefinitely
    const baseName = s.name.replace(/\s*\(copy(?:\s+\d+)?\)\s*$/i, '');
    // Count existing copies of the same base to auto-number
    const copyRe = new RegExp('^' + baseName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\s*\\(copy(?:\\s+(\\d+))?\\)$', 'i');
    const siblings = studies.filter(x => copyRe.test(x.name));
    const suffix = siblings.length === 0 ? ' (copy)' : ` (copy ${siblings.length + 1})`;
    const dup = {
      ...s,
      id: newId,
      name: baseName + suffix,
      status: 'Draft',
      responses: 0,
      updated: 'Just now',
      badge: 'amber',
      _sourceId: s.id, // keep a breadcrumb — same profiles + question variants follow this in the prototype
    };
    // Insert right after the source row for immediate visibility
    const next = [...studies.slice(0, srcIdx + 1), dup, ...studies.slice(srcIdx + 1)];
    setStudies(next);
    setJustDuplicated(newId);
    setTimeout(() => setJustDuplicated(prev => (prev === newId ? null : prev)), 1600);
  };

  const handleArchive = (s, e) => {
    if (e) e.stopPropagation();
    setOpenMenuId(null);
    setStudies(prev => prev.map(x => x.id === s.id
      ? { ...x, status: 'Archived', badge: 'neutral', updated: 'Just now' }
      : x
    ));
  };

  return (
    <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', background: '#f6fafd' }} data-screen-label="01 Studies list">
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '32px 32px 48px' }}>
        <div style={{ display:'flex', alignItems:'flex-end', justifyContent:'space-between', marginBottom: 24 }}>
          <div>
            <h1 style={{ fontFamily:"'PP Telegraf'", fontSize: 28, fontWeight: 700, margin: '6px 0 4px', letterSpacing: '-0.01em' }}>Studies</h1>
            <div style={{ fontSize: 13, color: '#636c79' }}>
              {filtered.length} of {studies.length} studies{caFilter.length > 0 && <> · covering {caFilter.length} attribute{caFilter.length === 1 ? '' : 's'}</>} · 12,430 responses this quarter
            </div>
          </div>
          <div style={{ display:'flex', gap: 8 }}>
            <Button variant="solid" size="md" onClick={onNewStudy} icon={<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>}>New study</Button>
          </div>
        </div>

        {/* filter pills */}
        <div style={{ display:'flex', alignItems:'center', gap: 8, marginBottom: 16, fontFamily:"'PP Telegraf', sans-serif", flexWrap: 'wrap' }}>
          <div style={{ display:'flex', gap: 4, background: '#fff', border: '1px solid #e5ebf1', padding: 3, borderRadius: 900 }}>
            {['All', 'Live', 'Draft', 'Closed'].map((f) => {
              const active = statusFilter === f;
              return (
                <button key={f} onClick={() => setStatusFilter(f)} style={{
                  padding: '6px 14px', borderRadius: 900, fontSize: 12, fontWeight: 600, cursor: 'pointer', border: 'none',
                  background: active ? '#050301' : 'transparent', color: active ? '#fff' : '#050301', fontFamily: 'inherit',
                  display: 'inline-flex', alignItems: 'center', gap: 6
                }}>
                  {f}
                  <span style={{ fontSize: 10, fontWeight: 600, color: active ? '#cdd4dc' : '#636c79' }}>{statusCounts[f] ?? 0}</span>
                </button>
              );
            })}
          </div>

          {/* CA filter trigger */}
          <div style={{ position: 'relative' }}>
            <button onClick={() => setCaPopOpen(o => !o)} style={{
              height: 36, padding: '0 12px', borderRadius: 900,
              border: '1px solid ' + (caFilter.length > 0 ? '#3a8518' : '#e5ebf1'),
              background: caFilter.length > 0 ? '#f1f8ec' : '#fff',
              color: caFilter.length > 0 ? '#2b6418' : '#050301',
              fontSize: 12, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', gap: 6
            }}>
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
              Attributes covered
              {caFilter.length > 0 && (
                <span style={{ padding: '1px 7px', borderRadius: 900, background: '#3a8518', color: '#fff', fontSize: 10, fontWeight: 700 }}>{caFilter.length}</span>
              )}
              <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" style={{ transform: caPopOpen ? 'rotate(180deg)' : 'none', transition: 'transform 120ms' }}><polyline points="6 9 12 15 18 9"/></svg>
            </button>
            {caPopOpen && (
              <CAFilterPopover
                cas={cas}
                studies={studies}
                selected={caFilter}
                onChange={setCaFilter}
                onClose={() => setCaPopOpen(false)}
              />
            )}
          </div>

          {/* Selected CA chips */}
          {caFilter.map(cid => {
            const ca = cas.find(c => c.id === cid);
            if (!ca) return null;
            return (
              <span key={cid} style={{
                display: 'inline-flex', alignItems: 'center', gap: 6,
                padding: '5px 6px 5px 11px', borderRadius: 900,
                background: '#eef2f6', color: '#050301', fontSize: 12, fontWeight: 600
              }}>
                {ca.name}
                <button onClick={() => setCaFilter(prev => prev.filter(x => x !== cid))} style={{
                  width: 18, height: 18, border: 'none', background: '#fff', borderRadius: 900,
                  cursor: 'pointer', color: '#636c79', display: 'inline-flex', alignItems: 'center', justifyContent: 'center'
                }} title="Remove filter">
                  <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                </button>
              </span>
            );
          })}
          {caFilter.length > 0 && (
            <button onClick={() => setCaFilter([])} style={{
              border: 'none', background: 'transparent', color: '#636c79', fontSize: 12, fontWeight: 600,
              cursor: 'pointer', fontFamily: 'inherit'
            }}>Clear</button>
          )}

          <div style={{ position:'relative', marginLeft:'auto', width: 260 }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#636c79" strokeWidth="2" strokeLinecap="round" style={{position:'absolute', left: 12, top: 12}}><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
            <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search studies…" style={{ width:'100%', height: 38, padding:'0 12px 0 32px', borderRadius: 900, border: '1px solid #e5ebf1', fontSize: 13, fontFamily:'inherit', boxSizing:'border-box', background:'#fff' }}/>
          </div>
        </div>

        {/* surveys table */}
        <div style={{ background: '#fff', border: '1px solid #e5ebf1', borderRadius: 12, overflow: 'visible', fontFamily: "'PP Telegraf', sans-serif" }}>
          <div style={{ display:'grid', gridTemplateColumns: '1fr 100px 100px 90px 90px 44px', padding: '12px 20px', background:'#fafcfe', borderBottom: '1px solid #e5ebf1', fontSize: 11, fontWeight: 700, color: '#636c79', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
            <span>Name</span>
            <span>Status</span>
            <span>Owner</span>
            <span style={{textAlign:'right'}}>Responses</span>
            <span style={{textAlign:'right'}}>Profiles</span>
            <span/>
          </div>
          {filtered.length === 0 && (
            <div style={{ padding: 36, textAlign: 'center', color: '#636c79', fontFamily: "'PP Telegraf', sans-serif" }}>
              <div style={{ fontSize: 14, fontWeight: 600, color: '#050301', marginBottom: 4 }}>No studies match these filters</div>
              <div style={{ fontSize: 12 }}>Try removing an attribute or status filter.</div>
            </div>
          )}
          {filtered.map((s, i) => {
            const clickable = clickableIds.includes(s.id);
            return (
            <div key={s.id} style={{
              display:'grid', gridTemplateColumns: '1fr 100px 100px 90px 90px 44px',
              padding: '14px 20px', borderBottom: i === filtered.length-1 ? 'none' : '1px solid #e5ebf1',
              alignItems:'center', cursor: clickable ? 'pointer' : 'default',
              background: (justDuplicated === s.id || justPublishedId === s.id) ? '#f4faf9' : (clickable ? '#fff' : '#fcfdfe'),
              transition: 'background 420ms cubic-bezier(0.2,0,0,1)',
            }}
            onClick={() => { if (clickable && onOpenStudy) onOpenStudy(s); }}
            onMouseEnter={e => { if (clickable && justDuplicated !== s.id) e.currentTarget.style.background = '#fafcfe'; }}
            onMouseLeave={e => { if (clickable && justDuplicated !== s.id) e.currentTarget.style.background = '#fff'; }}>
              <div style={{ minWidth: 0, display: 'flex', alignItems: 'flex-start', gap: 14 }}>
                <StudyThumbs studyId={s.id} />
                <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 600, color: '#050301', marginBottom: 2, display: 'inline-flex', alignItems: 'center', gap: 7 }}>
                  {s.name}
                  {clickable && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#3a8518" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 18 15 12 9 6"/></svg>}
                </div>
                <div style={{ fontSize: 12, color: '#636c79', marginBottom: 6 }}>Updated {s.updated}</div>
                {showChips && <StudyCAChips studyCas={s.cas || []} highlight={caFilter} cas={cas}/>}
                </div>
              </div>
              <div>
                {s.status === 'Live' ? (
                  <span style={{
                    display:'inline-flex', alignItems:'center',
                    padding:'2px 10px', borderRadius:900, fontSize:12, fontWeight:600,
                    height:22, lineHeight:1, fontFamily:"'PP Telegraf', sans-serif", letterSpacing:'0.02em',
                    border:'1px solid #c8e2ba', background:'#daebd1', color:'#3a8518'
                  }}>Active</span>
                ) : (
                  <Badge tone={s.status === 'Draft' ? 'amber' : 'neutral'}>{s.status}</Badge>
                )}
              </div>
              <div style={{ fontSize: 13, color: '#050301' }}>{s.owner}</div>
              <div style={{ fontSize: 13, color: '#050301', textAlign:'right', fontVariantNumeric:'tabular-nums' }}>{s.responses.toLocaleString()}</div>
              <div style={{ textAlign:'right', display:'flex', justifyContent:'flex-end' }}>
                <div style={{ display:'inline-flex' }}>
                  {Array.from({length: Math.min(s.profiles, 3)}).map((_, j) => (
                    <div key={j} style={{
                      width: 20, height: 20, borderRadius: 999,
                      background: ['#3a8518','#6d4cd9','#d6563a','#0070eb','#d69d2b'][j],
                      color:'#fff', fontSize: 9, fontWeight: 700,
                      display:'flex', alignItems:'center', justifyContent:'center',
                      border:'1.5px solid #fff',
                      marginLeft: j === 0 ? 0 : -6
                    }}>{['TZ','ER','VS','PL','LB'][j]}</div>
                  ))}
                  {s.profiles > 3 && (
                    <div style={{ width: 20, height: 20, borderRadius: 999, background: '#eef2f6', color:'#636c79', fontSize: 9, fontWeight: 700, display:'flex', alignItems:'center', justifyContent:'center', border:'1.5px solid #fff', marginLeft:-6 }}>+{s.profiles-3}</div>
                  )}
                </div>
              </div>
              <div style={{ display: 'flex', justifyContent: 'flex-end', position: 'relative' }}>
                {clickable && (<>
                <button
                  onClick={(e) => { e.stopPropagation(); setOpenMenuId(openMenuId === s.id ? null : s.id); }}
                  title="More"
                  aria-label="More actions"
                  aria-haspopup="menu"
                  aria-expanded={openMenuId === s.id}
                  style={{
                    width: 30, height: 30, borderRadius: 8,
                    border: '1px solid ' + (openMenuId === s.id ? '#ced6de' : 'transparent'),
                    background: openMenuId === s.id ? '#eef2f6' : 'transparent',
                    color: '#636c79', cursor: 'pointer',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    transition: 'background 120ms, border-color 120ms, color 120ms'
                  }}
                  onMouseEnter={e => {
                    if (openMenuId === s.id) return;
                    e.currentTarget.style.background = '#eef2f6';
                    e.currentTarget.style.color = '#050301';
                  }}
                  onMouseLeave={e => {
                    if (openMenuId === s.id) return;
                    e.currentTarget.style.background = 'transparent';
                    e.currentTarget.style.color = '#636c79';
                  }}
                >
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></svg>
                </button>
                {openMenuId === s.id && (
                  <>
                    <div onClick={(e) => { e.stopPropagation(); setOpenMenuId(null); }} style={{ position: 'fixed', inset: 0, zIndex: 30 }}/>
                    <div onClick={(e) => e.stopPropagation()} style={{
                      position: 'absolute', top: 36, right: 0, zIndex: 31,
                      background: '#fff', border: '1px solid #e5ebf1', borderRadius: 10,
                      boxShadow: '0 8px 24px rgba(4,12,21,0.12)', padding: 4,
                      minWidth: 170, fontFamily: "'PP Telegraf', sans-serif",
                      animation: 'msMenuIn 140ms cubic-bezier(0.2,0,0,1)'
                    }}>
                      <style>{`@keyframes msMenuIn { from { opacity:0; transform: translateY(-4px) } to { opacity:1; transform: translateY(0) } }`}</style>
                      <MenuItem
                        icon={<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>}
                        label="Duplicate"
                        sub="Copy to a new draft"
                        onClick={(e) => handleDuplicate(s, e)}
                      />
                      <MenuItem
                        icon={<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="21 8 21 21 3 21 3 8"/><rect x="1" y="3" width="22" height="5"/><line x1="10" y1="12" x2="14" y2="12"/></svg>}
                        label="Archive"
                        sub="Move out of active list"
                        onClick={(e) => handleArchive(s, e)}
                        disabled={s.status === 'Archived'}
                      />
                    </div>
                  </>
                )}
                </>)}
              </div>
            </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

const INTAKE_DEFAULTS = {
  name: 'Spring \'26 trail runner — colorway validation',
  objective: 'Validate final 4 colorways for the Spring \'26 trail runner launch. Understand appeal across trend-sensitive and core-performance segments and identify a clear #1.',
  category: 'Footwear — trail running',
  product: 'Terrex Agravic Ultra',
  launchDate: '2026-03-15',
  surveyType: 'Colorway validation',
  audienceSize: 600,
};

function NewStudyIntake({ onContinue, onBack }) {
  const [data, setData] = useStateSL(INTAKE_DEFAULTS);
  const set = (k, v) => setData(prev => ({ ...prev, [k]: v }));

  const canContinue = data.name.trim() && data.objective.trim();

  return (
    <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', background: '#f6fafd' }} data-screen-label="02 New study intake">
      <div style={{ padding: '10px 24px', background: '#fff', borderBottom: '1px solid #e5ebf1', display: 'flex', alignItems: 'center', gap: 12, fontFamily: "'PP Telegraf', sans-serif", fontSize: 13 }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', color: '#3a8518', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6, padding: 0, fontFamily: 'inherit', fontWeight: 600 }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><polyline points="15 18 9 12 15 6" /></svg>
          All studies
        </button>
        <span style={{ color: '#ced6de' }}>/</span>
        <span style={{ fontWeight: 600 }}>New study</span>
      </div>

      <div style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
        <div style={{ maxWidth: 880, margin: '0 auto', padding: '48px 32px 32px', fontFamily: "'PP Telegraf', sans-serif" }}>
          <div style={{ marginBottom: 32 }}>
            <div style={{ fontSize: 11, fontWeight: 700, color: '#3a8518', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>Research intake · Step 1 of 2</div>
            <h1 style={{ fontFamily: "'PP Telegraf'", fontSize: 32, fontWeight: 700, margin: '0 0 6px', letterSpacing: '-0.01em' }}>Let's set up your survey</h1>
            <div style={{ fontSize: 15, color: '#636c79' }}>The basics. Next you'll choose which consumers you want to hear from.</div>
          </div>

          {/* Progress */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 28 }}>
            <div style={{ flex: 1, height: 4, borderRadius: 900, background: '#eef2f6', overflow: 'hidden' }}>
              <div style={{ width: '33%', height: '100%', background: '#3a8518', borderRadius: 900, transition: 'width 300ms cubic-bezier(0.2,0,0,1)' }}/>
            </div>
            <div style={{ fontSize: 12, fontWeight: 600, color: '#636c79', minWidth: 70, textAlign: 'right', fontVariantNumeric: 'tabular-nums' }}>1 / 3</div>
          </div>

          <div style={{ background: '#fff', border: '1px solid #e5ebf1', borderRadius: 12, padding: 28 }}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
              <Field label="Survey name" required>
                <input value={data.name} onChange={e => set('name', e.target.value)} style={inputStyle()} autoFocus/>
              </Field>

              <Field label="Research objective" required hint="One or two sentences on what decision this survey will inform.">
                <textarea value={data.objective} onChange={e => set('objective', e.target.value)} rows={3} style={{ ...inputStyle(), height: 'auto', padding: '10px 12px', resize: 'vertical', lineHeight: 1.5 }}/>
              </Field>

              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
                <Field label="Category">
                  <SelectLike value={data.category} options={['Footwear — trail running', 'Footwear — road running', 'Footwear — lifestyle', 'Apparel — outerwear', 'Apparel — performance', 'Accessories']} onChange={v => set('category', v)}/>
                </Field>
                <Field label="Product / concept">
                  <input value={data.product} onChange={e => set('product', e.target.value)} style={inputStyle()}/>
                </Field>
              </div>

              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 16 }}>
                <Field label="Survey type">
                  <SelectLike value={data.surveyType} options={['Colorway validation', 'Concept test', 'Pricing study', 'Brand tracker', 'Post-purchase']} onChange={v => set('surveyType', v)}/>
                </Field>
                <Field label="Target launch">
                  <input type="date" value={data.launchDate} onChange={e => set('launchDate', e.target.value)} style={inputStyle()}/>
                </Field>
                <Field label="Target responses" hint="Across all profiles">
                  <input type="number" value={data.audienceSize} onChange={e => set('audienceSize', +e.target.value)} style={inputStyle()}/>
                </Field>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div style={{ background: '#fff', borderTop: '1px solid #e5ebf1', boxShadow: '0 -4px 12px rgba(4,12,21,0.04)', fontFamily: "'PP Telegraf', sans-serif" }}>
        <div style={{ maxWidth: 880, margin: '0 auto', padding: '14px 32px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', boxSizing: 'border-box' }}>
          <Button variant="subtle" size="md" onClick={onBack}>Cancel</Button>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <span style={{ fontSize: 12, color: '#636c79' }}>You can edit these details later from survey settings.</span>
            <Button variant="solid" size="md" disabled={!canContinue} onClick={() => onContinue(data)} icon={
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
            }>Continue to profiles</Button>
          </div>
        </div>
      </div>
    </div>
  );
}

function Field({ label, required, hint, children }) {
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <span style={{ fontSize: 12, fontWeight: 600, color: '#050301' }}>
        {label}{required && <span style={{ color: '#bf3826', marginLeft: 4 }}>*</span>}
      </span>
      {children}
      {hint && <span style={{ fontSize: 11, color: '#636c79' }}>{hint}</span>}
    </label>
  );
}

function inputStyle() {
  return {
    height: 40, padding: '0 12px', borderRadius: 8, border: '1px solid #ced6de',
    background: '#fff', fontSize: 14, color: '#050301', fontFamily: 'inherit',
    outline: 'none', width: '100%', boxSizing: 'border-box'
  };
}

function SelectLike({ value, options, onChange }) {
  const [open, setOpen] = useStateSL(false);
  return (
    <div style={{ position: 'relative' }}>
      <button onClick={() => setOpen(v => !v)} style={{
        ...inputStyle(), display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        cursor: 'pointer', textAlign: 'left'
      }}>
        <span>{value}</span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#636c79" strokeWidth="2" strokeLinecap="round"><polyline points="6 9 12 15 18 9" /></svg>
      </button>
      {open && (
        <>
          <div onClick={() => setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 10 }}/>
          <div style={{ position: 'absolute', top: 'calc(100% + 4px)', left: 0, right: 0, zIndex: 11, background: '#fff', border: '1px solid #e5ebf1', borderRadius: 8, boxShadow: '0 8px 24px rgba(4,12,21,0.12)', padding: 4, maxHeight: 260, overflowY: 'auto' }}>
            {options.map(o => (
              <button key={o} onClick={() => { onChange(o); setOpen(false); }} style={{
                display: 'block', width: '100%', textAlign: 'left', padding: '8px 12px',
                border: 'none', background: o === value ? '#f4faf9' : 'transparent', cursor: 'pointer',
                fontSize: 13, color: '#050301', borderRadius: 6, fontFamily: 'inherit'
              }}>{o}</button>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function MenuItem({ icon, label, sub, onClick, disabled, destructive }) {
  const [hover, setHover] = useStateSL(false);
  const baseColor = destructive ? '#bf3826' : '#050301';
  return (
    <button
      onClick={disabled ? undefined : onClick}
      disabled={disabled}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: 'flex', alignItems: 'center', gap: 10,
        width: '100%', padding: '8px 10px',
        border: 'none', borderRadius: 6,
        background: (!disabled && hover) ? '#f4faf9' : 'transparent',
        color: disabled ? '#adb6c0' : baseColor,
        cursor: disabled ? 'default' : 'pointer',
        fontFamily: 'inherit', textAlign: 'left',
        transition: 'background 120ms'
      }}
    >
      <span style={{ width: 18, height: 18, display: 'flex', alignItems: 'center', justifyContent: 'center', color: disabled ? '#adb6c0' : '#636c79', flex: 'none' }}>{icon}</span>
      <span style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>
        <span style={{ fontSize: 13, fontWeight: 600, lineHeight: 1.2 }}>{label}</span>
        {sub && <span style={{ fontSize: 11, color: disabled ? '#adb6c0' : '#636c79', marginTop: 2 }}>{sub}</span>}
      </span>
    </button>
  );
}

/* SEED_STUDIES is exported so a shared link can resolve a study id back to
   the row it names without the list being on screen first. */
Object.assign(window, { StudiesList, NewStudyIntake, SEED_STUDIES });

/* =============================================================
   CA-coverage UI for the surveys list:
   - StudyCAChips: compact chip stack under each survey name
   - CAFilterPopover: dropdown picker for filtering by covered CAs
   ============================================================= */

function StudyCAChips({ studyCas, highlight, cas }) {
  if (!studyCas || studyCas.length === 0) return (
    <span style={{ fontSize: 11, color: '#adb6c0', fontFamily: "'PP Telegraf', sans-serif" }}>No attributes mapped</span>
  );
  // Show highlighted (matched) chips first, then up to 4 total.
  const ordered = [
    ...studyCas.filter(c => highlight.includes(c)),
    ...studyCas.filter(c => !highlight.includes(c)),
  ];
  const VISIBLE = 4;
  const visible = ordered.slice(0, VISIBLE);
  const overflow = ordered.length - visible.length;
  return (
    <div style={{ display: 'inline-flex', flexWrap: 'wrap', gap: 4, fontFamily: "'PP Telegraf', sans-serif" }}>
      {visible.map(cid => {
        const ca = cas.find(c => c.id === cid);
        if (!ca) return null;
        const matched = highlight.includes(cid);
        return (
          <span key={cid} title={ca.description || ca.name} style={{
            padding: '2px 8px', borderRadius: 900, fontSize: 11, fontWeight: 600,
            border: matched ? '1px solid #3a8518' : '1px solid #e5ebf1',
            background: matched ? '#f1f8ec' : '#fff',
            color: matched ? '#2b6418' : '#636c79',
            display: 'inline-flex', alignItems: 'center', gap: 4
          }}>
            {matched && <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3.4" strokeLinecap="round"><polyline points="20 6 9 17 4 12"/></svg>}
            {ca.name}
          </span>
        );
      })}
      {overflow > 0 && (
        <span title={ordered.slice(VISIBLE).map(cid => cas.find(c => c.id === cid)?.name).filter(Boolean).join(' · ')} style={{
          padding: '2px 8px', borderRadius: 900, fontSize: 11, fontWeight: 600,
          border: '1px solid #e5ebf1', background: '#fafcfe', color: '#636c79'
        }}>+{overflow} more</span>
      )}
    </div>
  );
}

function CAFilterPopover({ cas, studies, selected, onChange, onClose }) {
  const [q, setQ] = useStateSL('');
  const filtered = cas.filter(c => !q || c.name.toLowerCase().includes(q.toLowerCase()));
  const toggle = (cid) => {
    onChange(selected.includes(cid) ? selected.filter(x => x !== cid) : [...selected, cid]);
  };
  // For each CA: how many surveys cover it. Shown as a hint.
  const coverageCount = (cid) => studies.filter(s => (s.cas || []).includes(cid)).length;
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 30 }}/>
      <div style={{
        position: 'absolute', top: 'calc(100% + 6px)', left: 0, zIndex: 31,
        width: 320, background: '#fff', border: '1px solid #e5ebf1', borderRadius: 10,
        boxShadow: '0 12px 32px rgba(4,12,21,0.14)', padding: 8,
        fontFamily: "'PP Telegraf', sans-serif",
        animation: 'msMenuIn 140ms cubic-bezier(0.2,0,0,1)'
      }} onClick={(e) => e.stopPropagation()}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '6px 8px 8px' }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: '#636c79', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
            Filter by attributes covered
          </div>
          {selected.length > 0 && (
            <button onClick={() => onChange([])} style={{ border: 'none', background: 'transparent', color: '#3a8518', fontSize: 11, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' }}>Clear</button>
          )}
        </div>
        <div style={{ fontSize: 11, color: '#636c79', padding: '0 8px 8px', lineHeight: 1.45 }}>
          Surveys that cover <strong style={{ color: '#050301' }}>all</strong> selected attributes will match.
        </div>
        <div style={{ position: 'relative', padding: '0 8px 8px' }}>
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#636c79" strokeWidth="2" strokeLinecap="round" style={{ position: 'absolute', left: 18, top: 9 }}><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
          <input autoFocus value={q} onChange={e => setQ(e.target.value)} placeholder="Search attributes…" style={{ width: '100%', height: 30, padding: '0 10px 0 28px', borderRadius: 8, border: '1px solid #e5ebf1', fontSize: 12, fontFamily: 'inherit', boxSizing: 'border-box', outline: 'none', background: '#fafcfe' }}/>
        </div>
        <div style={{ maxHeight: 280, overflowY: 'auto', padding: '0 4px 4px' }}>
          {filtered.map(ca => {
            const on = selected.includes(ca.id);
            const cov = coverageCount(ca.id);
            return (
              <button key={ca.id} onClick={() => toggle(ca.id)} style={{
                display: 'flex', alignItems: 'center', gap: 10, width: '100%',
                padding: '7px 8px', border: 'none', borderRadius: 6, cursor: 'pointer',
                background: on ? '#f4faf9' : 'transparent',
                fontFamily: 'inherit', textAlign: 'left'
              }}
              onMouseEnter={e => { if (!on) e.currentTarget.style.background = '#fafcfe'; }}
              onMouseLeave={e => { if (!on) e.currentTarget.style.background = 'transparent'; }}>
                <span style={{
                  width: 16, height: 16, borderRadius: 4, flex: 'none',
                  border: on ? '1px solid #3a8518' : '1px solid #ced6de',
                  background: on ? '#3a8518' : '#fff',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center'
                }}>
                  {on && <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3.4" strokeLinecap="round"><polyline points="20 6 9 17 4 12"/></svg>}
                </span>
                <span style={{ flex: 1, fontSize: 13, color: '#050301', fontWeight: on ? 600 : 500 }}>{ca.name}</span>
                <span style={{ fontSize: 11, color: '#636c79' }}>{cov}</span>
              </button>
            );
          })}
          {filtered.length === 0 && (
            <div style={{ padding: 12, fontSize: 12, color: '#636c79', textAlign: 'center' }}>No attributes match "{q}"</div>
          )}
        </div>
      </div>
    </>
  );
}

Object.assign(window, { StudyCAChips, CAFilterPopover });