// Slide-out drawer for editing an existing endpoint.
// Reuses the NodeDetail drawer chrome (.drawer / .drawer-head / .drawer-body
// / .drawer-actions) so the admin edit flow looks identical to the click-on-
// a-node flow.

const INPUT_STYLE = {
  width: '100%', padding: '6px 10px', background: 'var(--surface)',
  border: '1px solid var(--border-2)', borderRadius: 2,
  color: 'var(--text)', fontFamily: 'var(--mono)', fontSize: 12, outline: 'none',
};

function AdminEditor({ server, groups, onClose, onSaved }) {
  const open = !!server;
  // Keep local form state separate so mid-edit typing doesn't fight polling.
  const [url, setUrl] = React.useState('');
  const [group, setGroup] = React.useState('');
  const [customGroup, setCustomGroup] = React.useState(false);
  const [probePath, setProbePath] = React.useState('');
  const [okCodes, setOkCodes] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);

  React.useEffect(() => {
    if (!server) return;
    setUrl(server.url || '');
    setGroup(server.group || '');
    setCustomGroup(false);
    setProbePath(server.probePath || '');
    setOkCodes(Array.isArray(server.okCodes) ? server.okCodes.join(', ') : '');
    setErr(null);
  }, [server?.id]);

  if (!open) return <div className="drawer" />;

  function parseOkCodes(raw) {
    const xs = raw.split(/[,\s]+/).map(s => s.trim()).filter(Boolean);
    const out = [];
    for (const x of xs) {
      const n = Number(x);
      if (!Number.isFinite(n)) throw new Error(`okCodes: "${x}" is not a number`);
      out.push(Math.floor(n));
    }
    return out;
  }

  async function save() {
    setErr(null); setBusy(true);
    try {
      const patch = { group: group.trim() };
      if (probePath.trim()) patch.probePath = probePath.trim();
      else patch.probePath = null;  // explicit drop
      if (okCodes.trim()) patch.okCodes = parseOkCodes(okCodes);
      else patch.okCodes = null;
      const updated = await window.adminFetch(`/api/admin/servers/${server.id}`, {
        method: 'PATCH', body: JSON.stringify(patch),
      });
      onSaved(updated);
    } catch (e) {
      setErr(e.message || 'save failed');
    } finally { setBusy(false); }
  }

  const groupOpts = Array.from(new Set([...(groups || []), group])).filter(Boolean);

  return (
    <div className="drawer open">
      <div className="drawer-head">
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="drawer-title">Edit endpoint</div>
          <div className="drawer-sub">{server.id} · {server.url}</div>
        </div>
        <button className="close" onClick={onClose}>×</button>
      </div>
      <div className="drawer-body">
        <div className="tweak-row">
          <label>URL (read-only)</label>
          <input style={{ ...INPUT_STYLE, opacity: 0.6 }} value={url} readOnly />
        </div>
        <div className="tweak-row">
          <label>Group</label>
          {customGroup ? (
            <div style={{ display: 'flex', gap: 6 }}>
              <input style={INPUT_STYLE} value={group} onChange={e => setGroup(e.target.value)}
                     autoFocus placeholder="new group name" />
              <button className="btn" onClick={() => { setCustomGroup(false); setGroup(server.group || ''); }}>back</button>
            </div>
          ) : (
            <div style={{ display: 'flex', gap: 6 }}>
              <select style={INPUT_STYLE} value={group} onChange={e => {
                if (e.target.value === '__new__') { setCustomGroup(true); setGroup(''); }
                else setGroup(e.target.value);
              }}>
                {groupOpts.map(g => <option key={g} value={g}>{g}</option>)}
                <option value="__new__">+ new group…</option>
              </select>
            </div>
          )}
        </div>
        <div className="tweak-row">
          <label>Probe path <span style={{ textTransform: 'none', color: 'var(--text-mute)' }}>(optional, e.g. /health)</span></label>
          <input style={INPUT_STYLE} value={probePath} onChange={e => setProbePath(e.target.value)}
                 placeholder={`default: ${server.path || '/'}`} />
        </div>
        <div className="tweak-row">
          <label>ok codes <span style={{ textTransform: 'none', color: 'var(--text-mute)' }}>(csv, e.g. 401, 403, 404)</span></label>
          <input style={INPUT_STYLE} value={okCodes} onChange={e => setOkCodes(e.target.value)}
                 placeholder="200-range is always ok" />
          <div style={{ fontSize: 10, color: 'var(--text-mute)', marginTop: 4 }}>
            HTTP codes that should be treated as healthy. Useful for auth-gated
            endpoints (401/403) or API roots that 404 but are alive.
          </div>
        </div>
        {err && <div style={{ color: 'var(--crit)', fontSize: 11 }}>{err}</div>}
      </div>
      <div className="drawer-actions" style={{ gridTemplateColumns: '1fr 1fr' }}>
        <button className="action-btn" onClick={onClose} disabled={busy}>cancel</button>
        <button className="action-btn" onClick={save} disabled={busy || !group.trim()}
          style={{ color: 'var(--accent)', borderColor: 'var(--accent-dim)', background: 'var(--accent-bg)' }}>
          {busy ? 'saving…' : 'save'}
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { AdminEditor });
