// sv-admin.jsx — Admin Portal

const { useState: useAdminSt, useEffect: useAdminEf } = React;

const DEMO_SUBMISSIONS = [
  { id: "demo-1", companyName: "Redwood Distribution", facilityName: "Sacramento DC", facilityAddress: "1400 Distribution Way, Sacramento CA", facilityType: "Distribution center", facilitySize: "75k-200k sq ft", employees: "150-500", contactName: "Marcus Webb", contactTitle: "Director of Operations", contactEmail: "m.webb@redwooddist.com", contactPhone: "+1 916 555 0182", vmsProvider: "Milestone XProtect", hasCameras: "Yes", zones: [{ id: "1", name: "Receiving dock", cameras: "6" }, { id: "2", name: "Sortation line", cameras: "8" }, { id: "3", name: "Shipping bay", cameras: "4" }], workflows: ["Receiving","Sorting","Shipping","Safety compliance"], goals: ["End-of-shift reports","Incident detection","Real-time alerts"], reportFrequency: "End of shift", successLookLike: "Daily throughput reports with anomaly flagging.", score: 9, status: "Ready for setup", submittedAt: new Date(Date.now() - 2 * 86400000).toISOString(), acks: { limitedScope: true, readOnly: true, defaultRetention: true, docsConfig: true, modelConsent: true, authorized: true }, zoneSOPs: { "1": [{ name: "receiving_sop.pdf" }] }, files: [], internalSecurityReqs: "SOC 2 Type II required.", bottleneck: "Cannot track sortation throughput in real-time.", incidents: "" },
  { id: "demo-2", companyName: "Frostline Cold Chain", facilityName: "Portland Hub", facilityAddress: "800 Freezer Row, Portland OR", facilityType: "Cold storage", facilitySize: "25k-75k sq ft", employees: "25-50", contactName: "Lin Tran", contactTitle: "Facility Manager", contactEmail: "lin.tran@frostline.io", contactPhone: "+1 503 555 0041", vmsProvider: "Eagle Eye Networks", hasCameras: "Some areas", zones: [{ id: "1", name: "Freezer bay A", cameras: "3" }, { id: "2", name: "Loading dock", cameras: "2" }], workflows: ["Receiving","Cold chain monitoring","Loading / unloading"], goals: ["Incident detection","Audit trail","SLA compliance"], reportFrequency: "Hourly", successLookLike: "", score: 6, status: "Waiting on SOPs", submittedAt: new Date(Date.now() - 5 * 86400000).toISOString(), acks: { limitedScope: true, readOnly: true, defaultRetention: false, docsConfig: false, modelConsent: true, authorized: true }, zoneSOPs: {}, files: [], internalSecurityReqs: "", bottleneck: "Temperature deviations aren't caught until audit.", incidents: "One recall scare in Q1 due to missed excursion." },
  { id: "demo-3", companyName: "Halcyon Fulfillment", facilityName: "Chicago East", facilityAddress: "2200 Logistics Park, Chicago IL", facilityType: "Fulfillment center", facilitySize: "200k-500k sq ft", employees: "500+", contactName: "Sarah Okonkwo", contactTitle: "VP Supply Chain", contactEmail: "s.okonkwo@halcyon.com", contactPhone: "+1 312 555 0097", vmsProvider: "Genetec Security Center", hasCameras: "Yes", zones: [{ id: "1", name: "Packing stations", cameras: "12" }, { id: "2", name: "Returns processing", cameras: "4" }, { id: "3", name: "QA floor", cameras: "6" }, { id: "4", name: "Staging lanes", cameras: "8" }], workflows: ["Packing","Returns","QA inspection","Staging"], goals: ["Performance metrics","Real-time alerts","Root cause analysis","End-of-shift reports"], reportFrequency: "Real-time", successLookLike: "Per-station throughput tracked live, anomalies flagged within 2 min.", score: 8, status: "Ready for setup", submittedAt: new Date(Date.now() - 1 * 86400000).toISOString(), acks: { limitedScope: true, readOnly: true, defaultRetention: true, docsConfig: true, modelConsent: true, authorized: true }, zoneSOPs: { "1": [{ name: "packing_sop.pdf" }, { name: "packing_q2.pdf" }] }, files: [], internalSecurityReqs: "VPN-only access preferred.", bottleneck: "No visibility into per-station productivity without manual walkthroughs.", incidents: "" }
];

const SUBMISSIONS_API = 'https://dd6vq097rc.execute-api.us-east-1.amazonaws.com/default/submissions';

function AdminPortal() {
  const [authed, setAuthed] = useAdminSt(() => sessionStorage.getItem('svAdminAuth') === '1');
  const [pw, setPw] = useAdminSt('');
  const [err, setErr] = useAdminSt('');
  const [subs, setSubs] = useAdminSt([]);
  const [expanded, setExpanded] = useAdminSt(null);
  const [loading, setLoading] = useAdminSt(false);
  const [favorites, setFavorites] = useAdminSt(() => new Set(JSON.parse(localStorage.getItem('svAdminFavorites') || '[]')));
  const [showFavs, setShowFavs] = useAdminSt(false);

  const loadSubs = (showDemo) => {
    setLoading(true);
    const stored = JSON.parse(localStorage.getItem('svSubmissions') || '[]');
    fetch(SUBMISSIONS_API)
      .then(r => r.json())
            .then(apiSubs => {
        const rawArr = Array.isArray(apiSubs) ? apiSubs : [];
        // Deduplicate by id — the VMS Lambda caches submissions under a second S3 key
        // in the same prefix, so the listing API can return the same record twice.
        const seenIds = new Set();
        const apiArr = rawArr.filter(s => {
          const id = s.id || s.submissionId;
          if (!id || seenIds.has(id)) return false;
          seenIds.add(id);
          return true;
        });
        const localById = {};
        stored.forEach(s => { if (s.id) localById[s.id] = s; });
        const enriched = apiArr.map(apiSub => {
          const local = localById[apiSub.id || apiSub.submissionId];
          if (!local) return apiSub;
          const enrichedSOPs = {};
          Object.entries(apiSub.zoneSOPs || {}).forEach(([zid, files]) => {
            const lByName = {};
            const localFilesForZone = (local.zoneSOPs || {})[zid];
            (Array.isArray(localFilesForZone) ? localFilesForZone : []).forEach(f => { if (f && f.name) lByName[f.name] = f; });
            enrichedSOPs[zid] = (Array.isArray(files) ? files : []).map(f => (f && f.name ? { ...f, dataUrl: f.dataUrl || (lByName[f.name] || {}).dataUrl } : f));
          });
          return { ...apiSub, zoneSOPs: enrichedSOPs };
        });
        const apiIds = new Set(apiArr.map(s => s.id || s.submissionId).filter(Boolean));
        const localOnly = stored.filter(s => !apiIds.has(s.id));
        const merged = [...enriched, ...localOnly];
        if (merged.length > 0) {
          setSubs([...merged].sort((a, b) => new Date(b.submittedAt) - new Date(a.submittedAt)));
        } else if (showDemo) {
          setSubs(DEMO_SUBMISSIONS);
        } else {
          setSubs([]);
        }
      })
      .catch(() => {
        if (stored.length > 0) {
          setSubs([...stored].sort((a, b) => new Date(b.submittedAt) - new Date(a.submittedAt)));
        } else if (showDemo) {
          setSubs(DEMO_SUBMISSIONS);
        }
      })
      .finally(() => setLoading(false));
  };

  useAdminEf(() => {
    if (!authed) return;
    loadSubs(true);
  }, [authed]);

  const ADMIN_HASH = '43e8a5fb1c6ecfea2529e42f1a02af43b2852485e076eddc8c6e9320fb8c8df6';

  const login = async () => {
    try {
      const enc = new TextEncoder();
      const buf = await crypto.subtle.digest('SHA-256', enc.encode(pw));
      const hex = Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');
      if (hex === ADMIN_HASH) { sessionStorage.setItem('svAdminAuth','1'); setAuthed(true); setErr(''); }
      else setErr('Incorrect password.');
    } catch { setErr('Incorrect password.'); }
  };

  const logout = () => { sessionStorage.removeItem('svAdminAuth'); setAuthed(false); setPw(''); };

  const refresh = () => loadSubs(false);

  const toggleFavorite = (id) => {
    setFavorites(prev => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      localStorage.setItem('svAdminFavorites', JSON.stringify([...next]));
      return next;
    });
  };

  if (!authed) return (
    <div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--sv-bg)', padding: 24 }}>
      <div style={{ width: '100%', maxWidth: 380 }}>
        <div style={{ textAlign: 'center', marginBottom: 28 }}>
          <a href="/"><img src="logo-supervision.png" alt="Super Vision" style={{ height: 28, marginBottom: 20 }} /></a>
          <h2 style={{ fontSize: 20, fontWeight: 700, margin: '0 0 6px', letterSpacing: '-0.01em' }}>Admin portal</h2>
          <p style={{ fontSize: 13, color: 'var(--sv-fg-3)', margin: 0 }}>Enter your password to access the pilot intake pipeline.</p>
        </div>
        <Card>
          <form onSubmit={e => { e.preventDefault(); login(); }} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <Input value={pw} onChange={setPw} type="password" placeholder="Password" icon="lock" label="Password" />
            {err && <div style={{ fontSize: 13, color: 'var(--sv-err)' }}>{err}</div>}
            <Button type="submit" fullWidth onClick={login}>Sign in</Button>
          </form>
        </Card>
        <div style={{ textAlign: 'center', marginTop: 18 }}>
          <a href="#/intake/setup" style={{ fontSize: 13, color: 'var(--sv-fg-3)' }}>← Back to intake form</a>
        </div>
      </div>
    </div>
  );

  const displaySubs = showFavs ? subs.filter(s => favorites.has(s.id)) : subs;
  const ready   = displaySubs.filter(s => s.status === 'Ready for setup').length;
  const waiting = displaySubs.filter(s => s.status === 'Waiting on SOPs').length;
  const newSubs = displaySubs.filter(s => s.status === 'New submission').length;

  return (
    <div style={{ minHeight: '100vh', background: 'var(--sv-bg)' }}>
      <div style={{ height: 56, borderBottom: '1px solid var(--sv-line-1)', background: 'rgba(251,248,241,0.9)', backdropFilter: 'blur(12px)', display: 'flex', alignItems: 'center', padding: '0 24px', gap: 12, position: 'sticky', top: 0, zIndex: 10 }}>
        <a href="/"><img src="logo-supervision.png" alt="Super Vision" style={{ height: 22 }} /></a>
        <div style={{ width: 1, height: 18, background: 'var(--sv-line-2)' }} />
        <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--sv-fg-2)' }}>Admin portal</span>
        <div style={{ flex: 1 }} />
        <Button variant="ghost" size="sm" icon="plus" onClick={() => window.location.hash = '/intake/setup'}>New intake</Button>
        <Button variant="ghost" size="sm" icon="log-out" onClick={logout}>Sign out</Button>
      </div>

      <div style={{ maxWidth: 1100, margin: '0 auto', padding: '32px 24px' }}>
        <div style={{ display: 'flex', alignItems: 'flex-end', gap: 16, marginBottom: 24 }}>
          <div>
            <h2 style={{ margin: '0 0 4px', fontSize: 22, fontWeight: 700, letterSpacing: '-0.015em' }}>Pilot pipeline</h2>
            <p style={{ margin: 0, fontSize: 13, color: 'var(--sv-fg-3)' }}>{showFavs ? `${displaySubs.length} of ${subs.length}` : subs.length} submission{(showFavs ? displaySubs.length : subs.length) !== 1 ? 's' : ''}{showFavs ? ' · favorites' : ''}</p>
          </div>
          <div style={{ flex: 1 }} />
          <div style={{ display: 'flex', gap: 10 }}>
            {[['Ready for setup','live', ready], ['Waiting on SOPs','warn', waiting], ['New submission','neutral', newSubs]].map(([label, tone, count]) =>
              count > 0 ? <Pill key={label} tone={tone} dot>{count} {label}</Pill> : null
            )}
          </div>
          <Button variant="ghost" size="sm" icon="refresh-cw" onClick={refresh} disabled={loading}>{loading ? 'Loading…' : 'Refresh'}</Button>
          <button type="button" onClick={() => setShowFavs(v => !v)} style={{ display: 'flex', alignItems: 'center', gap: 5, padding: '5px 12px', background: showFavs ? 'var(--sv-accent)' : 'transparent', border: showFavs ? '1px solid var(--sv-accent)' : '1px solid var(--sv-line-1)', borderRadius: 8, fontSize: 13, fontWeight: 500, color: showFavs ? '#fff' : 'var(--sv-fg-2)', cursor: 'pointer', fontFamily: 'var(--sv-font-sans)' }}>
            <span style={{ fontSize: 15, lineHeight: 1 }}>{showFavs ? '★' : '☆'}</span>
            Favorites{favorites.size > 0 ? ` (${favorites.size})` : ''}
          </button>
        </div>

        {displaySubs.length === 0 ? (
          <Card style={{ textAlign: 'center', padding: '48px 24px' }}>
            <Icon name={showFavs ? 'star' : 'inbox'} size={30} color="var(--sv-fg-4)" />
            <p style={{ fontSize: 14, color: 'var(--sv-fg-3)', marginTop: 10 }}>{showFavs ? 'No favorited submissions. Click the ☆ on any submission to favorite it.' : 'No submissions yet.'}</p>
            {!showFavs && (
              <div style={{ marginTop: 14 }}>
                <Button variant="secondary" size="sm" onClick={() => window.location.hash = '/intake/setup'}>Start an intake</Button>
              </div>
            )}
          </Card>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {displaySubs.map(sub => (
              <AdminRow key={sub.id} sub={sub} open={expanded === sub.id} onToggle={() => setExpanded(expanded === sub.id ? null : sub.id)} isFavorited={favorites.has(sub.id)} onToggleFavorite={toggleFavorite} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function AdminFieldGroup({ title, children }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 0, background: 'var(--sv-bg-elev-1)', border: '1px solid var(--sv-line-1)', borderRadius: 'var(--sv-r-lg)', overflow: 'hidden' }}>
      <div style={{ padding: '10px 16px', borderBottom: '1px solid var(--sv-line-1)', background: 'var(--sv-bg-elev-2)' }}>
        <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--sv-fg-3)', letterSpacing: '0.08em', textTransform: 'uppercase' }}>{title}</span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column' }}>{children}</div>
    </div>
  );
}

function AdminField({ label, value, full }) {
  if (!value && value !== 0) return null;
  return (
    <div style={{ display: 'flex', gap: 12, padding: '9px 16px', borderBottom: '1px solid var(--sv-line-1)', flexDirection: full ? 'column' : 'row', alignItems: full ? 'flex-start' : 'baseline' }}>
      <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--sv-fg-4)', minWidth: full ? undefined : 160, flexShrink: 0, letterSpacing: '0.02em' }}>{label}</div>
      <div style={{ fontSize: 13, color: 'var(--sv-fg-1)', lineHeight: 1.55 }}>{value}</div>
    </div>
  );
}

function CopyLinkButton({ subId }) {
  const [copied, setCopied] = useAdminSt(false);
  const link = `${location.origin}${location.pathname}#/vms-access/${subId}`;
  const copy = () => {
    navigator.clipboard.writeText(link).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  return (
    <Button variant="secondary" size="sm" icon={copied ? 'check' : 'link'} onClick={copy}>
      {copied ? 'Copied!' : 'Copy access link'}
    </Button>
  );
}

function downloadSubmission(sub) {
  // Strip base64 dataUrls (can be huge) — replace with just file names so the JSON stays readable
  const clean = JSON.parse(JSON.stringify(sub));
  Object.entries(clean.zoneSOPs || {}).forEach(([zid, files]) => {
    clean.zoneSOPs[zid] = (Array.isArray(files) ? files : []).map(f => {
      if (!f || typeof f !== 'object') return f;
      const { dataUrl, ...rest } = f;
      return dataUrl ? { ...rest, _note: 'dataUrl omitted for size' } : rest;
    });
  });
  (Array.isArray(clean.files) ? clean.files : []).forEach((f, i) => {
    if (f && f.dataUrl) { clean.files[i] = { ...f, dataUrl: undefined, _note: 'dataUrl omitted for size' }; }
  });
  const blob = new Blob([JSON.stringify(clean, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  const safeName = (sub.companyName || 'submission').replace(/[^a-zA-Z0-9_-]/g, '_');
  const dateStr = new Date(sub.submittedAt).toISOString().slice(0, 10);
  a.href = url;
  a.download = `sv-submission-${safeName}-${dateStr}.json`;
  a.click();
  URL.revokeObjectURL(url);
}

function AdminRow({ sub, open, onToggle, isFavorited, onToggleFavorite }) {
  const date = new Date(sub.submittedAt).toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true, timeZone: 'America/Los_Angeles', timeZoneName: 'short' });
  const tone = sub.score >= 8 ? 'live' : sub.score >= 5 ? 'warn' : 'neutral';

  const totalSOPs = Object.values(sub.zoneSOPs || {}).reduce((a, arr) => a + (Array.isArray(arr) ? arr.length : 0), 0);

  return (
    <div style={{ background: 'var(--sv-bg-elev-1)', border: '1px solid var(--sv-line-1)', borderRadius: 'var(--sv-r-lg)', overflow: 'hidden' }}>
      {/* Header row — div not button so inner buttons are valid HTML */}
      <div role="button" tabIndex={0} onClick={onToggle} onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && onToggle()} style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 16, padding: '14px 20px', cursor: 'pointer', fontFamily: 'var(--sv-font-sans)', textAlign: 'left' }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 600, fontSize: 14, color: 'var(--sv-fg-1)', marginBottom: 2 }}>{sub.companyName || 'Unnamed'}</div>
          <div style={{ fontSize: 12, color: 'var(--sv-fg-3)' }}>{[sub.facilityName, sub.facilityType, sub.contactEmail].filter(Boolean).join(' · ')}</div>
        </div>
        <ScoreBadge score={sub.score || 0} />
        <Pill tone={tone} dot>{sub.status || 'New submission'}</Pill>
        <span style={{ fontSize: 12, color: 'var(--sv-fg-4)', minWidth: 88, textAlign: 'right' }}>{date}</span>
        <button
          type="button"
          title={isFavorited ? 'Remove from favorites' : 'Add to favorites'}
          onClick={e => { e.stopPropagation(); onToggleFavorite(sub.id); }}
          style={{ display: 'flex', alignItems: 'center', padding: '4px 6px', background: 'transparent', border: 'none', fontSize: 18, lineHeight: 1, color: isFavorited ? '#f5a623' : 'var(--sv-fg-4)', cursor: 'pointer', flexShrink: 0 }}>
          {isFavorited ? '★' : '☆'}
        </button>
        <button
          type="button"
          title="Download submission as JSON"
          onClick={e => { e.stopPropagation(); downloadSubmission(sub); }}
          style={{ display: 'flex', alignItems: 'center', gap: 5, padding: '4px 10px', background: 'var(--sv-bg-sunken)', border: '1px solid var(--sv-line-1)', borderRadius: 8, fontSize: 12, color: 'var(--sv-fg-2)', cursor: 'pointer', fontFamily: 'var(--sv-font-sans)', flexShrink: 0 }}>
          <Icon name="download" size={13} color="var(--sv-fg-3)" />
          Download
        </button>
        <Icon name={open ? 'chevron-up' : 'chevron-down'} size={16} color="var(--sv-fg-3)" />
      </div>

      {open && (
        <div style={{ borderTop: '1px solid var(--sv-line-1)', padding: '20px 24px', background: 'var(--sv-bg)', display: 'flex', flexDirection: 'column', gap: 16 }}>

          {/* Contact */}
          <AdminFieldGroup title="Contact">
            <AdminField label="Name" value={[sub.contactName, sub.contactTitle].filter(Boolean).join(', ')} />
            <AdminField label="Email" value={sub.contactEmail} />
            <AdminField label="Phone" value={sub.contactPhone} />
          </AdminFieldGroup>

          {/* Facility */}
          <AdminFieldGroup title="Facility">
            <AdminField label="Company" value={sub.companyName} />
            <AdminField label="Facility name" value={sub.facilityName} />
            <AdminField label="Address" value={sub.facilityAddress} />
            <AdminField label="Type" value={sub.facilityType} />
            <AdminField label="Size" value={sub.facilitySize} />
            <AdminField label="Employees" value={sub.employees} />
            <AdminField label="Operating days" value={sub.operatingDays} />
            <AdminField label="Operating hours" value={sub.operatingHours} />
            <AdminField label="Shifts per day" value={sub.shiftsPerDay} />
            {(sub.shiftSchedules || []).map((s, i) => (
              <AdminField key={s.id || i} label={`Shift ${i + 1}`} value={`${s.name} · ${s.start}–${s.end} · ${s.days}`} />
            ))}
          </AdminFieldGroup>

          {/* Operational context */}
          {(sub.bottleneck || sub.incidents) && (
            <AdminFieldGroup title="Operational context">
              {sub.bottleneck && <AdminField label="Bottleneck" value={sub.bottleneck} full />}
              {sub.incidents  && <AdminField label="Incidents / near-misses" value={sub.incidents} full />}
            </AdminFieldGroup>
          )}

          {/* Camera & VMS */}
          <AdminFieldGroup title="Camera & VMS">
            <AdminField label="Cameras installed" value={sub.hasCameras} />
            {sub.plansToInstallCameras && <AdminField label="Camera plans" value={sub.plansToInstallCameras} />}
            <AdminField label="VMS provider" value={sub.vmsProvider} />
            {sub.loginUrl && <AdminField label="VMS login URL" value={sub.loginUrl} />}
            {sub.internalSecurityReqs && <AdminField label="Security requirements" value={sub.internalSecurityReqs} full />}
          </AdminFieldGroup>

          {/* Zones */}
          <AdminFieldGroup title={`Zones (${(sub.zones || []).length})`}>
            {(sub.zones || []).map((z, i) => {
              const rawZoneFiles = (sub.zoneSOPs || {})[z.id];
              const zoneFiles = Array.isArray(rawZoneFiles) ? rawZoneFiles : [];
              return (
                <div key={z.id || i} style={{ padding: '10px 16px', borderBottom: '1px solid var(--sv-line-1)' }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: z.issues || zoneFiles.length ? 6 : 0 }}>
                    <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--sv-fg-1)' }}>{z.name || 'Unnamed zone'}</span>
                    {z.cameras && <Pill tone="neutral">{z.cameras} cam{z.cameras !== '1' ? 's' : ''}</Pill>}
                    {zoneFiles.length > 0 && <Pill tone="live" dot>{zoneFiles.length} SOP{zoneFiles.length !== 1 ? 's' : ''}</Pill>}
                  </div>
                  {z.issues && <div style={{ fontSize: 13, color: 'var(--sv-fg-2)', lineHeight: 1.55 }}>{z.issues}</div>}
                  {zoneFiles.length > 0 && (
                    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 7 }}>
                      {zoneFiles.map((f, fi) => (
                        f.dataUrl ? (
                          <a key={fi} href={f.dataUrl} download={f.name}
                            style={{ display: 'flex', alignItems: 'center', gap: 5, padding: '3px 10px', background: 'var(--sv-bg-sunken)', border: '1px solid var(--sv-accent-tint)', borderRadius: 8, fontSize: 12, color: 'var(--sv-accent)', textDecoration: 'none', cursor: 'pointer' }}>
                            <Icon name="download" size={12} color="var(--sv-accent)" />
                            {f.name}
                          </a>
                        ) : (
                          <div key={fi} style={{ display: 'flex', alignItems: 'center', gap: 5, padding: '3px 10px', background: 'var(--sv-bg-sunken)', border: '1px solid var(--sv-line-1)', borderRadius: 8, fontSize: 12, color: 'var(--sv-fg-2)' }}>
                            <Icon name="file-text" size={12} color="var(--sv-fg-4)" />
                            {f.name}
                          </div>
                        )
                      ))}
                    </div>
                  )}
                </div>
              );
            })}
          </AdminFieldGroup>

          {/* Workflows & Goals */}
          <AdminFieldGroup title="Scope">
            <AdminField label="Workflows" value={(sub.workflows || []).join(', ')} full />
            <AdminField label="Goals" value={(sub.goals || []).join(', ')} full />
            <AdminField label="Report frequency" value={sub.reportFrequency} />
            {sub.successLookLike && <AdminField label="Success definition" value={sub.successLookLike} full />}
          </AdminFieldGroup>

          {/* Notes */}
          {sub.notes && (
            <AdminFieldGroup title="Notes">
              <AdminField label="Additional notes" value={sub.notes} full />
            </AdminFieldGroup>
          )}

          {/* Actions */}
          <div style={{ display: 'flex', gap: 10, paddingTop: 4, flexWrap: 'wrap' }}>
            <Button variant="secondary" size="sm" icon="external-link" onClick={() => { window.location.hash = `/vms-access/${sub.id}`; }}>Set up VMS access</Button>
            <CopyLinkButton subId={sub.id} />
            <Button variant="secondary" size="sm" icon="download" onClick={() => downloadSubmission(sub)}>Download JSON</Button>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { AdminPortal });
