// admin-security.jsx — Security & Activity tab for the admin dashboard.
//
// Goal: at a glance Joe can spot anything weird — a signup spike (bot
// attack), a flood of failed verifications, an admin action he didn't
// take. All queries hit the anon-key client and rely on `is_admin()`
// in RLS to gate access; nothing here uses the service-role key.

const SecKPICard = ({ label, value, sub, valueColor, tone }) => (
  <div style={{
    background: '#fff', borderRadius: 14, padding: '20px 22px',
    border: '1px solid ' + (tone === 'warn' ? 'oklch(78% 0.13 60)' : 'oklch(90% 0.01 265)'),
    boxShadow: '0 2px 10px oklch(18% 0.06 265 / 0.05)'
  }}>
    <div style={{ fontSize: 11, fontWeight: 700, color: 'oklch(55% 0.03 265)', letterSpacing: '0.07em', textTransform: 'uppercase', marginBottom: 10 }}>{label}</div>
    <div style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: 30, fontWeight: 700, color: valueColor || 'oklch(18% 0.03 265)', lineHeight: 1 }}>{value}</div>
    {sub && <div style={{ fontSize: 12, color: 'oklch(60% 0.03 265)', marginTop: 6 }}>{sub}</div>}
  </div>
);

const relTime = (iso) => {
  if (!iso) return '—';
  const d = new Date(iso).getTime();
  if (!Number.isFinite(d)) return '—';
  const diff = Date.now() - d;
  const m = Math.floor(diff / 60000);
  if (m < 1)  return 'just now';
  if (m < 60) return m + 'm ago';
  const h = Math.floor(m / 60);
  if (h < 24) return h + 'h ago';
  const dd = Math.floor(h / 24);
  if (dd < 30) return dd + 'd ago';
  return new Date(iso).toLocaleDateString();
};

const isoToday = () => new Date().toISOString().slice(0, 10);
const isoNDaysAgo = (n) => new Date(Date.now() - n * 86400000).toISOString();

const AdminSecurity = () => {
  const [state, setState] = React.useState({ loading: true, profiles: [], audit: [], verifications: [], err: null });

  const refresh = React.useCallback(async () => {
    setState(s => ({ ...s, loading: true, err: null }));
    try {
      // Recent profile rows (signups). RLS allows authenticated SELECT.
      const { data: profiles, error: pErr } = await window.supa
        .from('profiles')
        .select('id, full_name, role, created_at')
        .order('created_at', { ascending: false })
        .limit(50);
      if (pErr) throw pErr;

      // Audit log (admin actions). RLS: is_admin() only.
      const { data: audit, error: aErr } = await window.supa
        .from('audit_log')
        .select('id, admin_email, action, table_name, row_id, fields_accessed, details, created_at')
        .order('created_at', { ascending: false })
        .limit(50);
      // audit_log only exists if v26 has been applied; treat 404-style errors as empty
      const auditRows = aErr ? [] : (audit || []);

      // Verification status counts
      const { data: verRows, error: vErr } = await window.supa
        .from('instructor_verifications')
        .select('instructor_id, status, submitted_at, requested_at')
        .order('submitted_at', { ascending: false, nullsFirst: false })
        .limit(50);
      const verifications = vErr ? [] : (verRows || []);

      setState({ loading: false, profiles: profiles || [], audit: auditRows, verifications, err: null });
    } catch (e) {
      setState({ loading: false, profiles: [], audit: [], verifications: [], err: e.message || String(e) });
    }
  }, []);

  React.useEffect(() => { refresh(); }, [refresh]);

  if (state.loading) {
    return <div style={{ padding: 60, textAlign: 'center', color: 'oklch(55% 0.03 265)', fontSize: 14 }}>Loading security activity…</div>;
  }
  if (state.err) {
    return <div style={{ padding: 60, textAlign: 'center', color: 'oklch(50% 0.18 25)', fontSize: 14 }}>Couldn't load activity: {state.err}</div>;
  }

  // ── Derived metrics ───────────────────────────────────────────────
  const today = isoToday();
  const week  = isoNDaysAgo(7);

  const signupsToday = state.profiles.filter(p => (p.created_at || '').slice(0, 10) === today).length;
  const signups7d    = state.profiles.filter(p => p.created_at && p.created_at >= week).length;

  // Anomaly heuristic: more than 20 signups today is unusual for a
  // small private marketplace — flag it as a possible bot attack.
  const signupSpike = signupsToday >= 20;

  const pendingVerifications  = state.verifications.filter(v => v.status === 'submitted').length;
  const rejectedVerifications = state.verifications.filter(v => v.status === 'rejected').length;
  const adminActions7d        = state.audit.filter(e => e.created_at >= week).length;

  // ── Render ────────────────────────────────────────────────────────
  return (
    <div>
      {signupSpike && (
        <div style={{
          background: 'oklch(95% 0.06 60)', border: '1px solid oklch(75% 0.16 60)',
          borderRadius: 12, padding: '14px 18px', marginBottom: 22, color: 'oklch(35% 0.13 50)',
          fontSize: 13, fontWeight: 600
        }}>
          ⚠ {signupsToday} signups today — that's unusual. Check the list below for bot patterns
          (sequential emails, throwaway domains, identical names). If it's a real campaign, ignore.
        </div>
      )}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 14, marginBottom: 26 }}>
        <SecKPICard label="Signups today"      value={signupsToday}        tone={signupSpike ? 'warn' : ''} />
        <SecKPICard label="Signups (7 days)"   value={signups7d}           sub={state.profiles.length + ' total ever shown'} />
        <SecKPICard label="Pending verifications" value={pendingVerifications} sub={rejectedVerifications + ' rejected'} />
        <SecKPICard label="Admin actions (7d)" value={adminActions7d}      sub={state.audit.length + ' logged total'} />
        <SecKPICard label="Refresh"            value={
          <button onClick={refresh} style={{ background:'oklch(22% 0.06 265)', color:'#fff', border:'none', borderRadius:8, padding:'8px 14px', fontSize:13, fontWeight:600, cursor:'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>↻ Reload</button>
        } sub="data is cached until reload" />
      </div>

      {/* Two-column on wide, stacked on narrow */}
      <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(420px, 1fr))', gap: 22 }}>

        {/* Recent signups */}
        <div style={{ background:'#fff', borderRadius: 14, border: '1px solid oklch(90% 0.01 265)', overflow: 'hidden' }}>
          <div style={{ padding: '16px 20px', borderBottom:'1px solid oklch(94% 0.01 265)' }}>
            <h3 style={{ margin:0, fontSize: 14, fontWeight: 700, color: 'oklch(20% 0.04 265)' }}>Recent signups</h3>
            <div style={{ fontSize: 11, color:'oklch(58% 0.03 265)', marginTop: 4 }}>
              Newest first. Look for batches of identical names / sequential emails.
            </div>
          </div>
          <div style={{ maxHeight: 460, overflowY: 'auto' }}>
            {state.profiles.length === 0 && (
              <div style={{ padding:'28px 20px', textAlign:'center', color:'oklch(60% 0.03 265)', fontSize: 13 }}>No signups yet.</div>
            )}
            {state.profiles.slice(0, 30).map(p => (
              <div key={p.id} style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'10px 20px', borderBottom:'1px solid oklch(96% 0.005 265)' }}>
                <div style={{ minWidth: 0, flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color:'oklch(20% 0.04 265)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                    {p.full_name || '(no name)'}
                  </div>
                  <div style={{ fontSize: 11, color:'oklch(58% 0.03 265)', marginTop: 2 }}>
                    {p.role || 'unknown role'} · {relTime(p.created_at)}
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Recent audit log entries */}
        <div style={{ background:'#fff', borderRadius: 14, border: '1px solid oklch(90% 0.01 265)', overflow: 'hidden' }}>
          <div style={{ padding: '16px 20px', borderBottom:'1px solid oklch(94% 0.01 265)' }}>
            <h3 style={{ margin:0, fontSize: 14, fontWeight: 700, color: 'oklch(20% 0.04 265)' }}>Admin actions (audit log)</h3>
            <div style={{ fontSize: 11, color:'oklch(58% 0.03 265)', marginTop: 4 }}>
              Every sensitive admin RPC writes here. If you see an action you didn't take, your admin email may be compromised.
            </div>
          </div>
          <div style={{ maxHeight: 460, overflowY: 'auto' }}>
            {state.audit.length === 0 && (
              <div style={{ padding:'28px 20px', textAlign:'center', color:'oklch(60% 0.03 265)', fontSize: 13 }}>No audit entries yet — these get written when admin actions run (decrypt verification, approve instructor, etc.).</div>
            )}
            {state.audit.map(e => (
              <div key={e.id} style={{ padding:'10px 20px', borderBottom:'1px solid oklch(96% 0.005 265)' }}>
                <div style={{ display:'flex', alignItems:'baseline', justifyContent:'space-between', gap:8 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color:'oklch(20% 0.04 265)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                    {e.action} · <span style={{ color: 'oklch(50% 0.06 265)', fontWeight: 500 }}>{e.table_name}</span>
                  </div>
                  <div style={{ fontSize: 11, color:'oklch(58% 0.03 265)', flexShrink: 0 }}>{relTime(e.created_at)}</div>
                </div>
                <div style={{ fontSize: 11, color:'oklch(50% 0.03 265)', marginTop: 3, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                  {e.admin_email || '(unknown admin)'}
                  {Array.isArray(e.fields_accessed) && e.fields_accessed.length > 0 && (
                    <> · fields: {e.fields_accessed.join(', ')}</>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div style={{ marginTop: 24, padding: '14px 18px', background:'oklch(97% 0.005 60)', borderRadius: 10, border: '1px solid oklch(92% 0.01 265)', fontSize: 12, color: 'oklch(45% 0.04 265)' }}>
        <strong>What you can't see here (yet):</strong> failed login attempts, IP addresses, and rate-limit hits aren't persisted to the database — they live in Supabase Auth's internal logs and Vercel's function logs. Bookmark
        {' '}
        <a href="https://supabase.com/dashboard/project/nyxrawxarnobivzjdlxa/auth/audit-log" target="_blank" rel="noreferrer" style={{ color: 'oklch(45% 0.15 250)' }}>Supabase Auth → Audit Logs</a>
        {' '}and{' '}
        <a href="https://vercel.com/josephkhouryys-projects/website-claude/logs" target="_blank" rel="noreferrer" style={{ color: 'oklch(45% 0.15 250)' }}>Vercel Function Logs</a>
        {' '}for those.
      </div>
    </div>
  );
};

Object.assign(window, { AdminSecurity });
