// ============================================================================
// Users management page (PR-S.17c · admin-only)
// ============================================================================
//
// Admin-only:列所有 user,提供 role toggle(is_admin)跟 ban/unban 按钮。
// 进入流程:
//   1. mount → GET /v1/auth/me 拿 is_admin
//      · 非 admin → 渲染 "Forbidden — 需要 admin 权限" 占位 + 5s 后跳回 /playground
//      · is_admin=true → 进真页
//   2. GET /v1/users 拉表
//   3. 每行 actions:
//      · Toggle admin: PATCH /v1/users/{id} { is_admin: !current }
//      · Ban / Unban:  PATCH /v1/users/{id} { status: 'banned' | 'active' }
//   4. Self-row 标 "(you)",所有 action 钮 disabled —— backend 也 enforce
//      self_modification_blocked 422,前端先挡免得 round-trip
//
// 设计跟 manage-app.jsx 视觉对齐(topbar + brand + tabs),不用单独 css。

const { useState, useEffect } = React;

function UsersApp() {
  const [me, setMe] = useState(null);          // null = loading; obj = loaded
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [busyUserId, setBusyUserId] = useState(null); // 防双击,行级 disable

  // Step 1: load /v1/auth/me first to gate
  useEffect(() => {
    (async () => {
      try {
        const m = await window.api.authMe();
        setMe(m);
      } catch (err) {
        setError(`auth check failed: ${err.message || err}`);
        setLoading(false);
      }
    })();
  }, []);

  // Step 2: 拿到 me 之后才拉 users(否则 admin 才 fetch,避免给 non-admin 一次 403)
  useEffect(() => {
    if (!me || !me.is_admin) {
      setLoading(false);
      return;
    }
    (async () => {
      try {
        const items = await window.api.listUsers();
        setUsers(items);
      } catch (err) {
        setError(`load users failed: ${err.message || err}`);
      } finally {
        setLoading(false);
      }
    })();
  }, [me]);

  async function patchUser(userId, patch) {
    setBusyUserId(userId);
    try {
      const updated = await window.api.updateUser(userId, patch);
      // 用 updated 替换该行,保证 UI 跟后端同步
      setUsers((prev) =>
        prev.map((u) => (u.user_id === userId ? { ...u, ...updated } : u))
      );
    } catch (err) {
      alert(`update failed: ${err.message || err}`);
    } finally {
      setBusyUserId(null);
    }
  }

  // -------- 非 admin / loading / error 占位 --------

  if (loading) {
    return (
      <div className="app">
        <Topbar isAdmin={false} />
        <div style={{ padding: 32, color: "var(--text-muted)" }}>Loading…</div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="app">
        <Topbar isAdmin={false} />
        <div style={{ padding: 32, color: "#b91c1c" }}>{error}</div>
      </div>
    );
  }

  if (!me || !me.is_admin) {
    // 非 admin 用 admin-only 链接进来 → 友好拒绝。不自动跳转 —— 之前用
    // setTimeout 在 render 里调会 every-render schedule 一个新 timer
    // (React 反模式;也让用户看不清自己被识别成哪个 user)。改成显式
    // 显示当前 user_id + 提供按钮:Go to Playground / Sign out。这样用户
    // 能一眼看出"被认成哪个 user 所以非 admin",自决定下一步。
    return (
      <div className="app">
        <Topbar isAdmin={false} />
        <div style={{
          padding: 32, maxWidth: 520, margin: "60px auto", textAlign: "center",
        }}>
          <h2 style={{ marginTop: 0 }}>Forbidden</h2>
          <p style={{ color: "var(--text-muted)" }}>
            This page is admin-only.
          </p>
          {me && (
            <p style={{ color: "var(--text-faint)", fontSize: 12, fontFamily: "var(--font-mono)" }}>
              you are signed in as <strong>{me.user_id}</strong>
              {me.is_admin ? "" : " (not admin)"}
            </p>
          )}
          <div style={{ marginTop: 18, display: "flex", gap: 8, justifyContent: "center" }}>
            <a className="btn ghost sm" href="/playground">Go to Playground</a>
            <button
              className="btn sm"
              onClick={() => {
                try {
                  localStorage.removeItem("baizhi.auth.token");
                  localStorage.removeItem("baizhi.auth.user_id");
                  localStorage.removeItem("baizhi.auth.email");
                } catch (e) {}
                location.replace("/login");
              }}
            >
              Sign out & switch user
            </button>
          </div>
        </div>
      </div>
    );
  }

  // -------- admin: 正式 UI --------

  return (
    <div className="app">
      <Topbar isAdmin={true} />
      <div style={{ padding: "20px 28px" }}>
        <h2 style={{ margin: "0 0 6px", fontSize: 18 }}>Users</h2>
        <p style={{
          margin: "0 0 18px", fontSize: 12.5, color: "var(--text-muted)",
        }}>
          {users.length} registered. Toggle admin role or ban/unban below.
          You can't modify your own row — ask another admin.
        </p>

        <div style={{
          border: "1px solid var(--border)", borderRadius: 8,
          background: "var(--bg)", overflowX: "auto",
        }}>
          <table style={{
            width: "100%", borderCollapse: "collapse", fontSize: 13,
          }}>
            <thead>
              <tr style={{ background: "var(--bg-subtle)" }}>
                <Th>Email</Th>
                <Th>User ID</Th>
                <Th>Created</Th>
                <Th align="center">Role</Th>
                <Th align="center">Status</Th>
                <Th align="right">Actions</Th>
              </tr>
            </thead>
            <tbody>
              {users.map((u) => {
                const isSelf = u.user_id === me.user_id;
                const isBusy = busyUserId === u.user_id;
                const banned = u.status === "banned";
                return (
                  <tr key={u.user_id} style={{
                    borderTop: "1px solid var(--border)",
                    opacity: banned ? 0.62 : 1,
                  }}>
                    <Td>
                      {u.email}
                      {isSelf && (
                        <span style={selfPillStyle}>you</span>
                      )}
                    </Td>
                    <Td mono small muted>{u.user_id}</Td>
                    <Td muted small>
                      {u.created_at
                        ? new Date(u.created_at * 1000).toLocaleString()
                        : "—"}
                    </Td>
                    <Td align="center">
                      <RoleBadge isAdmin={u.is_admin} />
                    </Td>
                    <Td align="center">
                      <StatusBadge status={u.status} />
                    </Td>
                    <Td align="right">
                      <button
                        className="btn ghost sm"
                        disabled={isSelf || isBusy}
                        title={isSelf
                          ? "Can't change your own role — ask another admin"
                          : (u.is_admin
                              ? "Demote to regular user"
                              : "Promote to admin")}
                        onClick={() =>
                          patchUser(u.user_id, { is_admin: !u.is_admin })
                        }
                        style={{ marginRight: 6 }}
                      >
                        {u.is_admin ? "Demote" : "Make admin"}
                      </button>
                      <button
                        className={"btn sm" + (banned ? "" : " danger")}
                        disabled={isSelf || isBusy}
                        title={isSelf
                          ? "Can't ban yourself"
                          : (banned ? "Restore account" : "Ban this user")}
                        onClick={() => patchUser(u.user_id, {
                          status: banned ? "active" : "banned",
                        })}
                      >
                        {banned ? "Unban" : "Ban"}
                      </button>
                    </Td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

function Topbar({ isAdmin }) {
  return (
    <div className="topbar">
      <div className="brand">
        <div className="dot">百</div>
        baizhi
        <span style={{ color: "var(--text-faint)" }}>/</span>
        <span style={{ fontWeight: 500, color: "var(--text-muted)" }}>Users</span>
      </div>
      <div className="tabs">
        <a href="/playground" style={tabLink}>Playground</a>
        <a href="/manage" style={tabLink}>Manage</a>
        <a href="/evals" style={tabLink}>Evals</a>
        <a href="/traces" style={tabLink}>Traces</a>
        <a href="/marketplace" style={tabLink}>Marketplace</a>
        <a href="/apps" style={tabLink}>Apps</a>
        {isAdmin && <button className="active">Users</button>}
        <a href="/api-docs" style={tabLink}>API&nbsp;Docs</a>
      </div>
      <div className="spacer" />
    </div>
  );
}

function Th({ children, align = "left" }) {
  return (
    <th style={{
      padding: "10px 14px", textAlign: align, fontWeight: 500,
      fontSize: 12, color: "var(--text-muted)",
      textTransform: "uppercase", letterSpacing: 0.3,
    }}>{children}</th>
  );
}

function Td({ children, align = "left", mono, small, muted }) {
  return (
    <td style={{
      padding: "10px 14px", textAlign: align,
      fontSize: small ? 12 : 13,
      color: muted ? "var(--text-muted)" : "var(--text)",
      fontFamily: mono ? "var(--font-mono)" : "inherit",
      verticalAlign: "middle",
    }}>{children}</td>
  );
}

function RoleBadge({ isAdmin }) {
  return (
    <span style={{
      display: "inline-block", padding: "2px 8px", borderRadius: 4,
      fontSize: 11, letterSpacing: 0.3, fontWeight: 500,
      background: isAdmin ? "var(--accent-bg)" : "var(--bg-subtle)",
      color: isAdmin ? "var(--accent)" : "var(--text-muted)",
    }}>{isAdmin ? "admin" : "user"}</span>
  );
}

function StatusBadge({ status }) {
  const banned = status === "banned";
  return (
    <span style={{
      display: "inline-block", padding: "2px 8px", borderRadius: 4,
      fontSize: 11, letterSpacing: 0.3, fontWeight: 500,
      background: banned ? "#fef2f2" : "var(--bg-subtle)",
      color: banned ? "#b91c1c" : "var(--text-muted)",
      border: banned ? "1px solid #fecaca" : "1px solid var(--border)",
    }}>{status}</span>
  );
}

const tabLink = {
  background: "transparent", border: 0, padding: "6px 10px", borderRadius: 6,
  color: "var(--text-muted)", fontSize: 13, textDecoration: "none",
};

const selfPillStyle = {
  marginLeft: 8, padding: "1px 6px", borderRadius: 3,
  background: "var(--accent-bg)", color: "var(--accent)",
  fontSize: 10, letterSpacing: 0.3,
  fontFamily: "var(--font-sans)",
};

ReactDOM.createRoot(document.getElementById("root")).render(<UsersApp />);
