/* ============================================
   ADMIN — DASHBOARD
   ============================================ */
function AdminDashboard({ onNavigate, onPlay }) {
  const [period, setPeriod] = React.useState('14d');
  const [, setTick] = React.useState(0);
  React.useEffect(() => {
    const h = () => setTick(t => t + 1);
    window.addEventListener('dataLoaded', h);
    return () => window.removeEventListener('dataLoaded', h);
  }, []);

  const analytics   = window.ANALYTICS  || ANALYTICS;
  const allTracks   = window.TRACKS     || TRACKS;
  const allComments = window.COMMENTS   || COMMENTS;
  const allUsers    = window.USERS      || USERS;

  // ── Period → slice of playsByDay ─────────────────────────
  const rawDays  = analytics.playsByDay || [];
  const nDays    = period === 'today' ? 1 : period === '7d' ? 7 : period === '14d' ? 14 : rawDays.length;
  const sparkDays = rawDays.length ? rawDays.slice(-Math.min(nDays, rawDays.length)) : [0];
  const prevDays  = rawDays.length && nDays < rawDays.length
    ? rawDays.slice(-Math.min(nDays * 2, rawDays.length), -nDays)
    : [];

  // ── Plays ────────────────────────────────────────────────
  const sum = arr => arr.reduce((a, b) => a + b, 0);
  const periodPlays = period === 'all'
    ? allTracks.reduce((s, t) => s + (t.plays || 0), 0)
    : sum(sparkDays);
  const prevPlays  = sum(prevDays);
  const playsDelta = prevPlays ? Math.round(((periodPlays - prevPlays) / prevPlays) * 100) : null;
  const fmtPlays = n => n >= 1e6 ? `${(n / 1e6).toFixed(2)}M` : n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n || 0);

  // ── Comments (real ISO timestamps) ───────────────────────
  const now = Date.now();
  const cutoffMs = { today: now - 86400000, '7d': now - 7*86400000, '14d': now - 14*86400000, '30d': now - 30*86400000, all: 0 }[period];
  const inPeriod = c => !c.flagged && (period === 'all' || new Date(c.timestamp || 0).getTime() >= cutoffMs);
  const inPrev   = c => !c.flagged && period !== 'all' &&
    new Date(c.timestamp || 0).getTime() >= (cutoffMs - (now - cutoffMs)) &&
    new Date(c.timestamp || 0).getTime() <  cutoffMs;
  const periodComments = allComments.filter(inPeriod);
  const prevComments   = allComments.filter(inPrev);
  const commentsDelta  = prevComments.length
    ? Math.round(((periodComments.length - prevComments.length) / prevComments.length) * 100)
    : null;

  // ── Users ────────────────────────────────────────────────
  const totalUsers = allUsers.length || analytics.totalUsers || 0;

  // ── Avg rating (live) ─────────────────────────────────────
  const ratedTracks = allTracks.filter(t => t.rating > 0);
  const avgRating = ratedTracks.length
    ? (ratedTracks.reduce((s, t) => s + t.rating, 0) / ratedTracks.length).toFixed(1)
    : (analytics.avgRating || '—');

  // ── Top tracks sorted by plays desc ──────────────────────
  const topTracks = [...allTracks].sort((a, b) => (b.plays || 0) - (a.plays || 0)).slice(0, 6);
  const maxPlays  = Math.max(topTracks[0]?.plays || 1, 1);
  const periodShortLabel = { today: '24h', '7d': '7d', '14d': '14d', '30d': '30d', all: 'all time' }[period];

  // ── Sparkline ─────────────────────────────────────────────
  const W = 600, H = 180;
  const maxV = Math.max(...sparkDays, 1);
  const minV = Math.min(...sparkDays);
  const rng  = maxV - minV || 1;
  const pts  = sparkDays.map((v, i) => [
    sparkDays.length > 1 ? (i / (sparkDays.length - 1)) * W : W / 2,
    H - ((v - minV) / rng) * H * 0.85 - 10,
  ]);
  const linePath = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x},${y}`).join(' ');
  const areaPath = `${linePath} L${W},${H} L0,${H} Z`;

  // ── X-axis date labels ────────────────────────────────────
  const dayLabel = daysAgo => {
    if (daysAgo === 0) return 'Today';
    const d = new Date(now - daysAgo * 86400000);
    return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
  };
  const xLabels = (() => {
    const n = sparkDays.length;
    if (n <= 1) return ['Today'];
    return [0, 1, 2, 3, 4].map(i => dayLabel(Math.round(((4 - i) / 4) * (n - 1))));
  })();

  const PERIODS = [
    { k: 'today', label: 'Today'   },
    { k: '7d',    label: '7 days'  },
    { k: '14d',   label: '14 days' },
    { k: '30d',   label: '30 days' },
    { k: 'all',   label: 'All time'},
  ];
  const periodLabel = { today: 'Today', '7d': 'Last 7 days', '14d': 'Last 14 days', '30d': 'Last 30 days', all: 'All time' }[period];

  const DeltaBadge = ({ delta, invert }) => {
    if (delta === null) return <div className="stat-delta" style={{ color: 'var(--fg-3)' }}>vs prev period</div>;
    const up = invert ? delta <= 0 : delta >= 0;
    return (
      <div className={`stat-delta ${up ? 'up' : 'dn'}`}>
        <Icon name="trend" size={11} style={!up ? { transform: 'scaleY(-1)' } : undefined} />
        {delta >= 0 ? '+' : ''}{delta}%
      </div>
    );
  };

  return (
    <div data-screen-label="08 Admin · Dashboard">
      <div className="admin-banner">
        <span className="dot"></span>
        <span><strong>Admin mode.</strong> You're viewing the moderation and analytics dashboard.</span>
        <span className="spacer"></span>
        <span className="kbd">A</span> <span className="fg-3" style={{ fontSize: 11 }}>Toggle admin</span>
      </div>

      <div className="section-head" style={{ marginBottom: 'var(--space-5)' }}>
        <div>
          <div className="eyebrow">{periodLabel}</div>
          <h1 className="h1" style={{ fontSize: 40, marginTop: 8 }}>Dashboard</h1>
        </div>
        <div className="row gap-2">
          {PERIODS.map(p => (
            <button key={p.k} className={`chip ${period === p.k ? 'active' : ''}`} onClick={() => setPeriod(p.k)}>
              {p.label}
            </button>
          ))}
        </div>
      </div>

      {/* Stats */}
      <div className="stat-grid">
        <div className="glass stat-card">
          <div className="stat-label">Plays</div>
          <div className="stat-value">{fmtPlays(periodPlays)}</div>
          <DeltaBadge delta={playsDelta} />
        </div>
        <div className="glass stat-card">
          <div className="stat-label">Total users</div>
          <div className="stat-value">{totalUsers >= 1000 ? `${(totalUsers / 1000).toFixed(1)}k` : totalUsers}</div>
          <div className="stat-delta" style={{ color: 'var(--fg-3)' }}>registered</div>
        </div>
        <div className="glass stat-card">
          <div className="stat-label">Comments</div>
          <div className="stat-value">{periodComments.length.toLocaleString()}</div>
          <DeltaBadge delta={commentsDelta} />
        </div>
        <div className="glass stat-card">
          <div className="stat-label">Avg rating</div>
          <div className="stat-value">{avgRating}</div>
          <div className="stat-delta" style={{ color: 'var(--fg-3)' }}>
            {ratedTracks.length} track{ratedTracks.length !== 1 ? 's' : ''} rated
          </div>
        </div>
      </div>

      {/* Chart + top tracks */}
      <div className="admin-chart-grid" style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr', gap: 'var(--space-5)', marginBottom: 'var(--space-5)' }}>
        <div className="glass chart-card">
          <div className="row" style={{ justifyContent: 'space-between' }}>
            <div>
              <div className="eyebrow">Plays · daily</div>
              <h3 className="h3" style={{ marginTop: 4 }}>Listening trend · {periodLabel.toLowerCase()}</h3>
            </div>
            <div className="row gap-3 mono" style={{ fontSize: 11 }}>
              <span className="row gap-1">
                <span style={{ width: 8, height: 8, borderRadius: 2, background: 'var(--accent)', display: 'inline-block' }}></span>
                plays
              </span>
            </div>
          </div>
          <div className="chart">
            <svg width="100%" height="100%" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
              <defs>
                <linearGradient id="chartFill" x1="0" x2="0" y1="0" y2="1">
                  <stop offset="0" stopColor="var(--accent)" stopOpacity="0.4"/>
                  <stop offset="1" stopColor="var(--accent)" stopOpacity="0"/>
                </linearGradient>
              </defs>
              {[0, 0.25, 0.5, 0.75, 1].map(y => (
                <line key={y} x1="0" x2={W} y1={y * H} y2={y * H} stroke="var(--line)" strokeDasharray="2 4" />
              ))}
              <path d={areaPath} fill="url(#chartFill)" />
              <path d={linePath} fill="none" stroke="var(--accent)" strokeWidth="2.5" strokeLinejoin="round" strokeLinecap="round" />
              {pts.map(([x, y], i) => (
                <circle key={i} cx={x} cy={y} r={i === pts.length - 1 ? 5 : 3} fill="var(--accent)" stroke="var(--bg-0)" strokeWidth="2" />
              ))}
            </svg>
          </div>
          <div className="row" style={{ justifyContent: 'space-between', marginTop: 8, fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--fg-3)' }}>
            {xLabels.map((l, i) => <span key={i}>{l}</span>)}
          </div>
        </div>

        <div className="glass" style={{ padding: 'var(--space-5)' }}>
          <div className="eyebrow">Top performers</div>
          <h3 className="h3" style={{ marginTop: 4, marginBottom: 16 }}>Top tracks · {periodShortLabel}</h3>
          <div className="col gap-3">
            {topTracks.length === 0 && (
              <div className="fg-3" style={{ fontSize: 12, textAlign: 'center', padding: '20px 0' }}>No track data yet</div>
            )}
            {topTracks.map((t, i) => (
              <div key={t.id} className="row gap-3" style={{ alignItems: 'center' }}>
                <div className="mono" style={{ fontSize: 16, fontWeight: 700, width: 18, color: 'var(--fg-2)' }}>{i + 1}</div>
                <button onClick={() => onPlay && onPlay(t)} style={{ width: 40, height: 40, borderRadius: 8, overflow: 'hidden', position: 'relative', flexShrink: 0, border: 'none', padding: 0, cursor: 'pointer' }}>
                  <Art index={t.art} />
                </button>
                <div className="col" style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.title}</div>
                  <div className="row gap-2 mono fg-2" style={{ fontSize: 10 }}>
                    <span>{(t.plays / 1000).toFixed(1)}k plays</span>
                    <span>· ★ {t.rating}</span>
                  </div>
                </div>
                <div style={{ width: 50 }}>
                  <div style={{ height: 4, background: 'var(--line)', borderRadius: 999, overflow: 'hidden' }}>
                    <div style={{ width: `${((t.plays || 0) / maxPlays) * 100}%`, height: '100%', background: 'linear-gradient(90deg, var(--accent), var(--accent-2))' }} />
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Quick links */}
      <div className="admin-ql-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 'var(--space-4)' }}>
        <button className="glass" style={{ padding: 'var(--space-5)', textAlign: 'left', cursor: 'pointer' }} onClick={() => onNavigate('admin-moderation')}>
          <div className="row gap-3" style={{ alignItems: 'flex-start' }}>
            <div style={{ width: 40, height: 40, borderRadius: 10, background: 'var(--accent-soft)', color: 'var(--accent)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
              <Icon name="flag" size={18} />
            </div>
            <div className="col">
              <div className="h4">Moderation queue</div>
              <div className="fg-2" style={{ fontSize: 12, marginTop: 2 }}>Review flagged comments & reports</div>
            </div>
            <div className="spacer"></div>
            {(() => {
              const n = (window.COMMENTS || []).filter(c => c.flagged || c.reported).length;
              return n > 0
                ? <span className="pill warn">{n} NEW</span>
                : <Icon name="arrow-right" size={14} />;
            })()}
          </div>
        </button>
        <button className="glass" style={{ padding: 'var(--space-5)', textAlign: 'left', cursor: 'pointer' }} onClick={() => onNavigate('admin-users')}>
          <div className="row gap-3" style={{ alignItems: 'flex-start' }}>
            <div style={{ width: 40, height: 40, borderRadius: 10, background: 'rgba(103, 232, 249, 0.12)', color: 'var(--accent-2)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
              <Icon name="users" size={18} />
            </div>
            <div className="col">
              <div className="h4">Manage users</div>
              <div className="fg-2" style={{ fontSize: 12, marginTop: 2 }}>Ban, suspend, view activity</div>
            </div>
            <div className="spacer"></div>
            <Icon name="arrow-right" size={14} />
          </div>
        </button>
        <button className="glass" style={{ padding: 'var(--space-5)', textAlign: 'left', cursor: 'pointer' }} onClick={() => onNavigate('admin-tracks')}>
          <div className="row gap-3" style={{ alignItems: 'flex-start' }}>
            <div style={{ width: 40, height: 40, borderRadius: 10, background: 'rgba(244, 114, 182, 0.12)', color: '#f472b6', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
              <Icon name="plus" size={18} />
            </div>
            <div className="col">
              <div className="h4">Upload tracks</div>
              <div className="fg-2" style={{ fontSize: 12, marginTop: 2 }}>Add new music, edit metadata, manage catalog</div>
            </div>
            <div className="spacer"></div>
            <Icon name="arrow-right" size={14} />
          </div>
        </button>
      </div>
    </div>
  );
}

/* ============================================
   ADMIN — MODERATION QUEUE
   ============================================ */
function AdminModeration() {
  const toast = useToast();
  const [items, setItems] = React.useState(() => (window.COMMENTS || COMMENTS).slice());
  const [filter, setFilter] = React.useState('flagged');

  // Stay in sync with live comment data
  React.useEffect(() => {
    const handler = () => setItems((window.COMMENTS || []).slice());
    window.addEventListener('dataLoaded', handler);
    return () => window.removeEventListener('dataLoaded', handler);
  }, []);

  const flaggedCount  = items.filter(c => c.flagged).length;
  const reportedCount = items.filter(c => c.reported).length;

  const visible = filter === 'flagged'
    ? items.filter(c => c.flagged)
    : filter === 'reports'
    ? items.filter(c => c.reported)
    : items.slice().sort((a, b) => (b.timestamp || b.when || '').localeCompare(a.timestamp || a.when || ''));

  const action = async (id, kind) => {
    const comment = items.find(c => c.id === id);
    if (!comment) return;

    if (kind === 'approve') {
      setItems(ix => ix.map(c => c.id === id ? { ...c, flagged: false, reported: false } : c));
      window.COMMENTS = (window.COMMENTS || []).map(c => c.id === id ? { ...c, flagged: false, reported: false } : c);
      try {
        if (window.firestoreDB && window.firestoreModule) {
          const { doc, updateDoc } = window.firestoreModule;
          await updateDoc(doc(window.firestoreDB, 'comments', id), { flagged: false, reported: false });
        }
        toast('Comment approved and unflagged ✓', 'success');
      } catch(e) { toast('Approved locally — sync failed', 'warn'); }

    } else if (kind === 'delete') {
      setItems(ix => ix.filter(c => c.id !== id));
      window.COMMENTS = (window.COMMENTS || []).filter(c => c.id !== id);
      try {
        if (window.firestoreDB && window.firestoreModule) {
          const { doc, deleteDoc } = window.firestoreModule;
          await deleteDoc(doc(window.firestoreDB, 'comments', id));
        }
        toast('Comment deleted ✓', 'success');
      } catch(e) { toast('Deleted locally — sync failed', 'warn'); }

    } else if (kind === 'ban') {
      setItems(ix => ix.filter(c => c.id !== id));
      window.COMMENTS = (window.COMMENTS || []).filter(c => c.id !== id);
      const matchedUser = (window.USERS || []).find(u => u.name === comment.user || u.email === comment.user);
      try {
        if (window.firestoreDB && window.firestoreModule) {
          const { doc, deleteDoc, updateDoc } = window.firestoreModule;
          await deleteDoc(doc(window.firestoreDB, 'comments', id));
          if (matchedUser?.id) {
            await updateDoc(doc(window.firestoreDB, 'users', matchedUser.id), { status: 'banned' });
            window.USERS = (window.USERS || []).map(u => u.id === matchedUser.id ? { ...u, status: 'banned' } : u);
          }
        }
        toast(`Comment removed · ${comment.user} banned ✓`, 'success');
      } catch(e) { toast('Banned locally — sync failed', 'warn'); }
    }
  };

  const EMPTY = {
    flagged: { icon: '✨', title: 'Queue clear', sub: 'Nothing to review. Good vibes only.' },
    reports:  { icon: '🙌', title: 'No reports',  sub: 'No user reports to review.' },
    recent:   { icon: '💬', title: 'No comments', sub: 'Comments will appear here once users start posting.' },
  };

  return (
    <div data-screen-label="09 Admin · Moderation">
      <div className="admin-banner">
        <span className="dot"></span>
        <span><strong>Admin · Moderation queue.</strong> Review flagged content from users and the auto-moderator.</span>
      </div>

      <div className="section-head" style={{ marginBottom: 'var(--space-5)' }}>
        <div>
          <div className="eyebrow">{visible.length} items</div>
          <h1 className="h1" style={{ fontSize: 40, marginTop: 8 }}>Moderation</h1>
        </div>
      </div>

      <div className="chip-row" style={{ marginBottom: 'var(--space-4)' }}>
        <button className={`chip ${filter === 'flagged' ? 'active' : ''}`} onClick={() => setFilter('flagged')}>
          <Icon name="flag" size={11} style={{ marginRight: 4, verticalAlign: 'middle' }} />
          Flagged · {flaggedCount}
        </button>
        <button className={`chip ${filter === 'recent' ? 'active' : ''}`} onClick={() => setFilter('recent')}>
          Recent · {items.length}
        </button>
        <button className={`chip ${filter === 'reports' ? 'active' : ''}`} onClick={() => setFilter('reports')}>
          User reports · {reportedCount}
        </button>
      </div>

      <div className="col gap-3">
        {visible.length === 0 && (
          <div className="glass" style={{ padding: 'var(--space-7)', textAlign: 'center' }}>
            <div style={{ fontSize: 32 }}>{EMPTY[filter].icon}</div>
            <div className="h3" style={{ marginTop: 12 }}>{EMPTY[filter].title}</div>
            <div className="fg-2" style={{ fontSize: 13, marginTop: 4 }}>{EMPTY[filter].sub}</div>
          </div>
        )}
        {visible.map(c => {
          const track = (window.TRACKS || TRACKS).find(t => t.id === c.trackId);
          return (
            <div key={c.id} className="glass" style={{ padding: 'var(--space-4)' }}>
              <div className="row gap-3" style={{ alignItems: 'flex-start' }}>
                <Avatar name={c.user} hue={c.hue} />
                <div className="col" style={{ flex: 1, minWidth: 0 }}>
                  <div className="row gap-2" style={{ alignItems: 'center', flexWrap: 'wrap' }}>
                    <strong style={{ fontSize: 14 }}>{c.user}</strong>
                    {c.flagged   && <span className="pill danger"><Icon name="flag" size={9} /> AUTO-FLAGGED</span>}
                    {c.reported  && <span className="pill warn"><Icon name="flag" size={9} /> REPORTED</span>}
                    {track && <><span className="fg-3 mono" style={{ fontSize: 11 }}>· on</span><span style={{ fontSize: 12, color: 'var(--accent)' }}>{track.title}</span></>}
                    {c.time && <span className="comment-timestamp">@ {c.time}</span>}
                    {c.when && <span className="fg-3" style={{ fontSize: 11 }}>· {c.when}</span>}
                  </div>
                  <div style={{
                    fontSize: 14, marginTop: 8, padding: 12,
                    background: c.flagged ? 'rgba(248,113,113,0.06)' : c.reported ? 'rgba(251,191,36,0.06)' : 'var(--bg-1)',
                    borderLeft: `3px solid ${c.flagged ? 'var(--danger)' : c.reported ? 'var(--warn)' : 'var(--line-strong)'}`,
                    borderRadius: '0 8px 8px 0', wordBreak: 'break-word',
                  }}>
                    "{c.text}"
                  </div>
                  {(c.flagged || c.reported) && (
                    <div className="row gap-2 mono fg-2" style={{ fontSize: 11, marginTop: 8 }}>
                      <Icon name="sparkles" size={11} />
                      <span>{c.flagReason || (c.flagged ? 'Auto-detected: spam / policy violation' : 'Reported by a user')}</span>
                    </div>
                  )}
                </div>
                <div className="col gap-2" style={{ minWidth: 120, flexShrink: 0 }}>
                  <button className="btn btn-glass btn-sm" onClick={() => action(c.id, 'approve')}>
                    <Icon name="check" size={12} /> Approve
                  </button>
                  <button className="btn btn-danger btn-sm" onClick={() => action(c.id, 'delete')}>
                    <Icon name="trash" size={12} /> Delete
                  </button>
                  <button className="btn btn-danger btn-sm" onClick={() => action(c.id, 'ban')}>
                    <Icon name="shield" size={12} /> Ban user
                  </button>
                </div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ============================================
   ADMIN — USERS
   ============================================ */
function AdminUsers({ user: currentUser }) {
  const toast = useToast();
  const [users, setUsers] = React.useState(() => (window.USERS || USERS).slice());
  const [filter, setFilter] = React.useState('all');
  const [search, setSearch] = React.useState('');

  // Refresh when Firestore data arrives
  React.useEffect(() => {
    const handler = () => setUsers((window.USERS || []).slice());
    window.addEventListener('dataLoaded', handler);
    return () => window.removeEventListener('dataLoaded', handler);
  }, []);

  const filtered = users.filter(u => {
    if (filter !== 'all' && u.status !== filter) return false;
    if (search && !u.name.toLowerCase().includes(search.toLowerCase()) && !(u.email || '').toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  });

  const setStatus = async (id, status, msg) => {
    setUsers(us => us.map(u => u.id === id ? { ...u, status } : u));
    window.USERS = (window.USERS || []).map(u => u.id === id ? { ...u, status } : u);
    try {
      await window.dbHelpers?.updateUser(id, { status });
      toast(msg, 'success');
    } catch(e) {
      toast('Updated locally — Firestore write failed', 'warn');
      console.error(e);
    }
  };

  const setRole = async (u, newRole) => {
    // Only full admin can change roles
    if (currentUser?.role !== 'admin') return;
    // Optimistic
    setUsers(us => us.map(x => x.id === u.id ? { ...x, role: newRole } : x));
    window.USERS = (window.USERS || []).map(x => x.id === u.id ? { ...x, role: newRole } : x);
    try {
      await window.dbHelpers?.setUserRole(u.email, u.name, newRole);
      toast(
        newRole === 'co-admin'
          ? `${u.name} promoted to Co-admin ✓`
          : `${u.name} demoted to User ✓`,
        'success'
      );
    } catch(e) {
      toast('Role updated locally — Firestore write failed', 'warn');
      console.error(e);
    }
  };

  const isFullAdmin = currentUser?.role === 'admin';

  return (
    <div data-screen-label="10 Admin · Users">
      <div className="admin-banner">
        <span className="dot"></span>
        <span><strong>Admin · Users.</strong> Manage accounts, view activity, ban or suspend users.</span>
        {isFullAdmin && (
          <span className="fg-3" style={{ fontSize: 11, marginLeft: 8 }}>
            · Full admin: can promote/demote roles
          </span>
        )}
      </div>

      <div className="section-head" style={{ marginBottom: 'var(--space-5)' }}>
        <div>
          <div className="eyebrow">{users.length} accounts</div>
          <h1 className="h1" style={{ fontSize: 40, marginTop: 8 }}>Users</h1>
        </div>
        <div className="row gap-2">
          <div className="search" style={{ maxWidth: 280 }}>
            <Icon name="search" size={14} />
            <input placeholder="Search name or email…" value={search} onChange={e => setSearch(e.target.value)} />
          </div>
        </div>
      </div>

      <div className="chip-row" style={{ marginBottom: 'var(--space-4)' }}>
        {[
          ['all', 'All', users.length],
          ['active', 'Active', users.filter(u => u.status === 'active').length],
          ['flagged', 'Flagged', users.filter(u => u.status === 'flagged').length],
          ['banned', 'Banned', users.filter(u => u.status === 'banned').length],
        ].map(([k, label, count]) => (
          <button key={k} className={`chip ${filter === k ? 'active' : ''}`} onClick={() => setFilter(k)}>
            {label} · {count}
          </button>
        ))}
      </div>

      <div className="glass" style={{ padding: 'var(--space-4)' }}>
        <div style={{ overflowX: 'auto' }}>
        <table className="table">
          <thead>
            <tr>
              <th>User</th>
              <th>Joined</th>
              <th>Plays</th>
              <th>Comments</th>
              <th>Status</th>
              <th style={{ textAlign: 'right' }}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 && (
              <tr>
                <td colSpan={6} style={{ textAlign: 'center', padding: 32, color: 'var(--fg-3)', fontSize: 13 }}>
                  No users yet — they'll appear here after signing in.
                </td>
              </tr>
            )}
            {filtered.map(u => (
              <tr key={u.id}>
                <td>
                  <div className="row gap-3">
                    <Avatar name={u.name} hue={u.hue} size="sm" />
                    <div className="col">
                      <div className="row gap-2" style={{ alignItems: 'center' }}>
                        <div style={{ fontWeight: 600, fontSize: 13 }}>{u.name}</div>
                        {u.role === 'co-admin' && (
                          <span className="pill" style={{ fontSize: 9, padding: '1px 6px', background: 'rgba(52,211,153,0.15)', color: '#34d399', borderColor: 'rgba(52,211,153,0.3)' }}>
                            CO-ADMIN
                          </span>
                        )}
                      </div>
                      <div className="fg-3 mono" style={{ fontSize: 11 }}>{u.email}</div>
                    </div>
                  </div>
                </td>
                <td className="mono fg-2" style={{ fontSize: 12 }}>{u.joined || '—'}</td>
                <td className="mono" style={{ fontSize: 13 }}>{(u.plays || 0).toLocaleString()}</td>
                <td className="mono" style={{ fontSize: 13 }}>{u.comments || 0}</td>
                <td>
                  <span className={`pill ${u.status === 'active' ? 'ok' : u.status === 'flagged' ? 'warn' : 'danger'}`}>
                    {u.status || 'active'}
                  </span>
                </td>
                <td>
                  <div className="row gap-1" style={{ justifyContent: 'flex-end' }}>
                    <button className="icon-btn" title="View"><Icon name="eye" size={14} /></button>
                    {/* Role toggle — full admin only */}
                    {isFullAdmin && u.role !== 'admin' && (
                      u.role === 'co-admin' ? (
                        <button
                          className="icon-btn"
                          style={{ color: '#34d399' }}
                          title="Demote to regular user"
                          onClick={() => setRole(u, 'user')}
                        >
                          <Icon name="shield" size={14} />
                        </button>
                      ) : (
                        <button
                          className="icon-btn"
                          style={{ color: 'var(--accent)' }}
                          title="Promote to Co-admin"
                          onClick={() => setRole(u, 'co-admin')}
                        >
                          <Icon name="sparkles" size={14} />
                        </button>
                      )
                    )}
                    {/* Suspend / reinstate — both admin and co-admin can do this */}
                    {u.status !== 'banned' && (
                      <button className="icon-btn" style={{ color: 'var(--warn)' }} title="Suspend" onClick={() => setStatus(u.id, 'flagged', `${u.name} suspended`)}>
                        <Icon name="flag" size={14} />
                      </button>
                    )}
                    {u.status !== 'banned' ? (
                      <button className="icon-btn" style={{ color: 'var(--danger)' }} title="Ban" onClick={() => setStatus(u.id, 'banned', `${u.name} banned`)}>
                        <Icon name="shield" size={14} />
                      </button>
                    ) : (
                      <button className="icon-btn" style={{ color: 'var(--ok)' }} title="Reinstate" onClick={() => setStatus(u.id, 'active', `${u.name} reinstated`)}>
                        <Icon name="check" size={14} />
                      </button>
                    )}
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </div>
    </div>
  );
}

/* ============================================
   ADMIN — TRACKS (upload + manage)
   ============================================ */
function AdminTracks({ user, onPlay }) {
  const toast = useToast();
  const [tracks, setTracks] = React.useState(() => (window.TRACKS || TRACKS).slice());
  const [saving, setSaving] = React.useState(false);
  const savingRef = React.useRef(false); // prevent onSnapshot from reverting mid-save

  // Refresh from Firestore when snapshot fires — but not while a save is in-flight
  React.useEffect(() => {
    const handler = () => {
      if (!savingRef.current) setTracks((window.TRACKS || []).slice());
    };
    window.addEventListener('dataLoaded', handler);
    return () => window.removeEventListener('dataLoaded', handler);
  }, []);
  const [form, setForm] = React.useState({
    title: '', album: '', duration: '', cardColor: 'violet',
    author: 'AI', humanName: '', spotify: '', apple: '', artworkUrl: '', audioUrl: '', lyrics: '',
  });
  const [editingId, setEditingId] = React.useState(null);
  const fileInputImg = React.useRef(null);
  const fileInputAudio = React.useRef(null);
  const [artworkFile, setArtworkFile] = React.useState(null);
  const [audioFile, setAudioFile] = React.useState(null);

  const update = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const reset = () => {
    setForm({ title: '', album: '', duration: '', cardColor: 'violet', author: 'AI', humanName: '', spotify: '', apple: '', artworkUrl: '', audioUrl: '', lyrics: '' });
    setArtworkFile(null); setAudioFile(null); setEditingId(null);
  };

  const submit = async () => {
    if (!form.title.trim()) { toast('Track title is required', 'info'); return; }
    savingRef.current = true;
    setSaving(true);
    const humanLabel = form.humanName.trim() || 'Sasha';
    const authorStr = form.author === 'AI' ? 'AI' : `${form.author} · ${humanLabel}`;
    let lyricsData = [];
    if (form.lyrics.trim()) {
      try { lyricsData = JSON.parse(form.lyrics); }
      catch(e) { toast('Lyrics JSON is invalid — check format', 'warn'); return; }
    }

    if (editingId) {
      const existing = tracks.find(t => t.id === editingId) || {};
      const updates = {
        title: form.title,
        duration: form.duration || existing.duration || '0:00',
        author: authorStr,
        artist: humanLabel,
        tag: form.author === 'AI' ? 'ai' : form.author === 'Human' ? 'human' : 'human+ai',
        ...(form.lyrics.trim() ? { lyrics: lyricsData } : {}),
      };
      // Update local component state immediately
      setTracks(ts => ts.map(t => t.id === editingId ? { ...t, ...updates } : t));
      // Update global TRACKS so other screens re-render with new data
      window.TRACKS = (window.TRACKS || []).map(t => t.id === editingId ? { ...t, ...updates } : t);
      window.dispatchEvent(new CustomEvent('dataLoaded'));
      // Persist to Firestore
      try {
        await window.dbHelpers?.updateTrack(editingId, updates);
        toast('Track updated ✓', 'success');
      } catch(e) {
        toast('Saved locally — Firestore write failed', 'warn');
        console.error(e);
      }

    } else {
      const newT = {
        id: 't' + Date.now(),
        title: form.title,
        artist: humanLabel,
        author: authorStr,
        tag: form.author === 'AI' ? 'ai' : form.author === 'Human' ? 'human' : 'human+ai',
        plays: 0, likes: 0, rating: 0, ratings: 0, comments: 0,
        duration: form.duration || '0:00',
        durationSec: 180,
        art: Math.floor(Math.random() * 8),
        releasedDays: 0,
        lyrics: lyricsData,
      };
      setTracks(ts => [newT, ...ts]);
      window.TRACKS = [newT, ...(window.TRACKS || [])];
      window.dispatchEvent(new CustomEvent('dataLoaded'));
      // Persist to Firestore (generates a real ID — used after next page load)
      try {
        await window.dbHelpers?.addTrack(newT);
        toast('Track added ✓', 'success');
      } catch(e) {
        toast('Saved locally — Firestore write failed', 'warn');
        console.error(e);
      }
      // Auto-notification: new track dropped
      window.dbHelpers?.sendNotification({
        title: '🎵 New track just dropped',
        message: `"${newT.title}" is now available — go check it out!`,
        type: 'new_track',
        sentBy: 'System',
      }).catch(() => {});
    }
    savingRef.current = false;
    setSaving(false);
    // Now let any pending snapshot refresh happen
    setTracks((window.TRACKS || []).slice());
    reset();
  };

  const edit = (t) => {
    setEditingId(t.id);
    const authorTag = t.tag === 'ai' ? 'AI' : t.tag === 'human' ? 'Human' : 'Human+AI';
    // Extract human name from stored author string e.g. "Human · Sasha" → "Sasha"
    const parts = (t.author || '').split(' · ');
    const humanName = parts.length >= 2 ? parts[parts.length - 1] : '';
    const lyricsStr = (t.lyrics && t.lyrics.length) ? JSON.stringify(t.lyrics, null, 2) : '';
    setForm(f => ({ ...f, title: t.title, duration: t.duration, author: authorTag, humanName, lyrics: lyricsStr }));
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };
  const remove = async (id) => {
    // Optimistic: remove from UI immediately
    setTracks(ts => ts.filter(t => t.id !== id));
    window.TRACKS = (window.TRACKS || []).filter(t => t.id !== id);
    window.dispatchEvent(new CustomEvent('dataLoaded'));
    // Persist to Firestore
    try {
      await window.dbHelpers?.deleteTrack(id);
      toast('Track removed ✓', 'success');
    } catch(e) {
      toast('Removed locally — Firestore delete failed', 'warn');
      console.error('deleteTrack error:', e);
    }
  };

  const handleFile = (e, kind) => {
    const f = e.target.files?.[0];
    if (!f) return;
    if (kind === 'img') setArtworkFile(f);
    else setAudioFile(f);
    toast(`${f.name} attached`, 'info');
  };

  const cardColors = ['violet', 'electric', 'heat', 'lime', 'mono', 'sunset', 'forest', 'midnight'];

  return (
    <div data-screen-label="11 Admin · Tracks">
      <div className="admin-banner">
        <span className="dot"></span>
        <span><strong>Admin · Tracks.</strong> Upload new tracks, edit metadata, manage the catalog.</span>
      </div>

      <div className="section-head" style={{ marginBottom: 'var(--space-5)' }}>
        <div>
          <div className="eyebrow">{tracks.length} tracks in catalog</div>
          <h1 className="h1" style={{ fontSize: 40, marginTop: 8 }}>Tracks</h1>
        </div>
      </div>

      {/* UPLOAD FORM */}
      <div className="glass" style={{ padding: 'var(--space-6)', marginBottom: 'var(--space-5)' }}>
        <div className="row" style={{ justifyContent: 'space-between', alignItems: 'center', marginBottom: 'var(--space-5)' }}>
          <div>
            <div className="eyebrow">{editingId ? 'Editing existing track' : 'New upload'}</div>
            <h2 className="h2 gradient-text" style={{ marginTop: 4, fontSize: 24 }}>
              {editingId ? 'Edit Track' : 'Add New Track'}
            </h2>
          </div>
          {editingId && (
            <button className="btn btn-glass btn-sm" onClick={reset}>
              <Icon name="x" size={12} /> Cancel edit
            </button>
          )}
        </div>

        <div className="admin-form-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-4)' }}>
          <div className="field">
            <label className="field-label">Track Title *</label>
            <input className="input" placeholder="e.g. Digital Dreams" value={form.title} onChange={e => update('title', e.target.value)} />
          </div>
          <div className="field">
            <label className="field-label">Album Name</label>
            <input className="input" placeholder="e.g. Neural Waves" value={form.album} onChange={e => update('album', e.target.value)} />
          </div>
          <div className="field">
            <label className="field-label">Duration</label>
            <input className="input" placeholder="e.g. 3:24" value={form.duration} onChange={e => update('duration', e.target.value)} />
          </div>
          <div className="field">
            <label className="field-label">Card Color</label>
            <div className="row gap-2" style={{ flexWrap: 'wrap' }}>
              {cardColors.map(c => (
                <button key={c} type="button"
                  className={`chip ${form.cardColor === c ? 'active' : ''}`}
                  onClick={() => update('cardColor', c)}
                  style={{ padding: '4px 12px', fontSize: 11 }}>
                  <span style={{
                    display: 'inline-block', width: 10, height: 10, borderRadius: '50%',
                    marginRight: 6, verticalAlign: 'middle',
                    background: ({
                      violet: 'linear-gradient(135deg,#a78bfa,#67e8f9)',
                      electric: 'linear-gradient(135deg,#22d3ee,#3b82f6)',
                      heat: 'linear-gradient(135deg,#f97316,#ec4899)',
                      lime: 'linear-gradient(135deg,#84cc16,#22d3ee)',
                      mono: 'linear-gradient(135deg,#f5f5f7,#a3a3a3)',
                      sunset: 'linear-gradient(135deg,#f59e0b,#dc2626)',
                      forest: 'linear-gradient(135deg,#10b981,#064e3b)',
                      midnight: 'linear-gradient(135deg,#1e1b4b,#0c0a09)',
                    })[c],
                  }}></span>
                  {c}
                </button>
              ))}
            </div>
          </div>
          <div className="field">
            <label className="field-label">Author</label>
            <select className="input" value={form.author} onChange={e => update('author', e.target.value)}>
              <option>AI</option>
              <option>Human</option>
              <option>Human+AI</option>
            </select>
          </div>
          <div className="field">
            <label className="field-label">
              Human Name
              {form.author === 'AI' && <span className="fg-3 mono" style={{ fontSize: 10, fontWeight: 400, marginLeft: 6 }}>— N/A for AI tracks</span>}
            </label>
            <input
              className="input"
              placeholder="e.g. Sasha"
              value={form.humanName}
              onChange={e => update('humanName', e.target.value)}
              disabled={form.author === 'AI'}
              style={form.author === 'AI' ? { opacity: 0.35, pointerEvents: 'none' } : {}}
            />
          </div>
          <div className="field">
            <label className="field-label">Spotify URL</label>
            <input className="input" placeholder="https://open.spotify.com/track/…" value={form.spotify} onChange={e => update('spotify', e.target.value)} />
          </div>
          <div className="field">
            <label className="field-label">Apple Music URL</label>
            <input className="input" placeholder="https://music.apple.com/…" value={form.apple} onChange={e => update('apple', e.target.value)} />
          </div>
          <div className="field" style={{ gridColumn: 'span 2' }}>
            <label className="field-label">
              Lyrics
              <span className="fg-3 mono" style={{ fontSize: 10, fontWeight: 400, marginLeft: 6 }}>— timestamped JSON · optional</span>
            </label>
            <textarea
              className="input"
              placeholder={'[{"t": 0, "text": "First line..."}, {"t": 4.5, "text": "Second line..."}]'}
              value={form.lyrics}
              onChange={e => update('lyrics', e.target.value)}
              rows={5}
              style={{ resize: 'vertical', fontFamily: 'var(--font-mono)', fontSize: 12, lineHeight: 1.6 }}
            />
          </div>
        </div>

        <div className="divider-line" />

        {/* Artwork */}
        <div className="admin-form-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-4)' }}>
          <div className="field">
            <label className="field-label">Artwork</label>
            <input className="input" placeholder="Paste image URL…" value={form.artworkUrl} onChange={e => update('artworkUrl', e.target.value)} />
            <div className="fg-3 mono" style={{ fontSize: 10, textAlign: 'center', margin: '4px 0', letterSpacing: '0.08em' }}>
              — OR UPLOAD A NEW FILE —
            </div>
            <input ref={fileInputImg} type="file" accept="image/*" style={{ display: 'none' }} onChange={e => handleFile(e, 'img')} />
            <button
              type="button"
              className="input"
              onClick={() => fileInputImg.current?.click()}
              style={{
                border: '1px dashed var(--line-strong)',
                background: 'transparent',
                cursor: 'pointer',
                color: artworkFile ? 'var(--fg-0)' : 'var(--fg-2)',
                textAlign: 'center',
              }}
            >
              {artworkFile ? `📎 ${artworkFile.name}` : '📷 Choose Image File'}
            </button>
          </div>

          {/* Audio */}
          <div className="field">
            <label className="field-label">Audio File</label>
            <input className="input" placeholder="Paste audio URL (mp3, wav, etc.)…" value={form.audioUrl} onChange={e => update('audioUrl', e.target.value)} />
            <div className="fg-3 mono" style={{ fontSize: 10, textAlign: 'center', margin: '4px 0', letterSpacing: '0.08em' }}>
              — OR UPLOAD A NEW FILE —
            </div>
            <input ref={fileInputAudio} type="file" accept="audio/*" style={{ display: 'none' }} onChange={e => handleFile(e, 'audio')} />
            <button
              type="button"
              className="input"
              onClick={() => fileInputAudio.current?.click()}
              style={{
                border: '1px dashed var(--line-strong)',
                background: 'transparent',
                cursor: 'pointer',
                color: audioFile ? 'var(--fg-0)' : 'var(--fg-2)',
                textAlign: 'center',
              }}
            >
              {audioFile ? `🎵 ${audioFile.name}` : '🎵 Choose Audio File'}
            </button>
          </div>
        </div>

        <div className="row gap-3" style={{ marginTop: 'var(--space-5)' }}>
          <button className="btn btn-primary btn-lg btn-block" onClick={submit} disabled={saving}>
            <Icon name="plus" size={16} /> {saving ? 'Saving…' : editingId ? 'Save changes' : 'Add Track'}
          </button>
        </div>
      </div>

      {/* MANAGE TRACKS */}
      <div className="glass" style={{ padding: 'var(--space-5)' }}>
        <div className="section-head" style={{ marginBottom: 'var(--space-4)' }}>
          <div>
            <div className="eyebrow">Catalog</div>
            <h3 className="h3" style={{ marginTop: 4 }}>Manage Tracks · {tracks.length}</h3>
          </div>
          <div className="row gap-2">
            <button className="chip active">All</button>
            <button className="chip">Published</button>
            <button className="chip">Drafts</button>
          </div>
        </div>

        <div className="col gap-2">
          {tracks.filter(t => t && t.id).map((t, i) => (
            <div key={t.id} className="admin-track-row row gap-3" style={{
              padding: '10px 14px',
              borderRadius: 14,
              border: '1px solid var(--glass-border)',
              alignItems: 'center',
            }}>
              <div className="mono fg-3 atr-num" style={{ width: 18, fontSize: 12 }}>{String(i + 1).padStart(2, '0')}</div>
              <button className="atr-art" onClick={() => onPlay && onPlay(t)} style={{ width: 44, height: 44, borderRadius: 10, overflow: 'hidden', position: 'relative', flexShrink: 0, border: 'none', padding: 0, cursor: 'pointer' }}>
                <Art index={t.art} />
              </button>
              <div className="col" style={{ flex: 1, minWidth: 0 }}>
                <div className="row gap-2" style={{ alignItems: 'center', flexWrap: 'wrap' }}>
                  <strong style={{ fontSize: 14 }}>{t.title}</strong>
                  <span className={`track-tag ${t.tag === 'ai' ? 'ai' : (t.tag === 'human' ? 'human' : '')}`}>{t.tag}</span>
                </div>
                <div className="fg-2 mono atr-meta" style={{ fontSize: 11, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {t.artist} · {t.duration} · {t.author}
                </div>
              </div>
              <div className="col atr-plays" style={{ textAlign: 'right', minWidth: 80 }}>
                <div className="mono" style={{ fontSize: 13, fontWeight: 600 }}>{(t.plays / 1000).toFixed(1)}k</div>
                <div className="fg-3 mono" style={{ fontSize: 10 }}>PLAYS</div>
              </div>
              <div className="row gap-2" style={{ flexShrink: 0 }}>
                <button className="icon-btn" title="Play" onClick={() => onPlay && onPlay(t)}>
                  <Icon name="play" size={14} />
                </button>
                <button className="btn btn-glass btn-sm" onClick={() => edit(t)}>
                  <Icon name="edit" size={12} /> Edit
                </button>
                {user?.role !== 'co-admin' && (
                  <button className="btn btn-danger btn-sm" onClick={() => remove(t.id)}>
                    <Icon name="trash" size={12} /> Remove
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ============================================
   ADMIN — NOTIFICATIONS
   ============================================ */
function AdminNotifications({ onNotifSent }) {
  const toast = useToast();
  const [notifs, setNotifs] = React.useState(() => (window.NOTIFICATIONS || []).slice());
  const [form, setForm] = React.useState({ title: '', message: '' });
  const [sending, setSending] = React.useState(false);

  // Keep in sync when app-level notifications update (e.g. auto-notifs from other screens)
  React.useEffect(() => {
    const handler = (e) => {
      setNotifs(ns => {
        const exists = ns.some(n => n.id === e.detail.id);
        return exists ? ns : [e.detail, ...ns];
      });
    };
    window.addEventListener('notificationSent', handler);
    return () => window.removeEventListener('notificationSent', handler);
  }, []);

  const send = async () => {
    if (!form.message.trim()) { toast('Message is required', 'info'); return; }
    setSending(true);
    try {
      const notif = await window.dbHelpers.sendNotification({
        title: form.title.trim() || 'Announcement',
        message: form.message.trim(),
        type: 'broadcast',
        sentBy: 'Admin',
      });
      setNotifs(ns => [notif, ...ns]);
      setForm({ title: '', message: '' });
      if (onNotifSent) onNotifSent(notif);
      toast('Notification sent to all users ✓', 'success');
    } catch (e) {
      toast('Failed to send: ' + e.message, 'warn');
    }
    setSending(false);
  };

  const TYPE_META = {
    broadcast: { label: 'Broadcast', cls: 'ok' },
    new_track:  { label: 'New track', cls: '' },
    system:     { label: 'System', cls: 'warn' },
  };

  const fmtTs = (ts) => {
    try {
      return new Date(ts).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
    } catch { return ts || ''; }
  };

  return (
    <div data-screen-label="12 Admin · Notifications">
      <div className="admin-banner">
        <span className="dot"></span>
        <span><strong>Admin · Notifications.</strong> Broadcast messages and view auto-generated alerts.</span>
      </div>

      <div className="section-head" style={{ marginBottom: 'var(--space-5)' }}>
        <div>
          <div className="eyebrow">Broadcast center</div>
          <h1 className="h1" style={{ fontSize: 40, marginTop: 8 }}>Notifications</h1>
        </div>
        <div className="row gap-2">
          <span className="pill ok">{notifs.filter(n => n.type === 'broadcast').length} manual</span>
          <span className="pill">{notifs.filter(n => n.type === 'new_track').length} auto</span>
        </div>
      </div>

      {/* Compose */}
      <div className="glass" style={{ padding: 'var(--space-6)', marginBottom: 'var(--space-5)' }}>
        <div className="eyebrow" style={{ marginBottom: 6 }}>New broadcast</div>
        <h2 className="h2" style={{ fontSize: 20, marginBottom: 'var(--space-4)' }}>Send to all users</h2>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-4)' }}>
          <div className="field">
            <label className="field-label">Title <span className="fg-3 mono" style={{ fontSize: 10, fontWeight: 400 }}>— optional</span></label>
            <input className="input" placeholder="e.g. New track just dropped!" value={form.title} onChange={e => setForm(f => ({ ...f, title: e.target.value }))} />
          </div>
          <div style={{ display: 'flex', alignItems: 'flex-end' }}>
            <button className="btn btn-primary btn-block" onClick={send} disabled={sending}>
              <Icon name="bell" size={14} /> {sending ? 'Sending…' : 'Send to all users'}
            </button>
          </div>
          <div className="field" style={{ gridColumn: 'span 2' }}>
            <label className="field-label">Message *</label>
            <textarea
              className="input"
              placeholder="Write your message to all users…"
              value={form.message}
              onChange={e => setForm(f => ({ ...f, message: e.target.value }))}
              rows={3}
              style={{ resize: 'vertical' }}
            />
          </div>
        </div>
      </div>

      {/* History */}
      <div className="glass" style={{ padding: 'var(--space-5)' }}>
        <div className="section-head" style={{ marginBottom: 'var(--space-4)' }}>
          <div>
            <div className="eyebrow">History · {notifs.length}</div>
            <h3 className="h3" style={{ marginTop: 4 }}>All notifications</h3>
          </div>
        </div>
        {notifs.length === 0 && (
          <div style={{ textAlign: 'center', padding: 'var(--space-7)', color: 'var(--fg-3)', fontSize: 13 }}>
            No notifications sent yet.
          </div>
        )}
        <div className="col gap-2">
          {notifs.map((n, i) => {
            const meta = TYPE_META[n.type] || TYPE_META.broadcast;
            return (
              <div key={n.id || i} style={{ padding: '12px 16px', borderRadius: 12, background: 'var(--bg-1)', border: '1px solid var(--glass-border)' }}>
                <div className="row gap-2" style={{ alignItems: 'center', marginBottom: 4 }}>
                  <Icon name="bell" size={11} style={{ color: 'var(--accent)', flexShrink: 0 }} />
                  <strong style={{ fontSize: 13 }}>{n.title || 'Announcement'}</strong>
                  <span className={`pill ${meta.cls}`} style={{ fontSize: 9, padding: '1px 6px' }}>{meta.label}</span>
                  <span className="spacer" />
                  <span className="fg-3 mono" style={{ fontSize: 10 }}>{fmtTs(n.timestamp)}</span>
                </div>
                <div style={{ fontSize: 12, color: 'var(--fg-2)', paddingLeft: 19 }}>{n.message}</div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AdminDashboard, AdminModeration, AdminUsers, AdminTracks, AdminNotifications });
