/* Workspace settings — port of prototype settings.jsx (simplified).
   Sections: Profile, Account, Notifications, Appearance, Danger zone.
   Most fields are visual-only; the Sign out / Switch theme actions
   are real. */

/* Tab list — Billing only renders for canSeeBilling roles (org_admin
   + aquaos_admin). Per Oli, billing isn't worth its own top-level
   nav for org_admin so it nests inside Settings. */
function ST_buildTabs() {
  const tabs = [
    { id: 'profile',       label: 'Profile' },
    { id: 'account',       label: 'Account' },
    { id: 'notifications', label: 'Notifications' },
    { id: 'appearance',    label: 'Appearance' },
  ];
  const role = Auth && Auth.getUser && Auth.getUser() && Auth.getUser().role;
  /* Bulk Operations — admin tool moved out of the sidebar (bug
     30480d6a). Visible to roles that previously had the standalone
     Bulk page in their nav. */
  if (role === 'aquaos_admin' || role === 'org_admin' || role === 'site_manager' || role === 'admin') {
    tabs.push({ id: 'bulk', label: 'Bulk operations' });
  }
  /* Audit log — moved out of the sidebar (bug 30480d6a). org_admin /
     aquaos_admin only, matching the original ROLE_NAV gating. */
  if (role === 'aquaos_admin' || role === 'org_admin' || role === 'admin') {
    tabs.push({ id: 'audit', label: 'Audit log' });
  }
  /* Team / Users — opens the full Users page rather than embedding,
     because the table needs more width than this modal's 1fr column.
     Org-admin + aquaos-admin only. The tab is render-as-link
     (handled in the tab click handler — see SettingsScreen). */
  if (role === 'aquaos_admin' || role === 'org_admin') {
    tabs.push({ id: 'team', label: 'Team', external: true });
  }
  // Feedback log — visible to admins (org_admin / aquaos_admin) since
  // the API filters status changes to those roles. Everyone else just
  // submits via the topbar bug icon.
  if (role === 'org_admin' || role === 'aquaos_admin') {
    tabs.push({ id: 'feedback', label: 'Feedback' });
  }
  if (Auth && typeof Auth.canSeeBilling === 'function' && Auth.canSeeBilling()) {
    tabs.push({ id: 'billing', label: 'Billing & usage' });
  }
  tabs.push({ id: 'danger', label: 'Danger zone' });
  return tabs;
}

/* Feedback panel — lists all submitted bug reports + feature requests.
   Toggle each item Open/Done; delete to purge entirely. The list is the
   working backlog Claude / engineers pull from.

   Screenshots — submitters can attach up to 4 images via the bug popover;
   they render as 64×64 thumbnails per row and click into a centered
   lightbox so admins can read pixel-level details (text on the screen,
   exact button position, etc.) without leaving the panel. */
function ST_FeedbackPanel() {
  const [items, setItems] = useState([]);
  const [counts, setCounts] = useState({ open: 0, done: 0 });
  const [filter, setFilter] = useState('open');
  const [loading, setLoading] = useState(true);
  // Lightbox state — null when closed, otherwise the URL string of the
  // screenshot to display full-bleed over a dimmed backdrop.
  const [zoomUrl, setZoomUrl] = useState(null);

  function load() {
    setLoading(true);
    fetch(`/api/feedback?status=${filter}&limit=200`, { credentials: 'include' })
      .then(r => r.json())
      .then(d => {
        setItems(d.items || []);
        const c = { open: 0, done: 0 };
        (d.counts || []).forEach(row => { c[row.status] = Number(row.n) || 0; });
        setCounts(c);
      })
      .catch(() => setItems([]))
      .finally(() => setLoading(false));
  }
  useEffect(load, [filter]);

  // ESC closes the lightbox (and only the lightbox — the parent settings
  // modal listens for ESC too, so we stop propagation when zoom is open).
  useEffect(() => {
    if (!zoomUrl) return;
    const onKey = (e) => {
      if (e.key === 'Escape') {
        e.stopPropagation();
        setZoomUrl(null);
      }
    };
    document.addEventListener('keydown', onKey, true);  // capture phase wins over the settings modal
    return () => document.removeEventListener('keydown', onKey, true);
  }, [zoomUrl]);

  async function setStatus(id, status) {
    await fetch(`/api/feedback/${id}`, {
      method: 'PATCH', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ status }),
    });
    load();
  }
  async function purge(id) {
    if (!confirm('Delete this item permanently?')) return;
    await fetch(`/api/feedback/${id}`, { method: 'DELETE', credentials: 'include' });
    load();
  }

  // Build a structured plain-text dump of the visible items. The output is
  // shaped for pasting into a chat with Claude — predictable separators,
  // explicit kind/status/page so each item is independently triagable
  // without back-context, and screenshot URLs included as references the
  // assistant can ask for if needed (it can't open them itself, but the
  // human can).
  function buildExportText() {
    const lines = [];
    lines.push('=== Slate Feedback Export ===');
    lines.push('Filter: ' + filter + ' · Items: ' + items.length);
    lines.push('Generated: ' + new Date().toISOString());
    lines.push('');
    items.forEach((it, idx) => {
      const shots = Array.isArray(it.screenshots) ? it.screenshots : [];
      lines.push('───────────────────────────────────────────────');
      lines.push('#' + (idx + 1) + '  [id=' + it.id + ']');
      lines.push('  ' + new Date(it.created_at).toISOString()
                 + '  ·  ' + (it.kind || '?')
                 + '  ·  ' + (it.status || '?'));
      lines.push('  by: ' + (it.submitted_by_name || it.submitted_by_email || 'Anonymous'));
      if (it.page_url) {
        lines.push('  page: ' + (it.page_title || '') + '  (' + it.page_url + ')');
      }
      lines.push('');
      // Indent the body so multi-line text stays visually grouped under
      // the metadata block. Empty lines preserved.
      String(it.text || '').split('\n').forEach((l) => lines.push('  ' + l));
      if (shots.length) {
        lines.push('');
        lines.push('  Screenshots (' + shots.length + '):');
        shots.forEach((u) => lines.push('    - ' + u));
      }
      lines.push('');
    });
    return lines.join('\n');
  }

  const [copyState, setCopyState] = useState('idle'); // 'idle' | 'copied' | 'error'
  async function copyAll() {
    const text = buildExportText();
    try {
      await navigator.clipboard.writeText(text);
      setCopyState('copied');
    } catch (e) {
      // Fallback for older browsers / non-secure contexts: use a hidden
      // textarea + execCommand. Less reliable but means the button never
      // looks broken on a kiosk-managed Chrome.
      try {
        const ta = document.createElement('textarea');
        ta.value = text;
        ta.style.position = 'fixed';
        ta.style.left = '-9999px';
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        document.body.removeChild(ta);
        setCopyState('copied');
      } catch (_) {
        setCopyState('error');
      }
    }
    setTimeout(() => setCopyState('idle'), 2000);
  }

  const KIND_BADGE = { bug: '🐞', feature: '💡', other: '💬' };

  return (
    <>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14, gap: 12, flexWrap: 'wrap' }}>
        <h2 style={{ margin: 0, fontFamily: 'var(--aq-ff-display)', fontSize: 16, fontWeight: 500, color: 'var(--aq-text)' }}>Feedback</h2>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          {/* Copy-all — bundles the visible items as structured text so an
              admin can paste the entire backlog into a Claude chat in one
              go. The button label flips through idle → copied → idle to
              confirm without needing a toast. */}
          <button
            onClick={copyAll}
            disabled={items.length === 0}
            title="Copy all visible feedback as text"
            style={{
              padding: '4px 10px', borderRadius: 6,
              border: '1px solid var(--aq-line)',
              background: copyState === 'copied' ? 'var(--aq-accent, #00c8b4)' : 'transparent',
              color: copyState === 'copied' ? '#0a1024' : 'var(--aq-text-dim)',
              fontFamily: 'inherit', fontSize: 12, fontWeight: 500,
              cursor: items.length === 0 ? 'not-allowed' : 'pointer',
              opacity: items.length === 0 ? 0.4 : 1,
              transition: 'background 0.15s, color 0.15s',
            }}
          >
            {copyState === 'copied' ? '✓ Copied' : copyState === 'error' ? 'Copy failed' : 'Copy all'}
          </button>
          <div style={{ display: 'flex', gap: 4 }}>
            {[['open', 'Open', counts.open], ['done', 'Done', counts.done], ['all', 'All', counts.open + counts.done]].map(([id, label, n]) => (
              <button
                key={id}
                onClick={() => setFilter(id)}
                style={{
                  padding: '4px 10px', borderRadius: 999,
                  border: '1px solid ' + (filter === id ? 'var(--aq-accent-line, rgba(0,200,180,0.4))' : 'var(--aq-line)'),
                  background: filter === id ? 'var(--aq-accent-soft, rgba(0,200,180,0.14))' : 'transparent',
                  color: filter === id ? 'var(--aq-text)' : 'var(--aq-text-dim)',
                  fontFamily: 'inherit', fontSize: 12, fontWeight: 500, cursor: 'pointer',
                }}
              >{label} <span style={{ opacity: 0.6, marginLeft: 4 }}>{n}</span></button>
            ))}
          </div>
        </div>
      </div>
      {loading && <div style={{ color: 'var(--aq-text-faint)', fontSize: 12, padding: '20px 0' }}>Loading…</div>}
      {!loading && items.length === 0 && (
        <div style={{ color: 'var(--aq-text-faint)', fontSize: 13, padding: '40px 16px', textAlign: 'center' }}>
          {filter === 'open' ? 'Nothing in the backlog. 🎉' : 'No items.'}
        </div>
      )}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {items.map((it) => {
          const shots = Array.isArray(it.screenshots) ? it.screenshots : [];
          return (
            <div key={it.id} style={{
              border: '1px solid var(--aq-line)', borderRadius: 8,
              padding: '12px 14px', background: 'var(--aq-surface-2, rgba(255,255,255,0.04))',
              opacity: it.status === 'done' ? 0.55 : 1,
            }}>
              <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
                <span style={{ fontSize: 18, lineHeight: 1.2 }}>{KIND_BADGE[it.kind] || '💬'}</span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{
                    whiteSpace: 'pre-wrap', fontSize: 13, color: 'var(--aq-text)', lineHeight: 1.5,
                    textDecoration: it.status === 'done' ? 'line-through' : 'none',
                  }}>{it.text}</div>

                  {/* Screenshot thumbnails — render below the text so the
                      eye lands on the comment first, then the visual. */}
                  {shots.length > 0 && (
                    <div style={{
                      marginTop: 8, display: 'flex', flexWrap: 'wrap', gap: 6,
                    }}>
                      {shots.map((url, idx) => (
                        <button
                          key={url + idx}
                          type="button"
                          onClick={() => setZoomUrl(url)}
                          aria-label={`Open screenshot ${idx + 1}`}
                          title="Click to zoom"
                          style={{
                            width: 64, height: 64, padding: 0,
                            border: '1px solid var(--aq-line)', borderRadius: 6,
                            background: 'transparent', overflow: 'hidden',
                            cursor: 'zoom-in',
                          }}
                        >
                          <img src={url} alt=""
                            style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
                        </button>
                      ))}
                    </div>
                  )}

                  <div style={{
                    marginTop: 6, fontSize: 10.5, color: 'var(--aq-text-faint)',
                    display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center',
                  }}>
                    <span>{it.submitted_by_name || it.submitted_by_email || 'Anonymous'}</span>
                    <span>·</span>
                    <span>{new Date(it.created_at).toLocaleString()}</span>
                    {it.page_url && (
                      <>
                        <span>·</span>
                        <a href={it.page_url} target="_blank" rel="noreferrer"
                           style={{ color: 'var(--aq-text-dim)', textDecoration: 'underline' }}>
                          {(it.page_title || it.page_url).slice(0, 60)}
                        </a>
                      </>
                    )}
                  </div>
                </div>
                <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
                  <button
                    onClick={() => setStatus(it.id, it.status === 'done' ? 'open' : 'done')}
                    title={it.status === 'done' ? 'Reopen' : 'Mark done'}
                    style={{
                      padding: '5px 10px', borderRadius: 6,
                      border: '1px solid var(--aq-line)',
                      background: it.status === 'done' ? 'transparent' : 'var(--aq-accent, #00c8b4)',
                      color: it.status === 'done' ? 'var(--aq-text-dim)' : '#0a1024',
                      fontSize: 11, fontWeight: 600, cursor: 'pointer',
                    }}
                  >{it.status === 'done' ? 'Reopen' : 'Done'}</button>
                  <button
                    onClick={() => purge(it.id)}
                    title="Delete permanently"
                    style={{
                      padding: '5px 8px', borderRadius: 6,
                      border: '1px solid var(--aq-line)',
                      background: 'transparent', color: 'var(--aq-text-faint)',
                      fontSize: 11, cursor: 'pointer',
                    }}
                  >×</button>
                </div>
              </div>
            </div>
          );
        })}
      </div>

      {/* Lightbox — portalled to body so it covers everything including
          the settings modal that contains this panel. Click the backdrop
          (or press ESC) to close. The image scales to fit while
          preserving aspect via maxWidth/maxHeight + objectFit:contain. */}
      {zoomUrl && ReactDOM.createPortal((
        <div
          onClick={() => setZoomUrl(null)}
          style={{
            position: 'fixed', inset: 0, zIndex: 10000,
            background: 'rgba(0,0,0,0.85)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            padding: 32, cursor: 'zoom-out',
          }}
        >
          <img
            src={zoomUrl}
            alt="Feedback screenshot"
            onClick={(e) => e.stopPropagation()}
            style={{
              maxWidth: '100%', maxHeight: '100%', objectFit: 'contain',
              borderRadius: 8, boxShadow: '0 30px 80px rgba(0,0,0,0.6)',
              cursor: 'default',
            }}
          />
          <a
            href={zoomUrl}
            target="_blank"
            rel="noreferrer"
            onClick={(e) => e.stopPropagation()}
            style={{
              position: 'fixed', bottom: 24, right: 24,
              padding: '6px 12px', borderRadius: 6,
              background: 'rgba(255,255,255,0.12)', color: '#fff',
              fontSize: 12, textDecoration: 'none',
              border: '1px solid rgba(255,255,255,0.2)',
            }}
          >Open original ↗</a>
        </div>
      ), document.body)}
    </>
  );
}

function SettingsScreen() {
  const ST_TABS = ST_buildTabs();
  const [tab, setTab] = useState('profile');
  const me = Auth.getUser() || {};
  const [theme, setTheme] = useState(document.body.dataset.theme || 'dark');
  const [density, setDensity] = useState(document.body.dataset.density || 'compact');
  const [accent, setAccent] = useState(document.body.dataset.accent || 'indigo');

  /* Persist theme / density / accent to localStorage so the choice
     survives page reloads + role switches. Keys are scoped to the
     current user so different demo accounts can keep their own
     preference. */
  function persist(key, value) {
    try { localStorage.setItem(`aquaos.pref.${key}`, value); } catch (_) {}
  }
  function applyTheme(v)   { document.body.dataset.theme   = v; setTheme(v);   persist('theme', v); }
  function applyDensity(v) { document.body.dataset.density = v; setDensity(v); persist('density', v); }
  function applyAccent(v)  { document.body.dataset.accent  = v; setAccent(v);  persist('accent', v); }

  return (
    <div className="st-content">
      <header style={{ marginBottom: 24 }}>
        <h1 style={{
          fontFamily: 'var(--aq-ff-display)', fontSize: 26, fontWeight: 500,
          letterSpacing: '-0.012em', color: 'var(--aq-text)', margin: 0,
        }}>Settings</h1>
      </header>

      <div className="st-shell-grid" style={{ display: 'grid', gridTemplateColumns: '200px 1fr', gap: 32, alignItems: 'start' }}>
        <aside style={{ display: 'flex', flexDirection: 'column', gap: 2, position: 'sticky', top: 0 }}>
          {ST_TABS.map((t) => (
            <button
              key={t.id}
              onClick={() => {
                // Tabs marked `external: true` are navigation pivots,
                // not in-modal panels — they take the operator out of
                // Settings and into a full page (e.g. Team → /#users).
                if (t.external) {
                  if (t.id === 'team') {
                    window.location.hash = '#users';
                    return;
                  }
                }
                setTab(t.id);
              }}
              style={{
                textAlign: 'left', padding: '8px 12px',
                background: tab === t.id ? 'var(--aq-surface-2)' : 'transparent',
                border: 0, borderRadius: 6,
                color: tab === t.id ? 'var(--aq-text)' : 'var(--aq-text-dim)',
                fontFamily: 'inherit', fontSize: 13, cursor: 'pointer',
                display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8,
              }}
            >
              <span>{t.label}</span>
              {t.external && (
                <span aria-hidden="true" style={{ fontSize: 11, color: 'var(--aq-text-faint)' }}>↗</span>
              )}
            </button>
          ))}
        </aside>

        <div className="x-card" style={{ padding: 24 }}>
          {tab === 'profile' && (
            <>
              <h2 style={{
                margin: '0 0 16px', fontFamily: 'var(--aq-ff-display)',
                fontSize: 16, fontWeight: 500, color: 'var(--aq-text)',
              }}>Profile</h2>
              <div className="x-form-field">
                <div className="x-form-label">Display name<small>How you appear to teammates.</small></div>
                <div className="x-form-control"><input className="x-input" defaultValue={me.name || ''} /></div>
              </div>
              <div className="x-form-field">
                <div className="x-form-label">Email<small>Used to sign in.</small></div>
                <div className="x-form-control"><input className="x-input" defaultValue={me.email || ''} disabled /></div>
              </div>
              <div className="x-form-field">
                <div className="x-form-label">Role<small>Set by your organisation admin.</small></div>
                <div className="x-form-control">
                  <input className="x-input" defaultValue={me.role || 'viewer'} disabled style={{ textTransform: 'capitalize' }} />
                </div>
              </div>
            </>
          )}

          {tab === 'account' && (
            <>
              <h2 style={{
                margin: '0 0 16px', fontFamily: 'var(--aq-ff-display)',
                fontSize: 16, fontWeight: 500, color: 'var(--aq-text)',
              }}>Account</h2>
              <div className="x-form-field">
                <div className="x-form-label">Password<small>Last changed — never recorded.</small></div>
                <div className="x-form-control">
                  <button className="x-btn ghost">Change password</button>
                </div>
              </div>
              <div className="x-form-field">
                <div className="x-form-label">Two-factor authentication<small>Add a second factor to sign-in.</small></div>
                <div className="x-form-control">
                  <button className="x-btn ghost">Enable 2FA</button>
                </div>
              </div>
              <div className="x-form-field">
                <div className="x-form-label">Session<small>Active workspaces and devices.</small></div>
                <div className="x-form-control">
                  <div className="x-session-row">
                    <div className="x-session-icon"><Icon name="cpu" /></div>
                    <div>
                      <div className="x-session-name">This browser <span style={{
                        fontSize: 10, fontFamily: 'var(--aq-ff-mono)', color: 'var(--aq-success)',
                        background: 'color-mix(in srgb, var(--aq-success) 14%, transparent)',
                        padding: '1px 6px', borderRadius: 4, marginLeft: 6,
                      }}>CURRENT</span></div>
                      <div className="x-session-meta">Signed in just now · token expires 24h</div>
                    </div>
                    <button className="x-btn sm">Sign out</button>
                  </div>
                </div>
              </div>
            </>
          )}

          {tab === 'notifications' && (
            <>
              <h2 style={{
                margin: '0 0 16px', fontFamily: 'var(--aq-ff-display)',
                fontSize: 16, fontWeight: 500, color: 'var(--aq-text)',
              }}>Notifications</h2>
              <p style={{ fontSize: 12.5, color: 'var(--aq-text-faint)', margin: '0 0 12px' }}>
                Notification routes aren't wired yet — these toggles are illustrative.
              </p>
              {[
                ['Screen offline', 'When any display loses heartbeat for >15 min'],
                ['Pending review', 'When a campaign or species needs your sign-off'],
                ['Daily digest', 'Morning summary of fleet health and activity'],
                ['Conservation alerts', 'IUCN-sensitive species flagged by Triage Intel'],
              ].map(([label, desc]) => (
                <div key={label} className="x-form-field">
                  <div className="x-form-label">{label}<small>{desc}</small></div>
                  <div className="x-form-control">
                    <button className="x-btn ghost sm">Email + In-app</button>
                  </div>
                </div>
              ))}
            </>
          )}

          {tab === 'appearance' && (
            <>
              <h2 style={{
                margin: '0 0 16px', fontFamily: 'var(--aq-ff-display)',
                fontSize: 16, fontWeight: 500, color: 'var(--aq-text)',
              }}>Appearance</h2>
              <div className="x-form-field">
                <div className="x-form-label">Theme<small>Dark, light, or follow your OS.</small></div>
                <div className="x-form-control" style={{ flexDirection: 'row', gap: 6 }}>
                  {['dark', 'light', 'system'].map((v) => (
                    <button
                      key={v}
                      onClick={() => {
                        if (v === 'system') {
                          /* Apply current OS preference + remember the
                             choice so the listener in app.jsx auto-flips
                             on prefers-color-scheme changes. */
                          const wantsDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
                          document.body.dataset.theme = wantsDark ? 'dark' : 'light';
                          setTheme('system'); persist('theme', 'system');
                        } else {
                          applyTheme(v);
                        }
                      }}
                      className={(theme === v || (v === 'system' && (localStorage.getItem('aquaos.pref.theme') === 'system'))) ? 'x-btn' : 'x-btn ghost'}
                      style={{ textTransform: 'capitalize' }}
                    >{v}</button>
                  ))}
                </div>
              </div>
              <div className="x-form-field">
                <div className="x-form-label">Density<small>Tighter or roomier rows.</small></div>
                <div className="x-form-control" style={{ flexDirection: 'row', gap: 6 }}>
                  {['compact', 'comfortable'].map((v) => (
                    <button
                      key={v}
                      onClick={() => applyDensity(v)}
                      className={density === v ? 'x-btn' : 'x-btn ghost'}
                      style={{ textTransform: 'capitalize' }}
                    >{v}</button>
                  ))}
                </div>
              </div>
              <div className="x-form-field">
                <div className="x-form-label">Accent<small>Tints active states and highlights.</small></div>
                <div className="x-form-control" style={{ flexDirection: 'row', gap: 6 }}>
                  {['indigo', 'aqua', 'coral', 'pearl'].map((v) => (
                    <button
                      key={v}
                      onClick={() => applyAccent(v)}
                      className={accent === v ? 'x-btn' : 'x-btn ghost'}
                      style={{ textTransform: 'capitalize' }}
                    >{v}</button>
                  ))}
                </div>
              </div>
            </>
          )}

          {tab === 'feedback' && <ST_FeedbackPanel />}

          {tab === 'bulk' && window.BulkScreen && (
            /* Bulk Operations was a separate sidebar entry; moved here
               so the sidebar stays focused (bug 30480d6a). Negative
               margin pulls the inner screen flush to the card edges
               since BulkScreen renders its own padding. */
            <div style={{ margin: '-24px' }}>
              <window.BulkScreen />
            </div>
          )}

          {tab === 'audit' && window.AuditLogScreen && (
            /* Audit log moved here from the sidebar (bug 30480d6a). */
            <div style={{ margin: '-24px' }}>
              <window.AuditLogScreen />
            </div>
          )}

          {tab === 'billing' && Auth.canSeeBilling() && window.BillingScreen && (
            /* Embed the standalone BillingScreen here so org admins
               can manage subscription + invoices from inside Settings
               without a top-level nav entry. */
            <div style={{ margin: '-24px' }}>
              <window.BillingScreen />
            </div>
          )}

          {tab === 'danger' && (
            <>
              <h2 style={{
                margin: '0 0 16px', fontFamily: 'var(--aq-ff-display)',
                fontSize: 16, fontWeight: 500, color: 'var(--aq-danger)',
              }}>Danger zone</h2>
              <div className="x-form-field">
                <div className="x-form-label">Sign out everywhere<small>Invalidates all active tokens.</small></div>
                <div className="x-form-control">
                  <button
                    className="x-btn is-danger"
                    onClick={() => { Auth.clear(); window.location.reload(); }}
                  >Sign out</button>
                </div>
              </div>
              <div className="x-form-field">
                <div className="x-form-label">Delete account<small>Permanent. Requires admin.</small></div>
                <div className="x-form-control">
                  <button className="x-btn is-danger" disabled>Delete account</button>
                </div>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

window.SettingsScreen = SettingsScreen;
