// Solo staff admin area — Phase 0: login + the pending-approvals queue.
//
// Deliberately not linked from the public nav — reached via /admin (see
// the pathname check in app.jsx's initial page state). No public admin
// signup route exists anywhere; accounts are created with
// scripts/seed-admin.mjs only (see src/routes/admin.ts).
//
// Reuses FieldBlock / DarkInput / LiveDot / CornerHairlines from
// reseller-login-page.jsx, and AdminShell (the shared sidebar-nav +
// page-header wrapper every admin page renders inside — see
// admin-shell.jsx) — both loaded earlier, see index.html.

function AdminLoginPage({ onNavigate }) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [showPassword, setShowPassword] = useState(false);
  const [status, setStatus] = useState("checking-session");
  const [error, setError] = useState("");

  useEffect(() => {
    let cancelled = false;
    fetch("/api/admin/me", { credentials: "same-origin" })
      .then((r) => (r.ok ? r.json() : null))
      .then((data) => {
        if (cancelled) return;
        if (data?.admin) onNavigate("admin-approvals");
        else setStatus("idle");
      })
      .catch(() => { if (!cancelled) setStatus("idle"); });
    return () => { cancelled = true; };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  const canSubmit = email.trim() && password.trim() && status !== "submitting";

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    setStatus("submitting");
    setError("");
    try {
      const res = await fetch("/api/admin/login", {
        method: "POST",
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: email.trim(), password }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setError(data.error || "Something went wrong. Please try again.");
        setStatus("idle");
        return;
      }
      onNavigate("admin-approvals");
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
      setStatus("idle");
    }
  };

  if (status === "checking-session") {
    return <section style={{ background: "#fff", minHeight: "calc(100vh - 88px)" }} />;
  }

  return (
    <section style={{
      background: "#fff", color: "#000", minHeight: "calc(100vh - 88px)",
      padding: "80px 36px 120px",
      display: "flex", alignItems: "center", justifyContent: "center",
      position: "relative",
    }}>
      <CornerHairlines />
      <div style={{ width: "100%", maxWidth: 440, position: "relative", zIndex: 2 }}>
        <div style={{
          display: "flex", alignItems: "center", gap: 10,
          fontFamily: "var(--font-body)", fontSize: 10,
          letterSpacing: "0.32em", textTransform: "uppercase",
          color: "rgba(180,110,0,0.95)", fontWeight: 500, marginBottom: 32,
        }}>
          <LiveDot />
          <span>Staff only · internal system</span>
        </div>

        <h1 style={{
          fontFamily: "var(--font-display)", fontWeight: 700,
          fontSize: "clamp(32px, 5vw, 48px)", lineHeight: 1,
          letterSpacing: "-0.005em", textTransform: "uppercase",
          margin: "0 0 18px", color: "#000",
        }}>
          Admin sign in.
        </h1>

        <form onSubmit={handleSubmit} style={{
          background: "rgba(0,0,0,0.03)",
          border: "1px solid rgba(0,0,0,0.16)",
          backdropFilter: "blur(6px)",
          padding: "32px",
        }}>
          {error && (
            <div style={{
              background: "rgba(190,40,40,0.08)",
              border: "1px solid rgba(190,40,40,0.35)",
              color: "#8a1f1f", padding: "14px 16px", marginBottom: 22,
              fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.5,
            }}>
              {error}
            </div>
          )}
          <FieldBlock label="Email">
            <DarkInput
              type="email" autoComplete="username" required
              value={email} onChange={(e) => setEmail(e.target.value)}
            />
          </FieldBlock>
          <FieldBlock label="Password" right={
            <button type="button" onClick={() => setShowPassword((v) => !v)} style={{
              background: "none", border: "none", cursor: "pointer", padding: 0,
              fontFamily: "var(--font-body)", fontSize: 10,
              letterSpacing: "0.22em", textTransform: "uppercase",
              color: "rgba(0,0,0,0.6)", fontWeight: 500,
            }}>{showPassword ? "Hide" : "Show"}</button>
          }>
            <DarkInput
              type={showPassword ? "text" : "password"}
              autoComplete="current-password" required
              value={password} onChange={(e) => setPassword(e.target.value)}
            />
          </FieldBlock>
          <button
            type="submit" disabled={!canSubmit}
            style={{
              width: "100%", marginTop: 12,
              background: canSubmit ? "#000" : "rgba(0,0,0,0.15)",
              color: canSubmit ? "#fff" : "rgba(0,0,0,0.5)",
              border: `1px solid ${canSubmit ? "#000" : "rgba(0,0,0,0.15)"}`,
              padding: "18px 22px",
              cursor: canSubmit ? "pointer" : "not-allowed",
              fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
              letterSpacing: "0.22em", textTransform: "uppercase",
              transition: "background 140ms, color 140ms",
            }}>
            {status === "submitting" ? "Signing in…" : "Sign in →"}
          </button>

          <div style={{
            marginTop: 24, paddingTop: 22,
            borderTop: "1px solid rgba(0,0,0,0.12)",
            textAlign: "center",
            fontFamily: "var(--font-body)", fontSize: 12,
            letterSpacing: "0.14em", textTransform: "uppercase",
          }}>
            <button
              type="button"
              onClick={() => onNavigate("admin-forgot-password")}
              style={{
                background: "none", border: "none", padding: 0,
                cursor: "pointer",
                fontFamily: "inherit", fontSize: "inherit", letterSpacing: "inherit",
                color: "rgba(0,0,0,0.7)",
                textDecoration: "underline",
                textDecorationColor: "rgba(0,0,0,0.3)",
                textUnderlineOffset: 4,
              }}>Forgot password?</button>
          </div>
        </form>
      </div>
    </section>
  );
}

/* ──────────── Forgot password (request link) ──────────── */
// Same generic "if that email exists, we've sent a link" flow as the
// reseller portal's equivalent (see reseller-login-page.jsx) — never
// reveals whether an email matches a staff account.
function AdminForgotPasswordPage({ onNavigate }) {
  const [email, setEmail] = useState("");
  const [status, setStatus] = useState("idle"); // idle → submitting → sent
  const [error, setError] = useState("");

  const canSubmit = email.trim() && status !== "submitting";

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    setStatus("submitting");
    setError("");
    try {
      const res = await fetch("/api/admin/forgot-password", {
        method: "POST",
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: email.trim() }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setError(data.error || "Something went wrong. Please try again.");
        setStatus("idle");
        return;
      }
      setStatus("sent");
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
      setStatus("idle");
    }
  };

  return (
    <section style={{
      background: "#fff", color: "#000", minHeight: "calc(100vh - 88px)",
      padding: "80px 36px 120px",
      display: "flex", alignItems: "center", justifyContent: "center",
      position: "relative",
    }}>
      <CornerHairlines />
      <div style={{ width: "100%", maxWidth: 440, position: "relative", zIndex: 2 }}>
        <div style={{
          display: "flex", alignItems: "center", gap: 10,
          fontFamily: "var(--font-body)", fontSize: 10,
          letterSpacing: "0.32em", textTransform: "uppercase",
          color: "rgba(180,110,0,0.95)", fontWeight: 500, marginBottom: 32,
        }}>
          <LiveDot />
          <span>Staff only · internal system</span>
        </div>

        <h1 style={{
          fontFamily: "var(--font-display)", fontWeight: 700,
          fontSize: "clamp(32px, 5vw, 48px)", lineHeight: 1,
          letterSpacing: "-0.005em", textTransform: "uppercase",
          margin: "0 0 18px", color: "#000",
        }}>
          Reset staff password.
        </h1>

        {status === "sent" ? (
          <div style={{
            background: "rgba(0,0,0,0.03)",
            border: "1px solid rgba(0,0,0,0.16)",
            padding: "32px",
          }}>
            <p style={{
              fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.6,
              color: "rgba(0,0,0,0.85)", margin: "0 0 24px",
            }}>
              If <strong>{email.trim()}</strong> matches a staff account, we've sent a password reset link to it.
              The link expires in 45 minutes.
            </p>
            <button
              type="button"
              onClick={() => onNavigate("admin-login")}
              style={{
                background: "#000", color: "#fff", border: "1px solid #000",
                padding: "16px 22px", cursor: "pointer",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
              }}>Back to sign in →</button>
          </div>
        ) : (
          <form onSubmit={handleSubmit} style={{
            background: "rgba(0,0,0,0.03)",
            border: "1px solid rgba(0,0,0,0.16)",
            backdropFilter: "blur(6px)",
            padding: "32px",
          }}>
            {error && (
              <div style={{
                background: "rgba(190,40,40,0.08)",
                border: "1px solid rgba(190,40,40,0.35)",
                color: "#8a1f1f", padding: "14px 16px", marginBottom: 22,
                fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.5,
              }}>
                {error}
              </div>
            )}
            <FieldBlock label="Email">
              <DarkInput
                type="email" autoComplete="username" required
                value={email} onChange={(e) => setEmail(e.target.value)}
              />
            </FieldBlock>
            <button
              type="submit"
              disabled={!canSubmit}
              style={{
                width: "100%", marginTop: 12,
                background: canSubmit ? "#000" : "rgba(0,0,0,0.15)",
                color: canSubmit ? "#fff" : "rgba(0,0,0,0.5)",
                border: `1px solid ${canSubmit ? "#000" : "rgba(0,0,0,0.15)"}`,
                padding: "18px 22px",
                cursor: canSubmit ? "pointer" : "not-allowed",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
                transition: "background 140ms, color 140ms",
              }}>
              {status === "submitting" ? "Sending…" : "Send reset link →"}
            </button>

            <div style={{
              marginTop: 24, paddingTop: 22,
              borderTop: "1px solid rgba(0,0,0,0.12)",
              textAlign: "center",
              fontFamily: "var(--font-body)", fontSize: 12,
              letterSpacing: "0.14em", textTransform: "uppercase",
            }}>
              <button
                type="button"
                onClick={() => onNavigate("admin-login")}
                style={{
                  background: "none", border: "none", padding: 0,
                  cursor: "pointer",
                  fontFamily: "inherit", fontSize: "inherit", letterSpacing: "inherit",
                  color: "rgba(0,0,0,0.7)",
                  textDecoration: "underline",
                  textDecorationColor: "rgba(0,0,0,0.3)",
                  textUnderlineOffset: 4,
                }}>← Back to sign in</button>
            </div>
          </form>
        )}
      </div>
    </section>
  );
}

/* ──────────── Reset password (with token from emailed link) ──────────── */
function AdminResetPasswordPage({ onNavigate, token }) {
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [showPassword, setShowPassword] = useState(false);
  const [status, setStatus] = useState("idle"); // idle → submitting → done
  const [error, setError] = useState("");

  const canSubmit = token && password.length >= 10 && password === confirmPassword && status !== "submitting";

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!canSubmit) return;
    setStatus("submitting");
    setError("");
    try {
      const res = await fetch("/api/admin/reset-password", {
        method: "POST",
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ token, password }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setError(data.error || "Something went wrong. Please try again.");
        setStatus("idle");
        return;
      }
      setStatus("done");
    } catch {
      setError("Couldn't reach the server. Check your connection and try again.");
      setStatus("idle");
    }
  };

  return (
    <section style={{
      background: "#fff", color: "#000", minHeight: "calc(100vh - 88px)",
      padding: "80px 36px 120px",
      display: "flex", alignItems: "center", justifyContent: "center",
      position: "relative",
    }}>
      <CornerHairlines />
      <div style={{ width: "100%", maxWidth: 440, position: "relative", zIndex: 2 }}>
        <div style={{
          display: "flex", alignItems: "center", gap: 10,
          fontFamily: "var(--font-body)", fontSize: 10,
          letterSpacing: "0.32em", textTransform: "uppercase",
          color: "rgba(180,110,0,0.95)", fontWeight: 500, marginBottom: 32,
        }}>
          <LiveDot />
          <span>Staff only · internal system</span>
        </div>

        <h1 style={{
          fontFamily: "var(--font-display)", fontWeight: 700,
          fontSize: "clamp(32px, 5vw, 48px)", lineHeight: 1,
          letterSpacing: "-0.005em", textTransform: "uppercase",
          margin: "0 0 18px", color: "#000",
        }}>
          Set a new password.
        </h1>

        {!token ? (
          <div style={{
            background: "rgba(0,0,0,0.03)",
            border: "1px solid rgba(0,0,0,0.16)",
            padding: "32px",
          }}>
            <p style={{
              fontFamily: "var(--font-body)", fontSize: 14.5, lineHeight: 1.6,
              color: "rgba(0,0,0,0.7)", margin: "0 0 24px",
            }}>
              This page is only reachable via the link in a password reset email.
            </p>
            <button
              type="button"
              onClick={() => onNavigate("admin-forgot-password")}
              style={{
                background: "#000", color: "#fff", border: "1px solid #000",
                padding: "16px 22px", cursor: "pointer",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
              }}>Request a reset link →</button>
          </div>
        ) : status === "done" ? (
          <div style={{
            background: "rgba(0,0,0,0.03)",
            border: "1px solid rgba(0,0,0,0.16)",
            padding: "32px",
          }}>
            <p style={{
              fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.6,
              color: "rgba(0,0,0,0.85)", margin: "0 0 24px",
            }}>
              Your password has been reset. You're signed out on every device — sign in below with your new password.
            </p>
            <button
              type="button"
              onClick={() => onNavigate("admin-login")}
              style={{
                background: "#000", color: "#fff", border: "1px solid #000",
                padding: "16px 22px", cursor: "pointer",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
              }}>Sign in →</button>
          </div>
        ) : (
          <form onSubmit={handleSubmit} style={{
            background: "rgba(0,0,0,0.03)",
            border: "1px solid rgba(0,0,0,0.16)",
            backdropFilter: "blur(6px)",
            padding: "32px",
          }}>
            {error && (
              <div style={{
                background: "rgba(190,40,40,0.08)",
                border: "1px solid rgba(190,40,40,0.35)",
                color: "#8a1f1f", padding: "14px 16px", marginBottom: 22,
                fontFamily: "var(--font-body)", fontSize: 13.5, lineHeight: 1.5,
              }}>
                {error}
              </div>
            )}
            <FieldBlock label="New password" right={
              <button type="button" onClick={() => setShowPassword((v) => !v)} style={{
                background: "none", border: "none", cursor: "pointer", padding: 0,
                fontFamily: "var(--font-body)", fontSize: 10,
                letterSpacing: "0.22em", textTransform: "uppercase",
                color: "rgba(0,0,0,0.6)", fontWeight: 500,
              }}>{showPassword ? "Hide" : "Show"}</button>
            } hint="At least 10 characters.">
              <DarkInput
                type={showPassword ? "text" : "password"}
                autoComplete="new-password" required
                value={password} onChange={(e) => setPassword(e.target.value)}
              />
            </FieldBlock>
            <FieldBlock label="Confirm new password">
              <DarkInput
                type={showPassword ? "text" : "password"}
                autoComplete="new-password" required
                value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)}
              />
            </FieldBlock>
            {password && confirmPassword && password !== confirmPassword && (
              <div style={{
                fontFamily: "var(--font-body)", fontSize: 12.5,
                color: "#8a1f1f", margin: "-10px 0 22px",
              }}>Passwords don't match.</div>
            )}
            <button
              type="submit" disabled={!canSubmit}
              style={{
                width: "100%", marginTop: 12,
                background: canSubmit ? "#000" : "rgba(0,0,0,0.15)",
                color: canSubmit ? "#fff" : "rgba(0,0,0,0.5)",
                border: `1px solid ${canSubmit ? "#000" : "rgba(0,0,0,0.15)"}`,
                padding: "18px 22px",
                cursor: canSubmit ? "pointer" : "not-allowed",
                fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 500,
                letterSpacing: "0.22em", textTransform: "uppercase",
                transition: "background 140ms, color 140ms",
              }}>
              {status === "submitting" ? "Resetting…" : "Reset password →"}
            </button>
          </form>
        )}
      </div>
    </section>
  );
}

function AdminApprovalsPage({ onNavigate }) {
  const [state, setState] = useState({ status: "loading", admin: null, pendingCompanies: [], pendingUsers: [] });
  const [busyId, setBusyId] = useState(null);

  const load = () => {
    Promise.all([
      fetch("/api/admin/me", { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : Promise.reject())),
      fetch("/api/admin/pending", { credentials: "same-origin" }).then((r) => (r.ok ? r.json() : Promise.reject())),
    ])
      .then(([me, pending]) => {
        setState({
          status: "ready", admin: me.admin,
          pendingCompanies: pending.pendingCompanies || [],
          pendingUsers: pending.pendingUsers || [],
        });
      })
      .catch(() => onNavigate("admin-login"));
  };

  useEffect(load, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  const isReadOnly = state.admin && state.admin.role !== "super_admin";

  const approveCompany = async (id, tier, am, geo, xeroContactId) => {
    setBusyId(`company-${id}`);
    try {
      const res = await fetch(`/api/admin/companies/${id}/approve`, {
        method: "POST", credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          tier,
          accountManagerName: am.name, accountManagerEmail: am.email, accountManagerPhone: am.phone,
          region: geo.region, country: geo.country,
          xeroContactId,
        }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) return data.error || "Something went wrong. Please try again.";
      load();
      return null;
    } catch {
      return "Couldn't reach the server. Check your connection and try again.";
    } finally { setBusyId(null); }
  };

  const rejectCompany = async (id) => {
    setBusyId(`company-${id}`);
    try { await fetch(`/api/admin/companies/${id}/reject`, { method: "POST", credentials: "same-origin" }); load(); }
    finally { setBusyId(null); }
  };

  const approveUser = async (id) => {
    setBusyId(`user-${id}`);
    try { await fetch(`/api/admin/users/${id}/approve`, { method: "POST", credentials: "same-origin" }); load(); }
    finally { setBusyId(null); }
  };

  const rejectUser = async (id) => {
    setBusyId(`user-${id}`);
    try { await fetch(`/api/admin/users/${id}/reject`, { method: "POST", credentials: "same-origin" }); load(); }
    finally { setBusyId(null); }
  };

  if (state.status === "loading") {
    return <section style={{ background: "#fff", minHeight: "calc(100vh - 88px)" }} />;
  }

  return (
    <AdminShell admin={state.admin} page="admin-approvals" onNavigate={onNavigate}
      subtitle="Staff only" title="Pending approvals">
      <SectionLabel>Pending companies ({state.pendingCompanies.length})</SectionLabel>
      {state.pendingCompanies.length === 0 ? (
        <EmptyNote>No companies waiting on approval.</EmptyNote>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 16, marginBottom: 44 }}>
          {state.pendingCompanies.map((c) => (
            <CompanyApprovalRow
              key={c.id} company={c}
              busy={busyId === `company-${c.id}`}
              isReadOnly={isReadOnly}
              onApprove={(tier, am, geo, xeroContactId) => approveCompany(c.id, tier, am, geo, xeroContactId)}
              onReject={() => rejectCompany(c.id)}
            />
          ))}
        </div>
      )}

      <SectionLabel>Pending users ({state.pendingUsers.length})</SectionLabel>
      {state.pendingUsers.length === 0 ? (
        <EmptyNote>No users waiting on approval.</EmptyNote>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {state.pendingUsers.map((u) => (
            <UserApprovalRow
              key={u.id} user={u}
              busy={busyId === `user-${u.id}`}
              isReadOnly={isReadOnly}
              onApprove={() => approveUser(u.id)}
              onReject={() => rejectUser(u.id)}
            />
          ))}
        </div>
      )}
    </AdminShell>
  );
}

function CompanyApprovalRow({ company, busy, isReadOnly, onApprove, onReject }) {
  const [tier, setTier] = useState("gold");
  const [amName, setAmName] = useState("");
  const [amEmail, setAmEmail] = useState("");
  const [amPhone, setAmPhone] = useState("");
  const [region, setRegion] = useState("UK");
  const [country, setCountry] = useState("United Kingdom");
  const [xeroContact, setXeroContact] = useState(null); // { contactId, name }
  const [xeroStatus, setXeroStatus] = useState({ status: "loading", connected: false });
  const [approveError, setApproveError] = useState("");

  const loadXeroStatus = () => {
    fetch("/api/admin/xero/status", { credentials: "same-origin" })
      .then((r) => r.json())
      .then((data) => setXeroStatus({ status: "ready", connected: !!data.connected }))
      .catch(() => setXeroStatus({ status: "error", connected: false }));
  };
  useEffect(loadXeroStatus, []); // eslint-disable-line react-hooks/exhaustive-deps -- mount-only

  const countryOptions = window.GEO_DATA.countriesForRegion(region);
  const handleRegionChange = (nextRegion) => {
    setRegion(nextRegion);
    setCountry(window.GEO_DATA.countriesForRegion(nextRegion)[0] || "");
  };
  const canApprove = !!region && !!country && !!xeroContact;

  const doApprove = async () => {
    setApproveError("");
    const err = await onApprove(
      tier, { name: amName, email: amEmail, phone: amPhone }, { region, country }, xeroContact.contactId
    );
    if (err) setApproveError(err);
  };

  return (
    <div data-testid={`company-row-${company.id}`} style={{
      background: "rgba(0,0,0,0.03)", border: "1px solid rgba(0,0,0,0.14)",
      padding: "22px 24px",
    }}>
      <div style={{ display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 12, marginBottom: 16 }}>
        <div>
          <div style={{
            fontFamily: "var(--font-display)", fontWeight: 700, fontSize: 18,
            textTransform: "uppercase", color: "#000",
          }}>{company.name}</div>
          <div style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "rgba(0,0,0,0.6)", marginTop: 4 }}>
            {company.user_count} signup{company.user_count === 1 ? "" : "s"} · {company.invoice_address || "no address given"}
          </div>
        </div>
      </div>
      <div style={{ display: "grid", gap: 10, gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", marginBottom: 16 }}>
        <MiniField label="Tier">
          <select value={tier} onChange={(e) => setTier(e.target.value)} style={selectStyle}>
            <option value="gold">Gold</option>
            <option value="platinum">Platinum</option>
            <option value="regional_reseller">Regional Reseller</option>
          </select>
        </MiniField>
        <MiniField label="Account manager name">
          <input value={amName} onChange={(e) => setAmName(e.target.value)} placeholder="e.g. Sam Manager" data-testid="am-name-input" style={inputStyle} />
        </MiniField>
        <MiniField label="Account manager email">
          <input value={amEmail} onChange={(e) => setAmEmail(e.target.value)} placeholder="sam@solosecure.group" data-testid="am-email-input" style={inputStyle} />
        </MiniField>
        <MiniField label="Account manager phone">
          <input value={amPhone} onChange={(e) => setAmPhone(e.target.value)} placeholder="+44 1234 567890" data-testid="am-phone-input" style={inputStyle} />
        </MiniField>
        <MiniField label="Region">
          <select
            value={region} onChange={(e) => handleRegionChange(e.target.value)}
            data-testid="am-region-select" style={selectStyle}
          >
            {window.GEO_DATA.REGIONS.map((r) => <option key={r} value={r}>{r}</option>)}
          </select>
        </MiniField>
        <MiniField label="Country">
          <select
            value={country} onChange={(e) => setCountry(e.target.value)}
            data-testid="am-country-select" style={selectStyle}
          >
            {countryOptions.map((cName) => <option key={cName} value={cName}>{cName}</option>)}
          </select>
        </MiniField>
      </div>
      <div style={{ fontFamily: "var(--font-body)", fontSize: 12, color: "rgba(0,0,0,0.5)", marginBottom: 16 }}>
        Region/country is locked to this customer record — some customers run separate regional
        entities, each of which should sign up as its own company instead of sharing this one.
      </div>
      <MiniField label="Xero contact">
        {xeroStatus.status === "ready" && !xeroStatus.connected ? (
          <window.XeroNotConnectedWarning onRecheck={loadXeroStatus} />
        ) : xeroContact ? (
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", background: "rgba(20,140,60,0.06)", border: "1px solid rgba(20,140,60,0.3)", padding: "10px 12px" }}>
            <span style={{ fontFamily: "var(--font-body)", fontSize: 13.5, color: "#000" }}>✓ <strong>{xeroContact.name}</strong></span>
            <button
              type="button" onClick={() => setXeroContact(null)}
              data-testid={`company-approval-xero-change-${company.id}`}
              style={{ background: "none", border: "none", padding: 0, color: "#000", textDecoration: "underline", cursor: "pointer", fontFamily: "inherit", fontSize: 12 }}
            >Change</button>
          </div>
        ) : (
          <window.XeroContactPicker
            defaultQuery={company.name}
            onSelect={(contact) => setXeroContact({ contactId: contact.contactId, name: contact.name })}
          />
        )}
      </MiniField>
      {approveError && (
        <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "#a30000", marginTop: 12, marginBottom: 4 }}>
          {approveError}
        </div>
      )}
      <div style={{ display: "flex", gap: 10, marginTop: 16 }}>
        <ActionButton
          disabled={busy || !canApprove} readOnly={isReadOnly} testId={`approve-company-${company.id}`}
          onClick={doApprove}
        >Approve company</ActionButton>
        <ActionButton disabled={busy} readOnly={isReadOnly} danger testId={`reject-company-${company.id}`} onClick={onReject}>Reject</ActionButton>
      </div>
    </div>
  );
}

function UserApprovalRow({ user, busy, isReadOnly, onApprove, onReject }) {
  return (
    <div data-testid={`user-row-${user.id}`} style={{
      background: "rgba(0,0,0,0.02)", border: "1px solid rgba(0,0,0,0.12)",
      padding: "16px 20px",
      display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 14,
    }}>
      <div>
        <div style={{ fontFamily: "var(--font-body)", fontSize: 14.5, fontWeight: 600, color: "#000" }}>
          {user.name} <span style={{ color: "rgba(0,0,0,0.5)", fontWeight: 400 }}>· {user.email}</span>
        </div>
        <div style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "rgba(0,0,0,0.55)", marginTop: 4 }}>
          {user.company_name} ({user.role}) · company is {user.company_status}
        </div>
      </div>
      <div style={{ display: "flex", gap: 10 }}>
        <ActionButton disabled={busy} readOnly={isReadOnly} testId={`approve-user-${user.id}`} onClick={onApprove}>Approve</ActionButton>
        <ActionButton disabled={busy} readOnly={isReadOnly} danger testId={`reject-user-${user.id}`} onClick={onReject}>Reject</ActionButton>
      </div>
    </div>
  );
}

function SectionLabel({ children }) {
  return (
    <div style={{
      fontFamily: "var(--font-body)", fontSize: 10,
      letterSpacing: "0.28em", textTransform: "uppercase",
      color: "rgba(0,0,0,0.55)", fontWeight: 500, marginBottom: 16,
    }}>{children}</div>
  );
}

function EmptyNote({ children }) {
  return (
    <div style={{
      fontFamily: "var(--font-body)", fontSize: 14,
      color: "rgba(0,0,0,0.45)", marginBottom: 40,
    }}>{children}</div>
  );
}

function MiniField({ label, children }) {
  return (
    <label style={{ display: "block" }}>
      <div style={{
        fontFamily: "var(--font-body)", fontSize: 9.5,
        letterSpacing: "0.16em", textTransform: "uppercase",
        color: "rgba(0,0,0,0.5)", marginBottom: 6,
      }}>{label}</div>
      {children}
    </label>
  );
}

function ActionButton({ children, danger, disabled, readOnly, onClick, testId }) {
  const isDisabled = disabled || readOnly;
  return (
    <button
      type="button" onClick={readOnly ? undefined : onClick} disabled={isDisabled} data-testid={testId}
      title={readOnly ? "Master admins only — you have read-only access" : undefined}
      style={{
        background: danger ? "transparent" : "#000",
        color: danger ? "#a30000" : "#fff",
        border: `1px solid ${danger ? "rgba(190,40,40,0.55)" : "#000"}`,
        padding: "10px 18px", cursor: isDisabled ? "not-allowed" : "pointer",
        opacity: isDisabled ? 0.5 : 1,
        fontFamily: "var(--font-body)", fontSize: 11.5, fontWeight: 500,
        letterSpacing: "0.14em", textTransform: "uppercase",
      }}>
      {children}
    </button>
  );
}

const inputStyle = {
  width: "100%", boxSizing: "border-box",
  background: "rgba(0,0,0,0.03)", border: "1px solid rgba(0,0,0,0.25)",
  color: "#000", fontFamily: "var(--font-body)", fontSize: 13.5, padding: "9px 10px",
  outline: "none",
};
const selectStyle = { ...inputStyle, appearance: "auto" };

Object.assign(window, { AdminLoginPage, AdminForgotPasswordPage, AdminResetPasswordPage, AdminApprovalsPage });
