const { useEffect, useState } = React;

function formatDateTime(value) {
  if (!value) {
    return 'Not set';
  }

  return new Intl.DateTimeFormat(undefined, {
    dateStyle: 'medium',
    timeStyle: 'short'
  }).format(new Date(value));
}

function agentIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <rect x="5" y="7" width="14" height="10" rx="3"></rect>
      <path d="M12 4v3"></path>
      <circle cx="10" cy="12" r="1"></circle>
      <circle cx="14" cy="12" r="1"></circle>
      <path d="M9 15h6"></path>
    </svg>
  );
}

function roleClass(role) {
  const classes = {
    Human: 'human',
    Pending: 'pending',
    Customer: 'customer',
    'Internal User': 'internal',
    Administrator: 'administrator',
    Agent: 'agent'
  };

  return classes[role] || 'pending';
}

function roleLabel(role) {
  return (
    <span className={`role-badge ${roleClass(role)}`}>
      {role === 'Agent' ? agentIcon() : null}
      {role}
    </span>
  );
}

function attendeeBadge(user) {
  return (
    <span className={`attendance-pill ${user.attended ? 'present' : 'absent'}`}>
      {user.attended ? 'Attended' : 'Not Attended'}
    </span>
  );
}

function extractToken(input) {
  const trimmed = (input || '').trim();

  if (!trimmed) {
    return '';
  }

  if (trimmed.includes('/check-in/')) {
    const parts = trimmed.split('/check-in/');
    return decodeURIComponent(parts[parts.length - 1].split(/[?#]/)[0]);
  }

  return trimmed;
}

function downloadQr(qr) {
  if (!qr?.dataUrl) {
    return;
  }

  const filenameBase = String(qr.badge?.displayName || qr.name || 'summit-pass')
    .normalize('NFKD')
    .replace(/[^\x00-\x7F]/g, '')
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '') || 'summit-pass';

  const link = document.createElement('a');
  link.href = qr.dataUrl;
  link.download = `${filenameBase}-garage-beta-qr.png`;
  link.click();
}

function copyText(value) {
  if (!value || typeof navigator === 'undefined' || !navigator.clipboard) {
    return;
  }

  navigator.clipboard.writeText(value).catch(() => {});
}

function initialAdminAuthState() {
  if (typeof window === 'undefined') {
    return {
      username: '',
      password: '',
      authorization: '',
      authenticated: false,
      checking: false
    };
  }

  return {
    username: window.sessionStorage.getItem('summitAdminUser') || '',
    password: '',
    authorization: window.sessionStorage.getItem('summitAdminAuth') || '',
    authenticated: false,
    checking: false
  };
}

function initialRegistrationState() {
  return {
    name: '',
    email: '',
    company: '',
    title: '',
    bringingAgent: false,
    agentName: '',
    agentEmoji: '🤖',
    agentRole: ''
  };
}

const AGENT_EMOJI_OPTIONS = ['🤖', '🛰️', '🚀', '🧠', '🎯', '🌟', '🦊', '🧩', '💡', '📚', '🎨', '🛠️'];

function SummitBrandLockup({ caption = 'Agentic AI Workshop' }) {
  return (
    <div className="summit-brand" aria-label="Adobe Summit 2026">
      <div className="summit-brand-mark" aria-hidden="true">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
      </div>
      <div className="summit-brand-copy">
        <div className="summit-brand-title">Adobe Summit 2026</div>
        <div className="summit-brand-caption">{caption}</div>
      </div>
    </div>
  );
}

function RegistrationBadgeCard({ card }) {
  if (!card?.user || !card?.qr) {
    return null;
  }

  const badge = card.qr.badge || {};
  const heading = badge.displayName || card.user.name;
  const detailLine = badge.detailLine || [card.user.company, card.user.title].filter(Boolean).join(' | ');
  const companionLabel = badge.companionLabel || 'Summit garage access';
  const eventLine = badge.eventLine || 'Summit 2026 | Garage Build | Agentic Access';

  return (
    <article className={`badge-ticket ${card.kind}`}>
      <div className="badge-ticket-top">
        <span className="badge-ticket-eyebrow">{badge.eyebrow || 'Garage Beta Access'}</span>
        {roleLabel(card.user.role)}
      </div>
      <div className="badge-ticket-kicker">{card.kind === 'agent' ? 'Agent pass' : 'Human pass'}</div>
      <h3>{heading}</h3>
      <p className="muted">{detailLine}</p>
      <div className="badge-ticket-strip">
        <span>{companionLabel}</span>
        <span>{eventLine}</span>
      </div>
      <div className="badge-ticket-qr">
        <img src={card.qr.dataUrl} alt={`QR badge for ${heading}`} />
      </div>
      <div className="badge-ticket-actions">
        <button className="button" type="button" onClick={() => downloadQr(card.qr)}>
          Download QR
        </button>
        <a className="ghost-button" href={card.qr.checkInUrl} target="_blank" rel="noreferrer">
          Open badge
        </a>
      </div>
    </article>
  );
}

function getPageMode() {
  if (typeof window === 'undefined') {
    return 'agent-register';
  }

  const pathname = (window.location.pathname || '/').replace(/\/+$/, '') || '/';

  if (pathname === '/admin') {
    return 'admin';
  }

  return 'agent-register';
}

function App() {
  const [config, setConfig] = useState({ roles: [], adminAuthEnabled: false, playground: null });
  const pageMode = getPageMode();
  const isAdminPage = pageMode === 'admin';
  const [users, setUsers] = useState([]);
  const [loadingUsers, setLoadingUsers] = useState(false);
  const [registrationState, setRegistrationState] = useState(initialRegistrationState);
  const [registrationError, setRegistrationError] = useState('');
  const [registrationSuccess, setRegistrationSuccess] = useState(null);
  const [adminError, setAdminError] = useState('');
  const [roleFilter, setRoleFilter] = useState('All');
  const [search, setSearch] = useState('');
  const [selectedQr, setSelectedQr] = useState(null);
  const [scannerInput, setScannerInput] = useState('');
  const [scannerMessage, setScannerMessage] = useState('');
  const [scannerResult, setScannerResult] = useState(null);
  const [adminAuth, setAdminAuth] = useState(initialAdminAuthState);
  const [playgroundState, setPlaygroundState] = useState({ agents: [], documents: [] });
  const [loadingPlayground, setLoadingPlayground] = useState(false);
  const [agentPromptCopied, setAgentPromptCopied] = useState(false);

  function persistAdminSession(authorization, username) {
    if (typeof window === 'undefined') {
      return;
    }

    if (authorization) {
      window.sessionStorage.setItem('summitAdminAuth', authorization);
      window.sessionStorage.setItem('summitAdminUser', username);
      return;
    }

    window.sessionStorage.removeItem('summitAdminAuth');
    window.sessionStorage.removeItem('summitAdminUser');
  }

  function clearAdminSession() {
    persistAdminSession('', '');
    setAdminAuth((current) => ({
      ...current,
      password: '',
      authorization: '',
      authenticated: false,
      checking: false
    }));
    setUsers([]);
    setSelectedQr(null);
    setScannerInput('');
    setScannerMessage('');
    setScannerResult(null);
    setPlaygroundState({ agents: [], documents: [] });
  }

  async function loadConfig() {
    const response = await fetch('/api/config');
    const data = await response.json();
    setConfig(data);
    return data;
  }

  async function adminFetch(url, options = {}) {
    const headers = new Headers(options.headers || {});

    if (adminAuth.authorization) {
      headers.set('Authorization', adminAuth.authorization);
    }

    const response = await fetch(url, {
      ...options,
      headers
    });

    if (response.status === 401) {
      clearAdminSession();
      throw new Error('Admin sign-in required.');
    }

    return response;
  }

  async function verifyAdminSession(authorization = adminAuth.authorization, username = adminAuth.username) {
    if (!authorization) {
      return false;
    }

    const response = await fetch('/api/admin/session', {
      method: 'POST',
      headers: {
        Authorization: authorization
      }
    });

    if (!response.ok) {
      clearAdminSession();
      throw new Error('Admin sign-in required.');
    }

    const data = await response.json();
    persistAdminSession(authorization, username || data.username || 'admin');
    setAdminAuth((current) => ({
      ...current,
      username: username || data.username || current.username,
      password: '',
      authorization,
      authenticated: true,
      checking: false
    }));

    return true;
  }

  async function loadUsers() {
    if (config.adminAuthEnabled && !adminAuth.authorization) {
      setUsers([]);
      return;
    }

    setLoadingUsers(true);
    setAdminError('');

    try {
      const response = await adminFetch('/api/users');
      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Unable to load users.');
      }

      setUsers(data);
    } catch (error) {
      setAdminError(error.message);
    } finally {
      setLoadingUsers(false);
    }
  }

  async function loadPlayground() {
    if (config.adminAuthEnabled && !adminAuth.authorization) {
      setPlaygroundState({ agents: [], documents: [] });
      return;
    }

    setLoadingPlayground(true);
    setAdminError('');

    try {
      const response = await adminFetch('/api/playground');
      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Unable to load playground data.');
      }

      setPlaygroundState({
        agents: Array.isArray(data.agents) ? data.agents : [],
        documents: Array.isArray(data.documents) ? data.documents : []
      });
    } catch (error) {
      setAdminError(error.message);
    } finally {
      setLoadingPlayground(false);
    }
  }

  useEffect(() => {
    let isMounted = true;

    async function bootstrap() {
      try {
        const data = await loadConfig();

        if (!isMounted) {
          return;
        }

        if (data.adminAuthEnabled && adminAuth.authorization) {
          setAdminAuth((current) => ({
            ...current,
            checking: true
          }));

          try {
            await verifyAdminSession(adminAuth.authorization, adminAuth.username);
          } catch (error) {
            if (isMounted) {
              setAdminError(error.message);
            }
          }
        }
      } catch (error) {
        if (isMounted) {
          setAdminError('Unable to load app configuration.');
        }
      }
    }

    bootstrap();

    return () => {
      isMounted = false;
    };
  }, []);

  useEffect(() => {
    if (!isAdminPage) {
      return;
    }

    if (config.adminAuthEnabled) {
      if (adminAuth.authenticated) {
        loadUsers();
        loadPlayground();
      }

      return;
    }

    loadUsers();
    loadPlayground();
  }, [isAdminPage, config.adminAuthEnabled, adminAuth.authenticated]);

  const filteredUsers = users.filter((user) => {
    const matchesRole = roleFilter === 'All' || user.role === roleFilter;
    const haystack = [user.name, user.email, user.company, user.title, user.agentName, user.agentRole, user.ownerName]
      .join(' ')
      .toLowerCase();
    const matchesSearch = haystack.includes(search.trim().toLowerCase());
    return matchesRole && matchesSearch;
  });

  const roleCounts = config.roles.reduce(
    (counts, role) => ({ ...counts, [role]: users.filter((user) => user.role === role).length }),
    {}
  );

  const attendanceCount = users.filter((user) => user.attended).length;

  async function handleRegister(event) {
    event.preventDefault();
    setRegistrationError('');
    setRegistrationSuccess(null);
    setAgentPromptCopied(false);

    try {
      const payload = registrationState.bringingAgent
        ? registrationState
        : {
            ...registrationState,
            agentName: '',
            agentEmoji: '',
            agentRole: ''
          };
      const response = await fetch('/api/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Unable to register.');
      }

      setRegistrationSuccess(data);
      setRegistrationState(initialRegistrationState());
      setSelectedQr(data.attendeeQr || data.qr);

      if (!config.adminAuthEnabled || adminAuth.authenticated) {
        loadUsers();
      }
    } catch (error) {
      setRegistrationError(error.message);
    }
  }

  async function updateRole(userId, role) {
    setAdminError('');

    try {
      const response = await adminFetch(`/api/users/${userId}/role`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ role })
      });
      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Unable to update role.');
      }

      setUsers((currentUsers) => currentUsers.map((user) => (user.id === data.id ? data : user)));
    } catch (error) {
      setAdminError(error.message);
    }
  }

  async function updateAttendance(userId, attended) {
    setAdminError('');

    try {
      const response = await adminFetch(`/api/users/${userId}/attendance`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ attended })
      });
      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Unable to update attendance.');
      }

      setUsers((currentUsers) => currentUsers.map((user) => (user.id === data.id ? data : user)));
      setScannerResult(data);
    } catch (error) {
      setAdminError(error.message);
    }
  }

  async function fetchQr(userId) {
    setAdminError('');

    try {
      const response = await adminFetch(`/api/users/${userId}/qrcode`);
      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || 'Unable to load QR code.');
      }

      setSelectedQr(data);
    } catch (error) {
      setAdminError(error.message);
    }
  }

  async function removeUser(userId) {
    const confirmed = window.confirm('Delete this registrant and their QR lookup keys?');

    if (!confirmed) {
      return;
    }

    setAdminError('');

    try {
      const response = await adminFetch(`/api/users/${userId}`, { method: 'DELETE' });

      if (!response.ok) {
        const data = await response.json();
        throw new Error(data.error || 'Unable to delete user.');
      }

      setUsers((currentUsers) => currentUsers.filter((user) => user.id !== userId));

      if (selectedQr?.userId === userId) {
        setSelectedQr(null);
      }
    } catch (error) {
      setAdminError(error.message);
    }
  }

  async function lookupToken(token) {
    const response = await adminFetch('/api/attendance/lookup', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token })
    });
    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.error || 'Lookup failed.');
    }

    return data.user;
  }

  async function checkInToken(token) {
    const response = await adminFetch('/api/attendance/check-in', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token })
    });
    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.error || 'Check-in failed.');
    }

    return data.user;
  }

  async function handleScanner(mode) {
    const token = extractToken(scannerInput);
    setScannerMessage('');
    setScannerResult(null);
    setAdminError('');

    if (!token) {
      setScannerMessage('Scan or paste a QR token or full check-in URL first.');
      return;
    }

    try {
      const user = mode === 'lookup' ? await lookupToken(token) : await checkInToken(token);
      setScannerResult(user);
      setScannerMessage(mode === 'lookup' ? 'Registrant found.' : 'Registrant marked as attended.');
      setScannerInput('');
      loadUsers();
    } catch (error) {
      setAdminError(error.message);
    }
  }

  async function handleAdminSignIn(event) {
    event.preventDefault();
    setAdminError('');

    const username = adminAuth.username.trim();
    const password = adminAuth.password;

    if (!username || !password) {
      setAdminError('Admin username and password are required.');
      return;
    }

    setAdminAuth((current) => ({
      ...current,
      checking: true
    }));

    try {
      const authorization = `Basic ${window.btoa(`${username}:${password}`)}`;
      await verifyAdminSession(authorization, username);
      loadUsers();
      loadPlayground();
    } catch (error) {
      setAdminError(error.message);
    } finally {
      setAdminAuth((current) => ({
        ...current,
        checking: false,
        password: ''
      }));
    }
  }

  function handleAdminSignOut() {
    clearAdminSession();
  }

  const adminLocked = config.adminAuthEnabled && !adminAuth.authenticated;
  const playgroundAgentCount = playgroundState.agents.length;
  const playgroundDocCount = playgroundState.documents.length;
  const playgroundInfo = config.playground || {};
  const playgroundSetup = registrationSuccess?.playground || null;
  const agentOwnerPrompt = playgroundSetup?.handoffPrompt || '';
  const bringingAgent = Boolean(registrationState.bringingAgent);
  const successCards = Array.isArray(registrationSuccess?.cards) ? registrationSuccess.cards : [];
  const attendeeCard =
    successCards.find((card) => card.kind === 'human') ||
    (registrationSuccess?.attendee && registrationSuccess?.attendeeQr
      ? {
          kind: 'human',
          user: registrationSuccess.attendee,
          qr: registrationSuccess.attendeeQr
        }
      : null);
  const agentCard =
    successCards.find((card) => card.kind === 'agent') ||
    (registrationSuccess?.agent && registrationSuccess?.agentQr
      ? {
          kind: 'agent',
          user: registrationSuccess.agent,
          qr: registrationSuccess.agentQr
        }
      : null);

  function handleCopyAgentPrompt() {
    if (!agentOwnerPrompt) {
      return;
    }

    copyText(agentOwnerPrompt);
    setAgentPromptCopied(true);
    window.setTimeout(() => setAgentPromptCopied(false), 1800);
  }

  return (
    <div className="app-shell">
      <section className={`hero${isAdminPage ? '' : ' hero-register'}`}>
        {isAdminPage ? (
          <div className="hero-card hero-copy">
            <SummitBrandLockup caption="Workshop admin" />
            <h1>Agentic AI Workshop Admin</h1>
            <p>
              Manage registrations, scan badges, and review the linked human and agent records from
              one admin workspace.
            </p>
          </div>
        ) : (
          <div className="hero-card hero-copy">
            <SummitBrandLockup caption="Agentic AI Workshop" />
            <h1>Register for the workshop</h1>
            <p>
              Register yourself first. If you are bringing an agent, the extra fields appear and we
              will issue badges for both of you.
            </p>
          </div>
        )}

        <div className="hero-side">
          <div className="panel">
            {isAdminPage ? (
              <>
                {adminLocked ? (
                  <>
                    <h2>Admin access</h2>
                    <p className="muted">
                      The scanner lane and attendee controls are protected. Sign in with the shared
                      event admin credentials to continue.
                    </p>

                    {adminError ? <div className="error-banner">{adminError}</div> : null}

                    <form className="form-grid" onSubmit={handleAdminSignIn}>
                      <div className="field">
                        <label htmlFor="admin-username">Admin username</label>
                        <input
                          id="admin-username"
                          autoComplete="username"
                          value={adminAuth.username}
                          onChange={(event) =>
                            setAdminAuth((current) => ({ ...current, username: event.target.value }))
                          }
                          placeholder="summitadmin"
                          required
                        />
                      </div>
                      <div className="field">
                        <label htmlFor="admin-password">Admin password</label>
                        <input
                          id="admin-password"
                          type="password"
                          autoComplete="current-password"
                          value={adminAuth.password}
                          onChange={(event) =>
                            setAdminAuth((current) => ({ ...current, password: event.target.value }))
                          }
                          placeholder="Enter shared password"
                          required
                        />
                      </div>
                      <div className="field full">
                        <button className="button" type="submit" disabled={adminAuth.checking}>
                          {adminAuth.checking ? 'Checking access...' : 'Unlock admin'}
                        </button>
                      </div>
                    </form>
                  </>
                ) : (
                  <>
                    <div className="section-header">
                      <div>
                        <h2>Quick scanner lane</h2>
                        <p className="muted">
                          Paste a QR token or a full <span className="mono">/check-in/...</span> URL from a
                          scanner.
                        </p>
                      </div>
                      {config.adminAuthEnabled ? (
                        <button className="ghost-button" type="button" onClick={handleAdminSignOut}>
                          Sign out
                        </button>
                      ) : null}
                    </div>

                    {adminError ? <div className="error-banner">{adminError}</div> : null}

                    <div className="scanner-grid">
                      <div className="field">
                        <label htmlFor="scanner">QR token or check-in URL</label>
                        <input
                          id="scanner"
                          value={scannerInput}
                          onChange={(event) => setScannerInput(event.target.value)}
                          placeholder={`${config.publicBaseUrl || 'https://your-event-host'}/check-in/...`}
                        />
                      </div>
                      <div className="field">
                        <label>&nbsp;</label>
                        <button className="ghost-button" type="button" onClick={() => handleScanner('lookup')}>
                          Lookup registrant
                        </button>
                      </div>
                      <div className="field">
                        <label>&nbsp;</label>
                        <button className="button" type="button" onClick={() => handleScanner('checkin')}>
                          Mark attended
                        </button>
                      </div>
                    </div>

                    {scannerMessage ? <div className="scanner-banner">{scannerMessage}</div> : null}

                    {scannerResult ? (
                      <div className="quick-result">
                        <div className="user-card-header">
                          <div>
                            <strong>{scannerResult.name}</strong>
                            <div className="muted">
                              {scannerResult.company} | {scannerResult.title}
                            </div>
                          </div>
                          <div className="status-row">
                            {roleLabel(scannerResult.role)}
                            {attendeeBadge(scannerResult)}
                          </div>
                        </div>
                        <div className="meta-row muted">
                          <span>{scannerResult.email}</span>
                          <span>Registered {formatDateTime(scannerResult.registeredAt)}</span>
                        </div>
                      </div>
                    ) : null}
                  </>
                )}
              </>
            ) : (
              <>
                <h2>Registration</h2>
                <p className="muted">
                  Fill out your details below. If your agent is joining you, switch the mode and
                  complete the agent section too.
                </p>

                {registrationError ? <div className="error-banner">{registrationError}</div> : null}

                <form className="form-grid" onSubmit={handleRegister}>
                  <div className="field full">
                    <label>Registration mode</label>
                    <div className="mode-switch" role="group" aria-label="Registration mode">
                      <button
                        className={`mode-switch-option${bringingAgent ? '' : ' active'}`}
                        type="button"
                        aria-pressed={!bringingAgent}
                        onClick={() => setRegistrationState((current) => ({ ...current, bringingAgent: false }))}
                      >
                        Just me
                      </button>
                      <button
                        className={`mode-switch-option${bringingAgent ? ' active' : ''}`}
                        type="button"
                        aria-pressed={bringingAgent}
                        onClick={() => setRegistrationState((current) => ({ ...current, bringingAgent: true }))}
                      >
                        Human + Agent
                      </button>
                    </div>
                    <div className="mode-switch-caption muted">
                      {bringingAgent
                        ? 'One person record and one agent record will be created.'
                        : 'One person record will be created.'}
                    </div>
                  </div>
                  <div className="field full">
                    <label htmlFor="name">Full name</label>
                    <input
                      id="name"
                      value={registrationState.name}
                      onChange={(event) => setRegistrationState({ ...registrationState, name: event.target.value })}
                      placeholder="Jordan Lee"
                      required
                    />
                  </div>
                  <div className="field full">
                    <label htmlFor="email">Work email</label>
                    <input
                      id="email"
                      type="email"
                      value={registrationState.email}
                      onChange={(event) => setRegistrationState({ ...registrationState, email: event.target.value })}
                      placeholder="jordan@company.com"
                      required
                    />
                  </div>
                  <div className="field">
                    <label htmlFor="company">Company</label>
                    <input
                      id="company"
                      value={registrationState.company}
                      onChange={(event) => setRegistrationState({ ...registrationState, company: event.target.value })}
                      placeholder="Adobe"
                      required
                    />
                  </div>
                  <div className="field">
                    <label htmlFor="title">Job title</label>
                    <input
                      id="title"
                      value={registrationState.title}
                      onChange={(event) => setRegistrationState({ ...registrationState, title: event.target.value })}
                      placeholder="Senior Product Manager"
                      required
                    />
                  </div>
                  {bringingAgent ? (
                    <>
                      <div className="field full">
                        <div className="subsection-intro">
                          <strong>Agent details</strong>
                          <span className="muted">Add the name, emoji, and role for the agent you are bringing.</span>
                        </div>
                      </div>
                      <div className="field full">
                        <label htmlFor="agent-name">Agent name</label>
                        <input
                          id="agent-name"
                          value={registrationState.agentName}
                          onChange={(event) => setRegistrationState({ ...registrationState, agentName: event.target.value })}
                          placeholder="Nova"
                          required={bringingAgent}
                        />
                      </div>
                      <div className="field">
                        <label htmlFor="agent-emoji-picker">Agent emoji</label>
                        <div className="emoji-picker" id="agent-emoji-picker" role="group" aria-label="Agent emoji">
                          {AGENT_EMOJI_OPTIONS.map((emoji) => (
                            <button
                              key={emoji}
                              className={`emoji-option${registrationState.agentEmoji === emoji ? ' selected' : ''}`}
                              type="button"
                              aria-label={`Select ${emoji}`}
                              aria-pressed={registrationState.agentEmoji === emoji}
                              onClick={() => setRegistrationState({ ...registrationState, agentEmoji: emoji })}
                            >
                              <span>{emoji}</span>
                            </button>
                          ))}
                        </div>
                        <div className="emoji-selection muted">Selected: {registrationState.agentEmoji}</div>
                      </div>
                      <div className="field">
                        <label htmlFor="agent-role">Agent role</label>
                        <input
                          id="agent-role"
                          value={registrationState.agentRole}
                          onChange={(event) => setRegistrationState({ ...registrationState, agentRole: event.target.value })}
                          placeholder="Research strategist"
                          required={bringingAgent}
                        />
                      </div>
                    </>
                  ) : null}
                  <div className="field full">
                    <button className="button" type="submit">
                      {bringingAgent ? 'Register human + agent' : 'Register human pass'}
                    </button>
                  </div>
                </form>
              </>
            )}
          </div>

      {!isAdminPage && registrationSuccess ? (
        <div className="success-card">
          <div className="success-header">
            <strong>
              {agentCard
                ? `${attendeeCard?.user?.name || registrationSuccess.user.name} and ${agentCard.user.agentName || agentCard.user.name} are on the list.`
                : `${attendeeCard?.user?.name || registrationSuccess.user.name} is registered for the garage beta.`}
            </strong>
            <div className="muted">
              {agentCard
                ? 'Both records are live, both QR badges are ready, and the agent handoff packet is queued below.'
                : 'Your human registration is in the system and your Summit badge is ready to download or open.'}
            </div>
          </div>

          <div className={`badge-ticket-grid${agentCard ? ' dual' : ''}`}>
            <RegistrationBadgeCard card={attendeeCard} />
            {agentCard ? <RegistrationBadgeCard card={agentCard} /> : null}
          </div>

          {agentCard ? (
            <div className="prompt-panel">
              <div className="prompt-panel-header">
                <div>
                  <h3>Agent handoff prompt</h3>
                  <p className="muted">
                    Copy this into your agent so it can join the Summit playground with the issued
                    credentials and docs.
                  </p>
                </div>
                <div className="status-row">
                  <span className="status-pill">Provisioned</span>
                  {roleLabel(agentCard.user.role)}
                </div>
              </div>
              <div className="meta-grid" style={{ marginBottom: '14px' }}>
                <div className="meta-item">
                  <span>Playground agent ID</span>
                  <div className="mono">{playgroundSetup?.agentId || 'Not available'}</div>
                </div>
                <div className="meta-item">
                  <span>Agent should respond</span>
                  <div>
                    {playgroundSetup?.readinessMessage ||
                      playgroundInfo.readinessMessage ||
                      'I have all the details I need to join the Agent Playground. Let me know when you want me to join.'}
                  </div>
                </div>
                <div className="meta-item">
                  <span>Skill doc</span>
                  <div>
                    <a href={playgroundSetup?.connectionPacket?.skill_url || playgroundInfo.skillUrl} target="_blank" rel="noreferrer">
                      Open skill.md
                    </a>
                  </div>
                </div>
                <div className="meta-item">
                  <span>Invite doc</span>
                  <div>
                    <a href={playgroundSetup?.connectionPacket?.invite_url || playgroundInfo.inviteUrl} target="_blank" rel="noreferrer">
                      Open invite.md
                    </a>
                  </div>
                </div>
                <div className="meta-item">
                  <span>Agent profile</span>
                  <div>{[agentCard.user.agentEmoji, agentCard.user.agentRole].filter(Boolean).join(' ')}</div>
                </div>
                <div className="meta-item">
                  <span>MCP URL</span>
                  <div className="mono">{playgroundSetup?.connectionPacket?.mcp_url || playgroundInfo.mcpUrl || 'Not available'}</div>
                </div>
              </div>
              <pre className="mono prompt-panel-code">{agentOwnerPrompt || 'Prompt unavailable.'}</pre>
              <div className="action-row" style={{ marginTop: '14px' }}>
                <button className="button" type="button" onClick={handleCopyAgentPrompt}>
                  {agentPromptCopied ? 'Prompt copied' : 'Copy prompt'}
                </button>
                {(playgroundSetup?.connectionPacket?.skill_url || playgroundInfo.skillUrl) ? (
                  <a className="ghost-button" href={playgroundSetup?.connectionPacket?.skill_url || playgroundInfo.skillUrl} target="_blank" rel="noreferrer">
                    Open skill doc
                  </a>
                ) : null}
              </div>
            </div>
          ) : null}
        </div>
      ) : null}
        </div>
      </section>

      {isAdminPage ? (
      <>
      <section className="panel" style={{ marginTop: '24px' }}>
        <div className="section-header">
          <div>
            <h2>Admin control panel</h2>
            <p className="muted">
              Review registrants, adjust roles, inspect QR details, and track who actually showed
              up.
            </p>
          </div>
          {config.adminAuthEnabled && adminAuth.authenticated ? (
            <button className="ghost-button" type="button" onClick={handleAdminSignOut}>
              Sign out {adminAuth.username}
            </button>
          ) : null}
        </div>

        {adminError ? <div className="error-banner">{adminError}</div> : null}

        {adminLocked ? (
          <div className="empty-state">
            Admin access is protected. Sign in above to view attendee data, QR previews, and
            scanner controls.
          </div>
        ) : (
          <>
            <div className="stats-grid" style={{ marginBottom: '18px' }}>
              <div className="stat-card">
                <strong>{users.length}</strong>
                <span>Total registrants</span>
              </div>
              <div className="stat-card">
                <strong>{attendanceCount}</strong>
                <span>Attended</span>
              </div>
              {config.roles.map((role) => (
                <div className="stat-card" key={role}>
                  <strong>{roleCounts[role] || 0}</strong>
                  <span>{role}</span>
                </div>
              ))}
            </div>

            <div className="filters-grid" style={{ marginBottom: '18px' }}>
              <div className="field">
                <label htmlFor="search">Search</label>
                <input
                  id="search"
                  value={search}
                  onChange={(event) => setSearch(event.target.value)}
                  placeholder="Name, company, title, email"
                />
              </div>
              <div className="field">
                <label htmlFor="role-filter">Filter by role</label>
                <select id="role-filter" value={roleFilter} onChange={(event) => setRoleFilter(event.target.value)}>
                  <option value="All">All roles</option>
                  {config.roles.map((role) => (
                    <option key={role} value={role}>
                      {role}
                    </option>
                  ))}
                </select>
              </div>
              <div className="field">
                <label>&nbsp;</label>
                <button className="ghost-button" type="button" onClick={loadUsers}>
                  {loadingUsers ? 'Refreshing...' : 'Refresh list'}
                </button>
              </div>
            </div>

            <div className="users-layout">
              <div className="users-list">
                {filteredUsers.length === 0 ? (
                  <div className="empty-state">
                    {loadingUsers ? 'Loading registrants...' : 'No registrants match the current search and filter.'}
                  </div>
                ) : (
                  filteredUsers.map((user) => (
                    <article className="user-card" key={user.id}>
                      <div className="user-card-header">
                        <div>
                          <div className="user-name-row">
                            <span className={`avatar ${user.role === 'Agent' ? 'agent' : ''}`}>
                              {user.role === 'Agent' ? (
                                agentIcon()
                              ) : (
                                <strong>{user.name.slice(0, 1).toUpperCase()}</strong>
                              )}
                            </span>
                            <div>
                              <strong>{user.name}</strong>
                              <div className="muted">
                                {user.company} | {user.title}
                              </div>
                            </div>
                          </div>
                        </div>
                        <div className="status-row">
                          {roleLabel(user.role)}
                          {attendeeBadge(user)}
                        </div>
                      </div>

                      <div className="meta-grid">
                        <div className="meta-item">
                          <span>Email</span>
                          <div>{user.email}</div>
                        </div>
                        <div className="meta-item">
                          <span>Record type</span>
                          <div>{user.recordType || (user.role === 'Agent' ? 'agent' : 'human')}</div>
                        </div>
                        {user.agentName ? (
                          <div className="meta-item">
                            <span>Agent name</span>
                            <div>{[user.agentEmoji, user.agentName].filter(Boolean).join(' ')}</div>
                          </div>
                        ) : null}
                        {user.agentRole ? (
                          <div className="meta-item">
                            <span>Agent role</span>
                            <div>{user.agentRole}</div>
                          </div>
                        ) : null}
                        {user.ownerName ? (
                          <div className="meta-item">
                            <span>Human owner</span>
                            <div>{user.ownerName}</div>
                          </div>
                        ) : null}
                        <div className="meta-item">
                          <span>Registered</span>
                          <div>{formatDateTime(user.registeredAt)}</div>
                        </div>
                        <div className="meta-item">
                          <span>Attendance source</span>
                          <div>{user.attendanceSource || 'Not checked in yet'}</div>
                        </div>
                        <div className="meta-item">
                          <span>Checked in at</span>
                          <div>{user.attendedAt ? formatDateTime(user.attendedAt) : 'Not attended'}</div>
                        </div>
                      </div>

                      <div className="inline-actions">
                        <div className="field" style={{ minWidth: '220px' }}>
                          <label htmlFor={`role-${user.id}`}>Role</label>
                          <select
                            id={`role-${user.id}`}
                            value={user.role}
                            onChange={(event) => updateRole(user.id, event.target.value)}
                          >
                            {config.roles.map((role) => (
                              <option key={role} value={role}>
                                {role}
                              </option>
                            ))}
                          </select>
                        </div>
                        <div className="field">
                          <label>&nbsp;</label>
                          <button
                            className={user.attended ? 'ghost-button' : 'button'}
                            type="button"
                            onClick={() => updateAttendance(user.id, !user.attended)}
                          >
                            {user.attended ? 'Reset attendance' : 'Mark attended'}
                          </button>
                        </div>
                        <div className="field">
                          <label>&nbsp;</label>
                          <button className="ghost-button" type="button" onClick={() => fetchQr(user.id)}>
                            View QR
                          </button>
                        </div>
                        <div className="field">
                          <label>&nbsp;</label>
                          <button className="danger-button" type="button" onClick={() => removeUser(user.id)}>
                            Delete
                          </button>
                        </div>
                      </div>
                    </article>
                  ))
                )}
              </div>

              <aside className="qr-card">
                {selectedQr ? (
                  <>
                    <div className="qr-card-header">
                      <div>
                        <h3>{selectedQr.name}</h3>
                        <div className="muted">
                          {selectedQr.badge?.badgeLabel || 'Workshop pass'} | {selectedQr.email}
                        </div>
                      </div>
                      <button className="ghost-button" type="button" onClick={() => setSelectedQr(null)}>
                        Close
                      </button>
                    </div>
                    <p className="muted">
                      This QR resolves to the protected staff check-in link shown below.
                    </p>
                    <img src={selectedQr.dataUrl} alt={`QR code for ${selectedQr.name}`} />
                    <div className="meta-grid" style={{ marginBottom: '0' }}>
                      <div className="meta-item">
                        <span>QR token</span>
                        <div className="mono">{selectedQr.qrToken}</div>
                      </div>
                      <div className="meta-item">
                        <span>Pass URL</span>
                        <div>
                          <a href={selectedQr.checkInUrl} target="_blank" rel="noreferrer">
                            Open link
                          </a>
                        </div>
                      </div>
                    </div>
                    <div className="action-row" style={{ marginTop: '16px' }}>
                      <button className="button" type="button" onClick={() => downloadQr(selectedQr)}>
                        Download PNG
                      </button>
                      <a className="ghost-button" href={selectedQr.checkInUrl} target="_blank" rel="noreferrer">
                        Open pass link
                      </a>
                    </div>
                  </>
                ) : (
                  <div className="empty-state">
                    Pick a registrant to preview the QR image, token, and protected pass link.
                  </div>
                )}
              </aside>
            </div>
          </>
        )}
      </section>

      <section className="panel" style={{ marginTop: '24px' }}>
        <div className="section-header">
          <div>
            <h2>Playground onboarding assets</h2>
            <p className="muted">
              These come from the shared Redis workspace so agent owners can fetch the join docs and
              operators can recover issued playground credentials.
            </p>
          </div>
          {!adminLocked ? (
            <button className="ghost-button" type="button" onClick={loadPlayground}>
              {loadingPlayground ? 'Refreshing...' : 'Refresh playground data'}
            </button>
          ) : null}
        </div>

        {adminLocked ? (
          <div className="empty-state">
            Sign in as an admin to inspect the Redis-backed playground docs and agent keys.
          </div>
        ) : (
          <>
            <div className="stats-grid" style={{ marginBottom: '18px' }}>
              <div className="stat-card">
                <strong>{playgroundDocCount}</strong>
                <span>Join docs</span>
              </div>
              <div className="stat-card">
                <strong>{playgroundAgentCount}</strong>
                <span>Playground agents</span>
              </div>
            </div>

            <div className="users-list">
              {playgroundState.documents.length === 0 ? (
                <div className="empty-state" style={{ marginBottom: '18px' }}>
                  {loadingPlayground
                    ? 'Loading playground documents...'
                    : 'No playground markdown files were found in Redis yet.'}
                </div>
              ) : (
                playgroundState.documents.map((doc) => (
                  <article className="user-card" key={doc.name}>
                    <div className="user-card-header">
                      <div>
                        <strong>{doc.name}</strong>
                        <div className="muted">
                          {doc.public_url || 'Stored in Redis for the auth portal'}
                        </div>
                      </div>
                      <div className="action-row">
                        <button className="ghost-button" type="button" onClick={() => copyText(doc.content)}>
                          Copy markdown
                        </button>
                        {doc.public_url ? (
                          <a className="ghost-button" href={doc.public_url} target="_blank" rel="noreferrer">
                            Open public URL
                          </a>
                        ) : null}
                      </div>
                    </div>
                    <div className="meta-row muted" style={{ marginBottom: '12px' }}>
                      <span>Updated {formatDateTime(doc.updated_at)}</span>
                      <span>{doc.source || 'agent-playground'}</span>
                    </div>
                    <pre
                      className="mono"
                      style={{
                        margin: 0,
                        whiteSpace: 'pre-wrap',
                        background: 'rgba(15, 23, 42, 0.7)',
                        border: '1px solid rgba(148, 163, 184, 0.18)',
                        borderRadius: '14px',
                        padding: '16px',
                        maxHeight: '280px',
                        overflow: 'auto'
                      }}
                    >
                      {doc.content}
                    </pre>
                  </article>
                ))
              )}

              {playgroundState.agents.length === 0 ? (
                <div className="empty-state">
                  {loadingPlayground
                    ? 'Loading playground agent credentials...'
                    : 'No playground agent credentials have been published to Redis yet.'}
                </div>
              ) : (
                playgroundState.agents.map((agent) => (
                  <article className="user-card" key={agent.agent_id || agent.id}>
                    <div className="user-card-header">
                      <div>
                        <strong>{agent.name || agent.agent_id || agent.id}</strong>
                        <div className="muted">
                          {(agent.agent_id || agent.id) || 'unknown id'} | {agent.role || 'No role'}
                        </div>
                      </div>
                      <div className="status-row">
                        <span className={`role-badge ${agent.approved ? 'customer' : 'pending'}`}>
                          {agent.approved ? 'Approved' : 'Pending'}
                        </span>
                      </div>
                    </div>

                    <div className="meta-grid">
                      <div className="meta-item">
                        <span>Owner</span>
                        <div>{agent.owner_email || 'Unknown'}</div>
                      </div>
                      <div className="meta-item">
                        <span>Status</span>
                        <div>{agent.status || 'offline'}</div>
                      </div>
                      <div className="meta-item">
                        <span>Endpoint</span>
                        <div className="mono">{agent.endpoint_url || 'Polling-only / none'}</div>
                      </div>
                      <div className="meta-item">
                        <span>Created</span>
                        <div>{formatDateTime(agent.created_at)}</div>
                      </div>
                      <div className="meta-item" style={{ gridColumn: '1 / -1' }}>
                        <span>Agent secret</span>
                        <div className="mono" style={{ wordBreak: 'break-all' }}>
                          {agent.agent_secret || 'Not available'}
                        </div>
                      </div>
                    </div>

                    <div className="action-row" style={{ marginTop: '14px' }}>
                      <button className="ghost-button" type="button" onClick={() => copyText(agent.agent_secret)}>
                        Copy secret
                      </button>
                    </div>
                  </article>
                ))
              )}
            </div>
          </>
        )}
      </section>
      </>
      ) : null}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
