'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useAuth } from '@/lib/auth-context';
import { usersApi, invitationsApi, AdminUser, AdminInvitation } from '@/lib/api';
import { Avatar } from '@/components/ui/avatar';

/**
 * Global workspace roles (stored in User.globalRole):
 *
 *  ADMIN        — Full system access. Manage all users, all projects, quotas, settings.
 *                 Sees every project regardless of membership.
 *
 *  MEMBER       — Regular registered user. Can create their own projects,
 *                 invite members, upload videos. Storage quota applies to owned projects.
 *
 *  PROJECT_USER — Invited-only user. Has no workspace presence beyond their invitations.
 *                 Cannot create projects. No storage quota (no owned projects).
 *
 *  (Project-level roles in ProjectMember.role:
 *   ADMIN | EDITOR | REVIEWER | VIEWER — scoped to a specific project.)
 */
async function safeCopy(text: string): Promise<void> {
  if (typeof window === 'undefined') return;
  try {
    const cb = navigator.clipboard;
    if (cb && typeof cb.writeText === 'function') {
      await cb.writeText(text);
    } else {
      const el = document.createElement('textarea');
      el.value = text;
      el.style.cssText = 'position:fixed;top:-999px;left:-999px;opacity:0';
      document.body.appendChild(el);
      el.focus(); el.select();
      try { document.execCommand('copy'); } catch { /* ignore */ }
      document.body.removeChild(el);
    }
  } catch { /* ignore */ }
}
const GLOBAL_ROLE_CONFIG: Record<string, { label: string; badge: string }> = {
  ADMIN:        { label: 'Admin',         badge: 'badge-danger' },
  MEMBER:       { label: 'Member',        badge: 'badge-muted' },
  PROJECT_USER: { label: 'Project User', badge: 'badge-subtle' },
};

export default function UsersPage() {
  const { user: currentUser, token } = useAuth();
  const [users, setUsers] = useState<AdminUser[]>([]);
  const [invitations, setInvitations] = useState<AdminInvitation[]>([]);
  const [loading, setLoading] = useState(true);
  const [updating, setUpdating] = useState<string | null>(null);
  const [confirmDelete, setConfirmDelete] = useState<string | null>(null);

  // Quota edit
  const [editingQuota, setEditingQuota] = useState<string | null>(null);
  const [quotaInput, setQuotaInput] = useState('');
  const [quotaUnit, setQuotaUnit] = useState<'MB' | 'GB'>('MB');
  const [quotaError, setQuotaError] = useState('');

  const formatBytes = (bytes: number): string => {
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
    return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`;
  };

  const parseBytes = (value: string, unit: 'MB' | 'GB'): number => {
    const v = parseFloat(value);
    if (unit === 'GB') return Math.round(v * 1024 * 1024 * 1024);
    return Math.round(v * 1024 * 1024);
  };

  const openQuotaEdit = (u: AdminUser) => {
    const quotaBytes = u.storageQuota;
    // Determine best unit: show GB if >= 1024 MB, otherwise MB
    const quotaMB = quotaBytes / 1024 / 1024;
    if (quotaMB >= 1024) {
      // Show in GB
      setQuotaInput(String(Math.round(quotaMB / 1024)));
      setQuotaUnit('GB');
    } else {
      setQuotaInput(String(Math.round(quotaMB)));
      setQuotaUnit('MB');
    }
    setQuotaError('');
    setEditingQuota(u.id);
  };

  const handleQuotaSave = async (userId: string) => {
    const parsed = parseFloat(quotaInput);
    if (isNaN(parsed) || parsed < 1) {
      setQuotaError('Enter a value ≥ 1');
      return;
    }
    setUpdating(userId);
    setQuotaError('');
    try {
      const bytes = parseBytes(quotaInput, quotaUnit);
      const { user: updated } = await usersApi.updateQuota(token!, userId, bytes);
      setUsers(prev => prev.map(u => u.id === userId
        ? { ...u, storageQuota: updated.storageQuota, storageUsed: updated.storageUsed }
        : u));
      setEditingQuota(null);
    } catch (err) {
      setQuotaError(err instanceof Error ? err.message : 'Failed to update quota');
    } finally {
      setUpdating(null);
    }
  };
  const [activeTab, setActiveTab] = useState<'users' | 'invites'>('users');

  // Invite form — workspace MEMBER invite (email only)
  const [inviteEmail, setInviteEmail] = useState('');
  const [inviting, setInviting] = useState(false);
  const [inviteError, setInviteError] = useState('');
  const [inviteSuccess, setInviteSuccess] = useState('');
  const [createdLink, setCreatedLink] = useState('');
  const [revokingId, setRevokingId] = useState<string | null>(null);
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const inviteUrlMap = useRef<Record<string, string>>({});

  const isAdmin = currentUser?.globalRole === 'ADMIN';

  const loadUsers = useCallback(async () => {
    if (!token || !isAdmin) return;
    try {
      const { users: u } = await usersApi.list(token);
      setUsers(u);
    } catch {
      console.error('Failed to load users');
    } finally {
      setLoading(false);
    }
  }, [token, isAdmin]);

  const loadInvitations = useCallback(async () => {
    if (!token || !isAdmin) return;
    try {
      const { invitations: inv } = await invitationsApi.listAll(token);
      setInvitations(inv);
      // Cache invite URLs
      for (const i of inv) {
        inviteUrlMap.current[i.token] = `${window.location.origin}/invite/${i.token}`;
      }
    } catch {
      console.error('Failed to load invitations');
    } finally {
      setLoading(false);
    }
  }, [token, isAdmin]);

  useEffect(() => {
    if (!token || !isAdmin) return;
    if (activeTab === 'users') loadUsers();
    else loadInvitations();
  }, [token, isAdmin, activeTab, loadUsers, loadInvitations]);

  // ── Send workspace invite ──────────────────────────────────────────────────────
  const handleInvite = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!token || !inviteEmail.trim()) return;
    setInviting(true);
    setInviteError('');
    setInviteSuccess('');
    setCreatedLink('');
    try {
      // Workspace invite → POST /api/invitations/workspace → creates MEMBER user
      const { inviteUrl } = await invitationsApi.inviteMember(token, inviteEmail.trim());
      const fullUrl = inviteUrl;
      const tokenPart = inviteUrl.split('/invite/').pop()!;
      inviteUrlMap.current[tokenPart] = fullUrl;
      // Optimistically add to list — backend returns the real invitation
      setInvitations(prev => [...prev, {
        id: Math.random().toString(),
        email: inviteEmail.trim(),
        projectId: '',
        role: 'MEMBER',
        token: tokenPart,
        status: 'PENDING',
        invitedBy: null,
        expiresAt: '',
        createdAt: new Date().toISOString(),
        project: { id: '', name: 'Workspace' },
        type: 'WORKSPACE',
      }]);
      setInviteEmail('');
      setInviteSuccess(`Invitation sent to ${inviteEmail.trim()}`);
      await safeCopy(fullUrl);
      setCreatedLink(fullUrl);
      setTimeout(() => setInviteSuccess(''), 6000);
    } catch (err) {
      setInviteError(err instanceof Error ? err.message : 'Failed to send invitation');
    } finally {
      setInviting(false);
    }
  };

  // ── Revoke invite ────────────────────────────────────────────────────────────
  const handleRevoke = async (invitationId: string) => {
    if (!token) return;
    setRevokingId(invitationId);
    try {
      await invitationsApi.revoke(token, invitationId);
      setInvitations(prev => prev.filter(i => i.id !== invitationId));
    } catch {
      alert('Failed to revoke invitation');
    } finally {
      setRevokingId(null);
    }
  };

  // ── Copy link ────────────────────────────────────────────────────────────────
  const handleCopy = async (inv: AdminInvitation) => {
    // Build full URL: either from cache or construct from known origin
    const url = inviteUrlMap.current[inv.token] ?? `${window.location.origin}/invite/${inv.token}`;
    await navigator.clipboard.writeText(url).catch(() => {});
    setCopiedId(inv.id);
    setTimeout(() => setCopiedId(null), 2000);
  };

  // ── User actions ─────────────────────────────────────────────────────────────
  const handleGlobalRoleChange = async (userId: string, globalRole: string) => {
    if (!token) return;
    setUpdating(userId);
    try {
      const { user: updated } = await usersApi.updateRole(token, userId, globalRole);
      setUsers(prev => prev.map(u => u.id === userId
        ? { ...u, globalRole: (updated as any).globalRole ?? globalRole }
        : u));
    } catch (err) {
      alert(err instanceof Error ? err.message : 'Failed to update role');
    } finally {
      setUpdating(null);
    }
  };

  const handleToggleActive = async (userId: string, currentActive: boolean) => {
    if (!token) return;
    setUpdating(userId);
    try {
      const { user: updated } = await usersApi.updateActive(token, userId, !currentActive);
      setUsers(prev => prev.map(u => u.id === userId ? { ...u, active: updated.active } : u));
    } catch (err) {
      alert(err instanceof Error ? err.message : 'Failed to update status');
    } finally {
      setUpdating(null);
    }
  };

  const handleDelete = async (userId: string) => {
    if (!token) return;
    try {
      await usersApi.deleteUser(token, userId);
      setUsers(prev => prev.filter(u => u.id !== userId));
      setConfirmDelete(null);
    } catch (err) {
      alert(err instanceof Error ? err.message : 'Failed to delete user');
    }
  };

  if (!isAdmin) {
    return (
      <div className="min-h-screen flex items-center justify-center" style={{ background: 'var(--bg)' }}>
        <p className="text-sm" style={{ color: 'var(--text-muted)' }}>Admin access required</p>
      </div>
    );
  }

  return (
    <div className="min-h-screen" style={{ background: 'var(--bg)' }}>
      {/* Header */}
      <header className="sticky top-0 z-10 px-4 md:px-8 py-4 flex items-center justify-between shrink-0 gap-3"
              style={{
                background: 'rgba(10,11,20,0.80)',
                backdropFilter: 'blur(12px)',
                borderBottom: '1px solid rgba(255,255,255,0.06)',
              }}>
        <div>
          <h1 className="text-xl font-semibold" style={{ color: 'var(--text)' }}>Workspace</h1>
          <p className="text-sm mt-0.5" style={{ color: 'var(--text-muted)' }}>
            {loading ? '…' : activeTab === 'users' ? `${users.length} user${users.length !== 1 ? 's' : ''}` : `${invitations.length} pending invitation${invitations.length !== 1 ? 's' : ''}`}
          </p>
        </div>

        {/* Tabs */}
        <div className="flex items-center gap-1 p-1 rounded-lg"
             style={{ background: 'rgba(255,255,255,0.04)' }}>
          {[['users', 'Users'], ['invites', 'Invitations']].map(([tab, label]) => (
            <button key={tab}
              onClick={() => setActiveTab(tab as any)}
              className="px-4 py-1.5 rounded-md text-xs font-medium transition-all"
              style={{
                background: activeTab === tab ? 'rgba(99,102,241,0.20)' : 'transparent',
                color: activeTab === tab ? '#A5B4FC' : 'var(--text-muted)',
              }}>
              {label}
              {tab === 'invites' && invitations.length > 0 && (
                <span className="ml-1.5 text-[10px] px-1.5 py-0.5 rounded-full"
                      style={{ background: 'rgba(255,255,255,0.06)', color: 'inherit' }}>
                  {invitations.length}
                </span>
              )}
            </button>
          ))}
        </div>

        <button onClick={() => activeTab === 'users' ? loadUsers() : loadInvitations()} className="btn btn-secondary btn-md">
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" />
          </svg>
          <span className="hidden sm:inline">Refresh</span>
        </button>
      </header>

      <div className="px-4 md:px-8 py-6">

        {/* ── Users Tab ──────────────────────────────────────────────────────── */}
        {activeTab === 'users' && (
          <>
            {loading ? (
              <div className="space-y-3">
                {[1,2,3,4].map(i => (
                  <div key={i} className="card h-20 skeleton" style={{ animationDelay: `${i*60}ms` }} />
                ))}
              </div>
            ) : (
              <div className="space-y-3">
                {users.map(u => {
                  const roleCfg = GLOBAL_ROLE_CONFIG[u.globalRole] ?? GLOBAL_ROLE_CONFIG.MEMBER;
                  const isMe = u.id === currentUser?.id;

                  return (
                    <div key={u.id}
                         className="card animate-fade-in overflow-hidden"
                         style={{ opacity: u.active ? 1 : 0.5 }}>
                      {/* Top row: avatar + info + role/actions */}
                      <div className="flex items-start gap-3 p-4">
                        {/* Avatar */}
                        <Avatar name={u.name} src={u.avatarUrl} size="md" />

                        {/* Info */}
                        <div className="flex-1 min-w-0">
                          <div className="flex flex-wrap items-center gap-1.5">
                            <span className="text-sm font-medium" style={{ color: 'var(--text)' }}>{u.name}</span>
                            {isMe && <span className="badge badge-brand text-[10px]">you</span>}
                            {!u.active && <span className="badge badge-muted text-[10px]">inactive</span>}
                          </div>
                          <p className="text-xs mt-0.5 truncate" style={{ color: 'var(--text-muted)' }}>{u.email}</p>
                        </div>

                        {/* Role + Actions */}
                        <div className="flex items-center gap-1.5 shrink-0">
                          <select
                            value={u.globalRole}
                            onChange={e => handleGlobalRoleChange(u.id, e.target.value)}
                            disabled={updating === u.id || isMe}
                            className="input text-xs py-1.5"
                            style={{ minWidth: '90px', maxWidth: '100px' }}
                          >
                            {Object.entries(GLOBAL_ROLE_CONFIG).map(([value, cfg]) => (
                              <option key={value} value={value}>{cfg.label}</option>
                            ))}
                          </select>
                          {!isMe && (
                            <div className="flex items-center gap-1">
                              <button
                                onClick={() => openQuotaEdit(u)}
                                disabled={updating === u.id}
                                className="btn btn-secondary btn-sm"
                                title="Edit storage quota"
                              >
                                <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                                  <path strokeLinecap="round" strokeLinejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
                                </svg>
                              </button>
                              <button
                                onClick={() => handleToggleActive(u.id, u.active)}
                                disabled={updating === u.id}
                                className={`btn btn-sm ${u.active ? 'btn-secondary' : 'btn-primary'}`}
                                title={u.active ? 'Deactivate' : 'Activate'}
                              >
                                {u.active ? (
                                  <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                                    <path strokeLinecap="round" strokeLinejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />
                                  </svg>
                                ) : (
                                  <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                                    <path strokeLinecap="round" strokeLinejoin="round" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
                                  </svg>
                                )}
                              </button>
                              <button
                                onClick={() => setConfirmDelete(u.id)}
                                className="btn btn-danger btn-sm"
                                title="Delete user"
                              >
                                <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                                  <path strokeLinecap="round" strokeLinejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                                </svg>
                              </button>
                            </div>
                          )}
                        </div>
                      </div>

                      {/* Stats row — desktop only */}
                      <div className="hidden sm:flex items-center gap-4 px-4 pb-3 text-xs" style={{ color: 'var(--text-muted)' }}>
                        <span>{u.ownedProjects ?? 0} owned</span>
                        <span>{((u._count?.memberships ?? 0) - (u.ownedProjects ?? 0))} shared</span>
                        <span>{u._count?.comments ?? 0} comments</span>
                        <span>{new Date(u.createdAt).toLocaleDateString('en-US', { month: 'short', year: 'numeric' })}</span>
                        {u.ownedProjects > 0 && (
                          <div className="flex items-center gap-2">
                            <div className="relative w-16 h-1.5 rounded-full overflow-hidden" style={{ background: 'rgba(255,255,255,0.08)' }}>
                              <div
                                className="absolute left-0 top-0 h-full rounded-full transition-all"
                                style={{
                                  width: `${Math.min(100, Math.round((u.storageUsed / Math.max(u.storageQuota, 1)) * 100))}%`,
                                  background: u.storageUsed >= u.storageQuota ? '#F87171' : '#6366F1',
                                }}
                              />
                            </div>
                            <span className="whitespace-nowrap" style={{ color: u.storageUsed >= u.storageQuota ? '#F87171' : undefined }}>
                              {formatBytes(u.storageUsed)} / {formatBytes(u.storageQuota)}
                            </span>
                          </div>
                        )}
                        {u.ownedProjects === 0 && (
                          <span style={{ color: 'var(--text-subtle)' }}>—</span>
                        )}
                      </div>

                      {/* Mobile stats — shown only on small screens */}
                      <div className="flex sm:hidden items-center gap-3 px-4 pb-3 text-xs" style={{ color: 'var(--text-muted)' }}>
                        <span>{u.ownedProjects ?? 0} owned</span>
                        <span>{u._count?.comments ?? 0} comments</span>
                      </div>

                      {/* Inline quota editor */}
                      {editingQuota === u.id && (
                        <div className="mx-4 mb-4 p-3 rounded-lg animate-fade-in"
                             style={{
                               background: 'rgba(99,102,241,0.06)',
                               border: '1px solid rgba(99,102,241,0.20)',
                             }}>
                          <div className="flex items-center gap-2 flex-wrap">
                            <svg className="w-3.5 h-3.5 shrink-0" style={{ color: '#A5B4FC' }} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                              <path strokeLinecap="round" strokeLinejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
                            </svg>
                            <span className="text-xs font-medium" style={{ color: 'var(--text)' }}>
                              Quota for {u.name}:
                            </span>
                            <div className="flex items-center gap-1">
                              <input
                                type="number"
                                min="1"
                                step="1"
                                className="input text-xs py-1 w-20"
                                value={quotaInput}
                                onChange={e => setQuotaInput(e.target.value)}
                                onKeyDown={e => e.key === 'Enter' && handleQuotaSave(u.id)}
                                autoFocus
                              />
                              <select
                                className="input text-xs py-1"
                                value={quotaUnit}
                                onChange={e => setQuotaUnit(e.target.value as 'MB' | 'GB')}
                              >
                                <option value="MB">MB</option>
                                <option value="GB">GB</option>
                              </select>
                            </div>
                            <button
                              onClick={() => handleQuotaSave(u.id)}
                              disabled={updating === u.id}
                              className="btn btn-primary btn-sm text-xs"
                            >
                              Save
                            </button>
                            <button
                              onClick={() => { setEditingQuota(null); setQuotaError(''); }}
                              className="btn btn-secondary btn-sm text-xs"
                            >
                              Cancel
                            </button>
                            {quotaError && (
                              <span className="text-xs w-full" style={{ color: '#F87171' }}>{quotaError}</span>
                            )}
                          </div>
                          <div className="mt-2">
                            <div className="relative w-full h-1.5 rounded-full overflow-hidden" style={{ background: 'rgba(255,255,255,0.08)' }}>
                              <div
                                className="absolute left-0 top-0 h-full rounded-full"
                                style={{
                                  width: `${Math.min(100, Math.round((u.storageUsed / Math.max(parseBytes(quotaInput, quotaUnit), 1)) * 100))}%`,
                                  background: u.storageUsed >= parseBytes(quotaInput, quotaUnit) ? '#F87171' : '#6366F1',
                                }}
                              />
                            </div>
                            <p className="text-[10px] mt-1" style={{ color: 'var(--text-subtle)' }}>
                              Currently used: {formatBytes(u.storageUsed)} ({Math.round((u.storageUsed / Math.max(u.storageQuota, 1)) * 100)}%)
                            </p>
                          </div>
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            )}
          </>
        )}

        {/* ── Invitations Tab ────────────────────────────────────────────────── */}
        {activeTab === 'invites' && (
          <div className="max-w-3xl animate-fade-in">
            {/* Invite form */}
            <div className="card p-5 mb-6">
              <h2 className="text-sm font-semibold mb-4" style={{ color: 'var(--text)' }}>
                Invite member
              </h2>

              <form onSubmit={handleInvite} className="space-y-4">
                <div className="flex flex-col sm:flex-row items-stretch sm:items-end gap-3">
                  <div className="flex-1">
                    <label className="block text-xs mb-1.5" style={{ color: 'var(--text-muted)' }}>
                      Invite email address
                    </label>
                    <input
                      type="email"
                      className="input"
                      value={inviteEmail}
                      onChange={e => setInviteEmail(e.target.value)}
                      placeholder="colleague@company.com"
                      required
                    />
                  </div>
                  <button type="submit" disabled={inviting || !inviteEmail.trim()} className="btn btn-primary btn-md shrink-0">
                    {inviting ? 'Sending…' : (
                      <span className="flex items-center gap-1.5">
                        <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                          <path strokeLinecap="round" strokeLinejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
                        </svg>
                        Send Invite
                      </span>
                    )}
                  </button>
                </div>

                {inviteError && (
                  <p className="text-xs" style={{ color: '#F87171' }}>{inviteError}</p>
                )}
                {inviteSuccess && (
                  <span className="text-xs" style={{ color: '#86EFAC' }}>{inviteSuccess}</span>
                )}

                {createdLink && (
                  <div className="rounded-lg p-3 animate-scale-in"
                       style={{ background: 'rgba(34,197,94,0.08)', border: '1px solid rgba(34,197,94,0.20)' }}>
                    <div className="flex items-center gap-2 mb-1">
                      <svg className="w-3.5 h-3.5 shrink-0" style={{ color: '#86EFAC' }} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                        <path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                      </svg>
                      <span className="text-xs font-medium" style={{ color: '#86EFAC' }}>Link copied to clipboard!</span>
                    </div>
                    <p className="text-[10px] truncate" style={{ color: 'rgba(134,239,172,0.7)' }}>{createdLink}</p>
                  </div>
                )}
              </form>
            </div>

            {/* Pending invitations */}
            <div className="card overflow-hidden">
              <div className="px-5 py-4 border-b flex items-center justify-between"
                   style={{ borderColor: 'rgba(255,255,255,0.06)' }}>
                <h2 className="text-sm font-semibold" style={{ color: 'var(--text)' }}>Pending invitations</h2>
                <span className="text-xs px-2 py-0.5 rounded-full"
                      style={{ background: 'rgba(255,255,255,0.05)', color: 'var(--text-muted)' }}>
                  {invitations.length}
                </span>
              </div>

              {loading ? (
                <div className="p-8 text-center">
                  <div className="w-5 h-5 rounded-full animate-spin mx-auto"
                       style={{ borderColor: '#6366F1', borderTopColor: 'transparent' }} />
                </div>
              ) : invitations.length === 0 ? (
                <div className="p-8 text-center">
                  <div className="w-12 h-12 rounded-2xl mx-auto mb-3 flex items-center justify-center"
                       style={{ background: 'rgba(99,102,241,0.08)', border: '1px solid rgba(99,102,241,0.12)' }}>
                    <svg className="w-5 h-5" style={{ color: '#6366F1' }} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                      <path strokeLinecap="round" strokeLinejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
                    </svg>
                  </div>
                  <p className="text-sm" style={{ color: 'var(--text-muted)' }}>No pending invitations</p>
                  <p className="text-xs mt-1" style={{ color: 'var(--text-subtle)' }}>Use the form above to invite new members</p>
                </div>
              ) : (
                <div className="divide-y" style={{ borderColor: 'rgba(255,255,255,0.04)' }}>
                  {invitations.map(inv => (
                    <div key={inv.id} className="flex items-center gap-4 px-5 py-4">
                      {/* Icon */}
                      <div className="w-9 h-9 rounded-full flex items-center justify-center shrink-0"
                           style={{ background: 'rgba(99,102,241,0.08)' }}>
                        <svg className="w-4 h-4" style={{ color: '#818CF8' }} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                          <path strokeLinecap="round" strokeLinejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
                        </svg>
                      </div>

                      {/* Info */}
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2">
                          <span className="text-sm font-medium" style={{ color: 'var(--text)' }}>{inv.email}</span>
                          {inv.type === 'WORKSPACE' ? (
                            <span className="badge badge-danger text-[10px]">Workspace</span>
                          ) : (
                            <span className="badge badge-brand text-[10px]">Project</span>
                          )}
                        </div>
                        <div className="flex items-center gap-2 mt-0.5">
                          <span className="text-xs" style={{ color: '#818CF8' }}>
                            {inv.type === 'WORKSPACE' ? 'Workspace member' : (inv.project?.name ?? '—')}
                          </span>
                          <span className="text-xs" style={{ color: 'var(--text-subtle)' }}>·</span>
                          <span className="text-xs" style={{ color: 'var(--text-subtle)' }}>
                            Sent {new Date(inv.createdAt).toLocaleDateString()} · Expires {new Date(inv.expiresAt).toLocaleDateString()}
                          </span>
                        </div>
                      </div>

                      {/* Actions */}
                      <div className="flex items-center gap-1.5 shrink-0">
                        <button
                          onClick={() => handleCopy(inv)}
                          className="btn btn-secondary btn-sm"
                          title="Copy invite link"
                        >
                          {copiedId === inv.id ? (
                            <svg className="w-3.5 h-3.5" style={{ color: '#86EFAC' }} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                              <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                            </svg>
                          ) : (
                            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                              <path strokeLinecap="round" strokeLinejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244" />
                            </svg>
                          )}
                        </button>
                        <button
                          onClick={() => handleRevoke(inv.id)}
                          disabled={revokingId === inv.id}
                          className="btn btn-danger btn-sm"
                          title="Revoke invitation"
                        >
                          {revokingId === inv.id ? '…' : (
                            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                              <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
                            </svg>
                          )}
                        </button>
                      </div>
                    </div>
                  ))}
                </div>
              )}

              {invitations.length > 0 && (
                <div className="px-5 py-3 border-t" style={{ borderColor: 'rgba(255,255,255,0.04)' }}>
                  <p className="text-xs" style={{ color: 'var(--text-subtle)' }}>
                    Invitation links expire after 7 days. Copy a link and send it manually to your invitee.
                  </p>
                </div>
              )}
            </div>
          </div>
        )}
      </div>

      {/* Delete confirm modal */}
      {confirmDelete && (
        <div className="fixed inset-0 z-50 flex items-center justify-center"
             style={{ background: 'rgba(0,0,0,0.7)' }}>
          <div className="card p-6 max-w-sm w-full mx-4 animate-scale-in"
               style={{ maxWidth: '400px' }}>
            <h3 className="text-base font-semibold mb-2" style={{ color: 'var(--text)' }}>
              Delete user?
            </h3>
            <p className="text-sm mb-5" style={{ color: 'var(--text-muted)' }}>
              This will permanently delete the user and all their comments. This action cannot be undone.
            </p>
            <div className="flex gap-3 justify-end">
              <button onClick={() => setConfirmDelete(null)} className="btn btn-secondary btn-md">
                Cancel
              </button>
              <button
                onClick={() => handleDelete(confirmDelete)}
                className="btn btn-danger btn-md"
              >
                Delete
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
