// Admin Allowlist Page — Council Phase 4b
// Owns: AdminAllowlistPage
// Manages the Firestore-backed allowlist of emails eligible for the admin claim.
// Pairs with Phase 4a backend endpoints exposed via window.adminApi:
//   - adminApi.listAdminAllowlist()
//   - adminApi.addAdminAllowlist({ email })
//   - adminApi.removeAdminAllowlist({ email })
// SAFETY: no raw HTML injection; all user strings render as {value} (auto-escaped by JSX).

const {
  Badge,
  ToastProvider, useToast,
  AdminStoreContext, adminApi,
  formatShortDate
} = window;

const { useState, useEffect, useRef } = React;

// Local copy of useOnMount (Babel script tags don't share scope cleanly).
function _useOnMountAllowlist(fn) {
  const ref = useRef(false);
  useEffect(() => {
    if (ref.current) return;
    ref.current = true;
    fn();
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
}

function AdminAllowlistPage() {
  const toast = useToast();
  const store = React.useContext(AdminStoreContext);

  const [entries, setEntries] = useState([]);
  const [loading, setLoading] = useState(true);

  const [addEmail, setAddEmail] = useState('');
  const [addBusy, setAddBusy] = useState(false);

  // Single shared in-flight guard for removals — only one removal at a time.
  const [removeBusy, setRemoveBusy] = useState('');

  async function loadList() {
    setLoading(true);
    try {
      const res = await adminApi.listAdminAllowlist();
      setEntries((res && res.entries) || []);
    } catch (e) {
      toast('Load failed: ' + (e.message || 'unknown error'), { icon: 'error' });
    } finally {
      setLoading(false);
    }
  }

  _useOnMountAllowlist(() => { loadList(); });

  async function submitAdd(e) {
    if (e && e.preventDefault) e.preventDefault();
    const email = (addEmail || '').trim().toLowerCase();
    if (!email) {
      toast('Enter an email address', { icon: 'error' });
      return;
    }
    setAddBusy(true);
    try {
      const res = await adminApi.addAdminAllowlist({ email });
      if (res && res.alreadyPresent) {
        toast(`${email} is already in the allowlist`, { icon: 'info' });
      } else {
        toast(`Added ${email}`, { icon: 'check' });
        try {
          store && store.logConfig && store.logConfig(
            'admin_allowlist_added',
            email,
            JSON.stringify({ email })
          );
        } catch (_) { /* logConfig is best-effort */ }
      }
      setAddEmail('');
      await loadList();
    } catch (err) {
      if (err && err.errorCode === 'INVALID_EMAIL') {
        toast(err.message || 'Invalid email address', { icon: 'error' });
      } else {
        toast('Add failed: ' + ((err && err.message) || 'unknown error'), { icon: 'error' });
      }
    } finally {
      setAddBusy(false);
    }
  }

  async function handleRemove(entry) {
    const email = (entry && entry.email) || '';
    if (!email) return;
    if (entry.isBootstrap) return; // defensive — button is hidden for bootstrap
    const ok = window.confirm(
      `Remove ${email} from the admin allowlist?\n\n` +
      `If they currently have admin access, it will be revoked immediately.`
    );
    if (!ok) return;
    setRemoveBusy(email);
    try {
      const res = await adminApi.removeAdminAllowlist({ email });
      const stripped = !!(res && res.claimStripped);
      toast(
        `Removed ${email}` + (stripped ? ' and revoked their admin claim' : ''),
        { icon: 'check' }
      );
      try {
        store && store.logConfig && store.logConfig(
          'admin_allowlist_removed',
          email,
          JSON.stringify({ email, claimStripped: stripped })
        );
      } catch (_) { /* best-effort */ }
      await loadList();
    } catch (err) {
      if (err && err.errorCode === 'SUPER_ADMIN_PROTECTED') {
        toast('Cannot remove super-admin — bootstrap protection.', { icon: 'error' });
      } else {
        toast('Remove failed: ' + ((err && err.message) || 'unknown error'), { icon: 'error' });
      }
    } finally {
      setRemoveBusy('');
    }
  }

  const muted = 'var(--md-sys-color-on-surface-variant)';
  const errorColor = 'var(--md-sys-color-error)';

  return (
    <div className="page">
      <div className="card">
        <h1 style={{ margin: '0 0 8px 0' }}>Admin Allowlist</h1>
        <p style={{ color: muted, margin: '0 0 16px 0', maxWidth: 720 }}>
          These emails are eligible to be promoted to admin. Add a row here
          BEFORE clicking "Invite as Admin" or "Promote to Admin" on the Roster
          page. <strong>brian@bmrkllc.com</strong> is hardcoded as super-admin
          and cannot be removed.
        </p>

        <form
          onSubmit={submitAdd}
          style={{
            display: 'flex',
            gap: 8,
            alignItems: 'center',
            marginBottom: 16,
            flexWrap: 'wrap'
          }}
        >
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, flex: '1 1 320px' }}>
            <span style={{ fontSize: 13, color: muted }}>Add email:</span>
            <input
              type="email"
              value={addEmail}
              onChange={(e) => setAddEmail(e.target.value)}
              placeholder="email@example.com"
              autoComplete="off"
              disabled={addBusy}
              style={{ flex: 1, minWidth: 220, padding: '6px 10px' }}
            />
          </label>
          <button
            type="submit"
            className="btn btn-filled btn-sm"
            disabled={addBusy || !addEmail.trim()}
          >
            {addBusy ? 'Adding…' : 'Add'}
          </button>
        </form>

        {loading ? (
          <div style={{ padding: '24px 0', color: muted }}>Loading…</div>
        ) : entries.length === 0 ? (
          <div style={{ padding: '24px 0', color: muted }}>No admins in allowlist.</div>
        ) : (
          <table className="data-table" style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead>
              <tr>
                <th style={{ textAlign: 'left', padding: '8px 12px', borderBottom: '1px solid var(--md-sys-color-outline-variant)' }}>Email</th>
                <th style={{ textAlign: 'left', padding: '8px 12px', borderBottom: '1px solid var(--md-sys-color-outline-variant)', width: 160 }}>Added</th>
                <th style={{ textAlign: 'left', padding: '8px 12px', borderBottom: '1px solid var(--md-sys-color-outline-variant)', width: 220 }}>Action</th>
              </tr>
            </thead>
            <tbody>
              {entries.map((entry) => {
                const email = (entry && entry.email) || '';
                const addedAtRaw = entry && entry.addedAt;
                const addedAtShort = addedAtRaw
                  ? formatShortDate(String(addedAtRaw).slice(0, 10))
                  : '—';
                const addedByEmail = (entry && entry.addedByEmail) || '';
                const isBootstrap = !!(entry && entry.isBootstrap);
                const rowBusy = removeBusy && removeBusy !== email;
                const myBusy = removeBusy === email;

                return (
                  <tr key={email}>
                    <td style={{ padding: '8px 12px', borderBottom: '1px solid var(--md-sys-color-outline-variant)' }}>
                      <span style={{ marginRight: 8 }}>{email}</span>
                      {isBootstrap && (
                        <Badge tone="info">👑 super-admin</Badge>
                      )}
                    </td>
                    <td style={{ padding: '8px 12px', borderBottom: '1px solid var(--md-sys-color-outline-variant)', color: muted, fontSize: 13 }}>
                      {isBootstrap ? '—' : addedAtShort}
                      {!isBootstrap && addedByEmail ? (
                        <div style={{ fontSize: 11, color: muted, marginTop: 2 }}>
                          by {addedByEmail}
                        </div>
                      ) : null}
                    </td>
                    <td style={{ padding: '8px 12px', borderBottom: '1px solid var(--md-sys-color-outline-variant)' }}>
                      {isBootstrap ? (
                        <span style={{
                          fontSize: 11,
                          fontStyle: 'italic',
                          color: muted
                        }}>
                          super-admin · bootstrap
                        </span>
                      ) : (
                        <button
                          className="btn btn-text btn-sm"
                          style={{ color: errorColor }}
                          onClick={() => handleRemove(entry)}
                          disabled={!!removeBusy}
                          title={rowBusy ? 'Another removal is in-flight' : `Remove ${email} from allowlist`}
                        >
                          {myBusy ? 'Removing…' : 'Remove'}
                        </button>
                      )}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { AdminAllowlistPage });
