/* Users view */
function Users() {
  const s = useStore();
  const toast = useToast();
  const [modal, setModal] = useState(null);
  const [form, setForm] = useState({ name: "", displayName: "", email: "" });
  const [view, setView] = useState(() => localStorage.getItem("hs.uview") || "cards");
  useEffect(() => { localStorage.setItem("hs.uview", view); }, [view]);
  const rowFor = (u) => {
    const machines = s.machinesByUser(u.id);
    const online = machines.filter((m) => m.online).length;
    const keys = s.preauthKeys.filter((k) => String(k.user) === u.id).length;
    const methods = new Set(machines.map((m) => m.registerMethod));
    const provLabel = u.provider === "oidc" ? "OIDC" : methods.has(s.consts.RM.cli) ? "CLI" : methods.has(s.consts.RM.key) ? "Key" : "—";
    return { machines, online, keys, provLabel };
  };

  return (
    <div className="page fade-up">
      <div className="section-head">
        <div>
          <h2 style={{ fontSize: 19 }}>Users</h2>
          <div className="sub">{s.users.length} users · a user owns machines and pre-auth keys</div>
        </div>
        <div className="spacer" />
        <div className="seg" title="View">
          <button className={view === "cards" ? "on" : ""} onClick={() => setView("cards")} title="Cards"><Ic name="dashboard" size={14} /></button>
          <button className={view === "table" ? "on" : ""} onClick={() => setView("table")} title="Table"><Ic name="layers" size={14} /></button>
        </div>
        <RefreshBtn />
        <button className="btn primary" onClick={() => { setForm({ name: "", displayName: "", email: "" }); setModal("create"); }}><Ic name="plus" size={15} />Create user</button>
      </div>

      {view === "table" ? (
        <div className="tbl-wrap"><div className="tbl-scroll"><table className="tbl">
          <thead><tr><th>User</th><th>Machines</th><th>Keys</th><th>Provider</th><th>Joined</th><th>Email</th><th></th></tr></thead>
          <tbody>
            {s.users.map((u) => { const r = rowFor(u); return (
              <tr key={u.id} style={{ cursor: "default" }}>
                <td><div className="cell-main"><Avatar user={u} size={24} />{u.displayName}<span style={{ color: "var(--text-faint)", fontWeight: 400, fontFamily: "var(--font-mono)", fontSize: 11.5 }}>{u.name}</span></div></td>
                <td><span className="mono">{r.machines.length}</span> <span style={{ color: "var(--text-faint)", fontSize: 11.5 }}>({r.online} online)</span></td>
                <td className="mono">{r.keys}</td>
                <td><span className="badge">{r.provLabel}</span></td>
                <td style={{ color: "var(--text-dim)", fontSize: 12.5 }}>{absDate(u.createdAt)}</td>
                <td className="mono" style={{ fontSize: 11.5, color: "var(--text-faint)" }}>{u.email || "—"}</td>
                <td><div className="row-actions"><Menu trigger={<button className="btn icon sm ghost"><Ic name="dots" size={16} /></button>}>
                  <MenuItem icon="edit" onClick={() => { setForm({ id: u.id, name: u.name }); setModal("rename"); }}>Rename</MenuItem>
                  <div className="menu-sep" /><MenuItem icon="trash" danger onClick={() => setModal({ del: u })}>Delete user</MenuItem>
                </Menu></div></td>
              </tr>); })}
          </tbody>
        </table></div></div>
      ) : (
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))", gap: 14 }}>
        {s.users.map((u) => {
          const machines = s.machinesByUser(u.id);
          const online = machines.filter((m) => m.online).length;
          const keys = s.preauthKeys.filter((k) => String(k.user) === u.id).length;
          // provider from how this user's nodes registered (the real signal)
          const methods = new Set(machines.map((m) => m.registerMethod));
          const provLabel = u.provider === "oidc" ? "OIDC" : methods.has(s.consts.RM.cli) ? "CLI" : methods.has(s.consts.RM.key) ? "Key" : "—";
          return (
            <div key={u.id} className="card card-pad" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 11 }}>
                <Avatar user={u} size={42} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 600, fontSize: 14.5 }}>{u.displayName}</div>
                  <div style={{ fontSize: 12, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>{u.name} · id {u.id}</div>
                </div>
                <Menu trigger={<button className="btn icon sm ghost"><Ic name="dots" size={16} /></button>}>
                  <MenuItem icon="edit" onClick={() => { setForm({ id: u.id, name: u.name }); setModal("rename"); }}>Rename</MenuItem>
                  <MenuItem icon="key" onClick={() => toast.push({ kind: "info", title: "Create key", msg: "Go to Keys → Pre-auth" })}>New pre-auth key</MenuItem>
                  <div className="menu-sep" />
                  <MenuItem icon="trash" danger onClick={() => setModal({ del: u })}>Delete user</MenuItem>
                </Menu>
              </div>
              <div style={{ display: "flex", gap: 8 }}>
                <Mini label="Machines" value={machines.length} sub={`${online} online`} />
                <Mini label="Keys" value={keys} sub="pre-auth" />
                <Mini label="Provider" value={provLabel} sub="" small />
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 8, paddingTop: 12, borderTop: "1px solid var(--border)", fontSize: 12, color: "var(--text-faint)" }}>
                <Ic name="clock" size={13} />Joined {absDate(u.createdAt)}
                <div style={{ flex: 1 }} />
                <span className="mono" style={{ fontSize: 11 }}>{u.email || "no email"}</span>
              </div>
            </div>
          );
        })}
      </div>
      )}

      {modal === "create" && (
        <Modal title="Create user" subtitle="POST /api/v1/user" icon="users" onClose={() => setModal(null)}
          footer={<><div className="spacer" /><button className="btn" onClick={() => setModal(null)}>Cancel</button>
            <button className="btn primary" disabled={!form.name.trim()} onClick={() => { HS.act.addUser({ name: form.name.trim(), displayName: form.displayName.trim(), email: form.email.trim() }); toast.push({ kind: "success", title: "User created", msg: form.name }); setModal(null); }}>Create user</button></>}>
          <div className="field">
            <label>Username <span style={{ color: "var(--danger)" }}>*</span></label>
            <input className="input mono" autoFocus placeholder="e.g. dave" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value.replace(/[^a-z0-9-]/gi, "").toLowerCase() })} />
            <span className="hint">Required. Used in <span className="code-inline">node/register?user={form.name || "name"}</span>.</span>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <div className="field"><label>Display name</label><input className="input" placeholder="optional" value={form.displayName} onChange={(e) => setForm({ ...form, displayName: e.target.value })} /></div>
            <div className="field"><label>Email</label><input className="input" placeholder="optional" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} /></div>
          </div>
          <span className="hint">Display name and email are optional metadata — even non-OIDC users can carry them.</span>
        </Modal>
      )}

      {modal === "rename" && (
        <Modal title="Rename user" subtitle="POST /api/v1/user/{id}/rename/{newName}" icon="edit" onClose={() => setModal(null)}
          footer={<><div className="spacer" /><button className="btn" onClick={() => setModal(null)}>Cancel</button>
            <button className="btn primary" disabled={!form.name.trim()} onClick={() => { HS.act.renameUser(form.id, form.name.trim()); toast.push({ kind: "success", title: "User renamed", msg: form.name }); setModal(null); }}>Rename</button></>}>
          <div className="field"><label>Username</label><input className="input mono" autoFocus value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value.replace(/[^a-z0-9-]/gi, "").toLowerCase() })} /></div>
        </Modal>
      )}

      {modal?.del && (
        <ConfirmModal danger title={`Delete user ${modal.del.name}?`} subtitle="DELETE /api/v1/user/{id}" confirmLabel="Delete user"
          body={<div style={{ fontSize: 13.5, color: "var(--text-dim)", lineHeight: 1.55 }}>
            {s.machinesByUser(modal.del.id).length > 0
              ? <>This user still owns <b>{s.machinesByUser(modal.del.id).length} user-owned machine(s)</b>. Reassign or delete them first in a real deployment.</>
              : <>Removes the user and any associated pre-auth keys.</>}
          </div>}
          onConfirm={() => { HS.act.deleteUser(modal.del.id); toast.push({ kind: "success", title: "User deleted", msg: modal.del.name }); }}
          onClose={() => setModal(null)} />
      )}
    </div>
  );
}
function Mini({ label, value, sub, small }) {
  return (
    <div style={{ flex: 1, background: "var(--surface-2)", borderRadius: 8, padding: "9px 11px" }}>
      <div style={{ fontSize: small ? 14 : 20, fontWeight: 600, fontFamily: small ? "var(--font-sans)" : "var(--font-mono)", letterSpacing: "-0.01em" }}>{value}</div>
      <div style={{ fontSize: 11, color: "var(--text-faint)" }}>{label}{sub && " · " + sub}</div>
    </div>
  );
}
window.Users = Users;
