const { useState: useStateU, useEffect: useEffectU, useCallback: useCallbackU } = React;

function fmtRelU(ts) {
  if (!ts) return '—';
  const diff = Date.now() - new Date(ts).getTime();
  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 d = Math.floor(h / 24);
  if (d < 30) return `${d}d ago`;
  return `${Math.floor(d / 30)}mo ago`;
}

function fmtDateU(ts) {
  if (!ts) return '—';
  return new Date(ts).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
}

// ── Tiny sparkline using SVG ──────────────────────────────────────────────────
function Sparkline({ data, color = 'var(--accent)', height = 32 }) {
  if (!data || data.length < 2) return <div style={{ height }} />;
  const max = Math.max(...data, 1);
  const w = 120, h = height;
  const pts = data.map((v, i) => {
    const x = (i / (data.length - 1)) * w;
    const y = h - (v / max) * (h - 4) - 2;
    return `${x},${y}`;
  }).join(' ');
  return (
    <svg width={w} height={h} style={{ display: 'block' }}>
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  );
}

// ── Data fetchers ─────────────────────────────────────────────────────────────
async function fetchUserStats(sb) {
  const now = Date.now();
  const t5m  = new Date(now - 5 * 60000).toISOString();
  const t1h  = new Date(now - 3600000).toISOString();
  const t24h = new Date(now - 86400000).toISOString();
  const t7d  = new Date(now - 7 * 86400000).toISOString();
  const t30d = new Date(now - 30 * 86400000).toISOString();

  const [allUsers, devices, sessions7d, signups30d, dau30d] = await Promise.all([
    // All non-deleted profiles for bucketing
    sb.from('user_profiles')
      .select('id, role, created_at, last_active, onboarding_completed')
      .is('deleted_at', null)
      .limit(2000),

    // iOS vs Android
    sb.from('user_device_fingerprints')
      .select('platform')
      .then(({ data }) => {
        const ios = (data || []).filter(d => d.platform === 'ios').length;
        const android = (data || []).filter(d => d.platform === 'android').length;
        return { ios, android };
      }),

    // Sessions last 7d
    sb.from('user_sessions')
      .select('user_id, started_at', { count: 'exact' })
      .gte('started_at', new Date(Date.now() - 7 * 86400000).toISOString()),

    // Signups per day last 30d
    sb.from('user_profiles')
      .select('created_at')
      .gte('created_at', new Date(Date.now() - 30 * 86400000).toISOString())
      .order('created_at'),

    // DAU per day last 30d
    sb.from('user_sessions')
      .select('user_id, started_at')
      .gte('started_at', new Date(Date.now() - 30 * 86400000).toISOString())
      .order('started_at'),
  ]);

  const all = allUsers.data || [];

  // Activity buckets
  const bucket = (from, to) => all.filter(u => {
    if (!u.last_active) return false;
    const ts = new Date(u.last_active).getTime();
    return ts >= new Date(from).getTime() && (!to || ts < new Date(to).getTime());
  }).length;

  // Build 30-day signup + DAU sparklines
  const signupByDay = {};
  (signups30d.data || []).forEach(r => {
    const d = r.created_at.slice(0, 10);
    signupByDay[d] = (signupByDay[d] || 0) + 1;
  });
  const dauUsers = {};
  (dau30d.data || []).forEach(r => {
    const d = r.started_at.slice(0, 10);
    if (!dauUsers[d]) dauUsers[d] = new Set();
    dauUsers[d].add(r.user_id);
  });

  const last30days = Array.from({ length: 30 }, (_, i) => {
    const d = new Date(Date.now() - (29 - i) * 86400000).toISOString().slice(0, 10);
    return { date: d, signups: signupByDay[d] || 0, dau: dauUsers[d]?.size || 0 };
  });

  return {
    total:      all.length,
    onlineNow:  bucket(t5m, null),
    lastHour:   bucket(t1h, t5m),
    last24h:    bucket(t24h, t1h),
    last7d:     bucket(t7d, t24h),
    last30d:    bucket(t30d, t7d),
    dormant:    all.filter(u => !u.last_active || new Date(u.last_active).getTime() < new Date(t30d).getTime()).length,
    signups24h: all.filter(u => new Date(u.created_at).getTime() >= new Date(t24h).getTime()).length,
    signups7d:  all.filter(u => new Date(u.created_at).getTime() >= new Date(t7d).getTime()).length,
    onboarded:  all.filter(u => u.onboarding_completed).length,
    buyers:     all.filter(u => u.role === 'buyer').length,
    sellers:    all.filter(u => u.role === 'seller').length,
    delivery:   all.filter(u => u.role === 'delivery').length,
    ios:        devices.ios,
    android:    devices.android,
    sessions7d: sessions7d.count || 0,
    last30days,
  };
}

async function fetchUserList(sb, activityFilter, roleFilter, search) {
  let q = sb
    .from('user_profiles')
    .select('id, username, display_name, email, role, created_at, last_active, onboarding_completed, account_status, verification_level')
    .is('deleted_at', null)
    .order('last_active', { ascending: false, nullsFirst: false })
    .limit(150);

  if (roleFilter !== 'all') q = q.eq('role', roleFilter);

  const now = Date.now();
  if (activityFilter === 'online')   q = q.gte('last_active', new Date(now - 5 * 60000).toISOString());
  if (activityFilter === 'today')    q = q.gte('last_active', new Date(now - 24 * 3600000).toISOString());
  if (activityFilter === 'week')     q = q.gte('last_active', new Date(now - 7 * 86400000).toISOString());
  if (activityFilter === 'dormant')  q = q.or('last_active.is.null,last_active.lte.' + new Date(now - 30 * 86400000).toISOString());

  const { data: users } = await q;
  if (!users?.length) return [];

  // Join device info
  const ids = users.map(u => u.id);
  const { data: devices } = await sb
    .from('user_device_fingerprints')
    .select('user_id, platform, ip_address, inferred_city, inferred_region, device_name')
    .in('user_id', ids)
    .order('last_seen', { ascending: false });

  const dm = {};
  (devices || []).forEach(d => { if (!dm[d.user_id]) dm[d.user_id] = d; });

  let results = users.map(u => ({ ...u, device: dm[u.id] || null }));

  if (search) {
    const q2 = search.toLowerCase();
    results = results.filter(u =>
      u.username?.toLowerCase().includes(q2) ||
      u.display_name?.toLowerCase().includes(q2) ||
      u.email?.toLowerCase().includes(q2) ||
      u.device?.ip_address?.includes(q2) ||
      u.device?.inferred_city?.toLowerCase().includes(q2)
    );
  }

  return results;
}

// ── Activity dot ──────────────────────────────────────────────────────────────
function ActivityDot({ lastActive }) {
  if (!lastActive) return <span style={{ color: 'var(--ink-4)', fontSize: 11 }}>Never</span>;
  const diff = Date.now() - new Date(lastActive).getTime();
  const color = diff < 5 * 60000 ? 'var(--pos)' : diff < 3600000 ? 'var(--warn)' : 'var(--ink-4)';
  return (
    <span className="row" style={{ gap: 5 }}>
      <span style={{ width: 7, height: 7, borderRadius: '50%', background: color, flexShrink: 0, display: 'inline-block' }} />
      <span style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>{fmtRelU(lastActive)}</span>
    </span>
  );
}

// ── Mini bar chart for 30-day trend ──────────────────────────────────────────
function MiniBarChart({ data, valueKey, color }) {
  const max = Math.max(...data.map(d => d[valueKey]), 1);
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 2, height: 40 }}>
      {data.map((d, i) => (
        <div
          key={i}
          title={`${d.date}: ${d[valueKey]}`}
          style={{
            flex: 1, minWidth: 2,
            height: `${Math.max(2, (d[valueKey] / max) * 100)}%`,
            background: color,
            borderRadius: 1,
            opacity: d[valueKey] === 0 ? 0.15 : 0.85,
          }}
        />
      ))}
    </div>
  );
}

// ── Main page ─────────────────────────────────────────────────────────────────
window.UsersPage = function UsersPage() {
  const sb = window.supabaseClient;
  const [stats, setStats] = useStateU(null);
  const [users, setUsers] = useStateU([]);
  const [loadingStats, setLoadingStats] = useStateU(true);
  const [loadingUsers, setLoadingUsers] = useStateU(true);
  const [activityFilter, setActivityFilter] = useStateU('all');
  const [roleFilter, setRoleFilter] = useStateU('all');
  const [search, setSearch] = useStateU('');

  const loadStats = useCallbackU(async () => {
    setLoadingStats(true);
    const s = await fetchUserStats(sb);
    setStats(s);
    setLoadingStats(false);
  }, []);

  const loadUsers = useCallbackU(async () => {
    setLoadingUsers(true);
    const u = await fetchUserList(sb, activityFilter, roleFilter, search);
    setUsers(u);
    setLoadingUsers(false);
  }, [activityFilter, roleFilter, search]);

  useEffectU(() => { loadStats(); }, []);
  useEffectU(() => { loadUsers(); }, [activityFilter, roleFilter]);

  // Debounce search
  useEffectU(() => {
    const t = setTimeout(() => loadUsers(), 300);
    return () => clearTimeout(t);
  }, [search]);

  const onboardRate = stats ? Math.round((stats.onboarded / Math.max(stats.total, 1)) * 100) : 0;

  return (
    <div className="page">
      <div className="page-h">
        <div>
          <h1>Users</h1>
          <div className="ts"><span className="live">live</span> · user_profiles · user_sessions · user_device_fingerprints</div>
        </div>
        <div className="acts">
          <button className="btn" onClick={() => { loadStats(); loadUsers(); }}>↺ Refresh</button>
        </div>
      </div>

      {/* ── KPI row ── */}
      <div className="kpi-grid" style={{ gridTemplateColumns: 'repeat(5,1fr)', marginBottom: 16 }}>
        <div className="kpi">
          <div className="lbl">Total Users</div>
          <div className="val">{loadingStats ? '—' : stats?.total}</div>
          <div className="sub">
            <span>{stats?.buyers ?? '—'} buyers</span>
            <span>·</span>
            <span>{stats?.sellers ?? '—'} sellers</span>
          </div>
        </div>
        <div className="kpi">
          <div className="lbl">Online Now</div>
          <div className="val" style={{ color: stats?.onlineNow > 0 ? 'var(--pos)' : 'var(--ink-3)' }}>
            {loadingStats ? '—' : stats?.onlineNow}
          </div>
          <div className="sub">{stats?.lastHour ?? '—'} in last hour</div>
        </div>
        <div className="kpi">
          <div className="lbl">Active (24h / 7d)</div>
          <div className="val">{loadingStats ? '—' : stats?.last24h}</div>
          <div className="sub">{stats?.last7d ?? '—'} past 7 days</div>
        </div>
        <div className="kpi">
          <div className="lbl">New Signups</div>
          <div className="val">{loadingStats ? '—' : stats?.signups24h}</div>
          <div className="sub">{stats?.signups7d ?? '—'} this week</div>
        </div>
        <div className="kpi">
          <div className="lbl">Onboarded</div>
          <div className="val">{loadingStats ? '—' : `${onboardRate}%`}</div>
          <div className="sub">{stats?.onboarded ?? '—'} of {stats?.total ?? '—'} users</div>
        </div>
      </div>

      {/* ── Charts row ── */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12, marginBottom: 16 }}>

        {/* Signups 30d */}
        <div className="panel" style={{ padding: '14px 16px' }}>
          <div style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>
            Signups — last 30 days
          </div>
          {stats ? <MiniBarChart data={stats.last30days} valueKey="signups" color="var(--accent)" /> : <div style={{ height: 40 }} />}
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)', marginTop: 4 }}>
            <span>{stats?.last30days?.[0]?.date?.slice(5)}</span>
            <span>today</span>
          </div>
        </div>

        {/* DAU 30d */}
        <div className="panel" style={{ padding: '14px 16px' }}>
          <div style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>
            DAU — last 30 days
          </div>
          {stats ? <MiniBarChart data={stats.last30days} valueKey="dau" color="var(--info)" /> : <div style={{ height: 40 }} />}
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)', marginTop: 4 }}>
            <span>{stats?.last30days?.[0]?.date?.slice(5)}</span>
            <span>today</span>
          </div>
        </div>

        {/* Activity buckets + platform split */}
        <div className="panel" style={{ padding: '14px 16px' }}>
          <div style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 10 }}>
            Activity & Platform
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
            {[
              { label: 'Online now',   val: stats?.onlineNow, color: 'var(--pos)' },
              { label: 'Last 24h',     val: stats?.last24h,   color: 'var(--accent)' },
              { label: 'Last 7 days',  val: stats?.last7d,    color: 'var(--info)' },
              { label: 'Last 30 days', val: stats?.last30d,   color: 'var(--warn)' },
              { label: 'Dormant',      val: stats?.dormant,   color: 'var(--ink-4)' },
            ].map(row => (
              <div key={row.label} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <span style={{ width: 7, height: 7, borderRadius: '50%', background: row.color, flexShrink: 0 }} />
                <span style={{ flex: 1, fontSize: 12, color: 'var(--ink-2)' }}>{row.label}</span>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--ink)' }}>{row.val ?? '—'}</span>
              </div>
            ))}
            <div style={{ height: 1, background: 'var(--hairline)', margin: '4px 0' }} />
            <div style={{ display: 'flex', gap: 12 }}>
              <span style={{ fontSize: 12, color: 'var(--ink-2)' }}>
                📱 iOS <strong>{stats?.ios ?? '—'}</strong>
              </span>
              <span style={{ fontSize: 12, color: 'var(--ink-2)' }}>
                🤖 Android <strong>{stats?.android ?? '—'}</strong>
              </span>
            </div>
          </div>
        </div>
      </div>

      {/* ── User list ── */}
      <div className="panel">
        <div style={{ display: 'flex', alignItems: 'center', borderBottom: '1px solid var(--hairline)' }}>
          <div className="ftabs" style={{ borderBottom: 'none', flex: 1 }}>
            {[
              { id: 'all',     label: 'All' },
              { id: 'online',  label: 'Online' },
              { id: 'today',   label: 'Today' },
              { id: 'week',    label: 'This Week' },
              { id: 'dormant', label: 'Dormant' },
            ].map(f => (
              <div key={f.id} className={`ftab${activityFilter === f.id ? ' active' : ''}`} onClick={() => setActivityFilter(f.id)}>
                {f.label}
                {f.id === 'online' && stats?.onlineNow > 0 && (
                  <span className="ct" style={{ background: 'var(--pos-soft)', color: 'var(--pos)' }}>{stats.onlineNow}</span>
                )}
              </div>
            ))}
          </div>
          <div style={{ display: 'flex', gap: 8, padding: '0 12px' }}>
            <select
              value={roleFilter}
              onChange={e => setRoleFilter(e.target.value)}
              style={{
                height: 26, padding: '0 8px', fontSize: 12,
                border: '1px solid var(--hairline)', borderRadius: 4,
                background: 'var(--surface-2)', color: 'var(--ink)',
                outline: 'none', fontFamily: 'var(--font-sans)',
              }}
            >
              <option value="all">All roles</option>
              <option value="buyer">Buyers</option>
              <option value="seller">Sellers</option>
              <option value="delivery">Delivery</option>
            </select>
            <input
              placeholder="Search name, email, IP, city…"
              value={search}
              onChange={e => setSearch(e.target.value)}
              style={{
                height: 26, padding: '0 10px', fontSize: 12,
                border: '1px solid var(--hairline)', borderRadius: 4,
                background: 'var(--surface-2)', color: 'var(--ink)',
                outline: 'none', width: 220, fontFamily: 'var(--font-sans)',
              }}
            />
          </div>
        </div>

        <div className="t-wrap">
          <table className="t">
            <thead>
              <tr>
                <th>User</th>
                <th>Role</th>
                <th>Last Active</th>
                <th>Signed Up</th>
                <th>Onboarded</th>
                <th>Platform</th>
                <th>IP / Location</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
              {loadingUsers && (
                <tr><td colSpan={8} style={{ textAlign: 'center', color: 'var(--ink-3)', padding: '28px 0' }}>Loading…</td></tr>
              )}
              {!loadingUsers && users.length === 0 && (
                <tr><td colSpan={8} style={{ textAlign: 'center', color: 'var(--ink-3)', padding: '28px 0' }}>No users found</td></tr>
              )}
              {!loadingUsers && users.map(u => (
                <tr key={u.id}>
                  <td>
                    <div className="col" style={{ gap: 1 }}>
                      <span style={{ color: 'var(--ink)', fontWeight: 500 }}>{u.display_name || u.username || '—'}</span>
                      <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{u.email || `@${u.username}`}</span>
                    </div>
                  </td>
                  <td>
                    <span className={`chip ${u.role === 'seller' ? 'accent' : u.role === 'delivery' ? 'info' : ''}`}>
                      {u.role}
                    </span>
                  </td>
                  <td><ActivityDot lastActive={u.last_active} /></td>
                  <td><span style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>{fmtDateU(u.created_at)}</span></td>
                  <td>
                    {u.onboarding_completed
                      ? <span className="chip pos">✓ done</span>
                      : <span className="chip warn">pending</span>}
                  </td>
                  <td>
                    {u.device
                      ? <span style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--ink-2)' }}>{u.device.platform ?? '—'}</span>
                      : <span className="muted">—</span>}
                  </td>
                  <td>
                    <div className="col" style={{ gap: 1 }}>
                      <span style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--ink-2)' }}>
                        {u.device?.ip_address ?? '—'}
                      </span>
                      {(u.device?.inferred_city || u.device?.inferred_region) && (
                        <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>
                          {[u.device.inferred_city, u.device.inferred_region].filter(Boolean).join(', ')}
                        </span>
                      )}
                    </div>
                  </td>
                  <td>
                    <span className={`chip dot ${
                      u.account_status === 'active' ? 'pos' :
                      u.account_status === 'banned' ? 'neg' : 'warn'
                    }`}>
                      {u.account_status ?? 'active'}
                    </span>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
};
