// ---------- Team view (client-side org_admin self-service) ----------
// Lets an org's own org_admin manage OTHER logins within their org — never
// workspace/telephony/pricing config, which stays developer-only via
// /client-admin. All calls go to /org-admin/*, which is scoped server-side
// to the caller's own organizationKey.

function TeamView({ lang = "en" } = {}) {
  const t = makeT(lang);
  const session = getSession();
  const [users, setUsers] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr] = React.useState(null);

  const [showNew, setShowNew] = React.useState(false);
  const [form, setForm] = React.useState({ name: "", email: "", phone: "" });
  const [formErr, setFormErr] = React.useState(null);
  const [saving, setSaving] = React.useState(false);

  const [tempPw, setTempPw] = React.useState(null); // { email, password }
  const [busyId, setBusyId] = React.useState(null);
  const [mfaResetTarget, setMfaResetTarget] = React.useState(null); // user object mid-reset

  async function loadUsers() {
    try {
      setErr(null);
      const data = await voxApi("/org-admin/users");
      setUsers(data.users || []);
    } catch (e) {
      setErr(e.message);
    } finally {
      setLoading(false);
    }
  }

  React.useEffect(() => { loadUsers(); }, []);

  async function createUser() {
    if (!form.name.trim() || !form.email.trim()) { setFormErr(t("team.err.nameEmailRequired")); return; }
    setSaving(true);
    setFormErr(null);
    try {
      const res = await voxApi("/org-admin/users", {
        method: "POST",
        body: JSON.stringify({ name: form.name.trim(), email: form.email.trim(), phone: form.phone.trim() }),
      });
      setShowNew(false);
      setForm({ name: "", email: "", phone: "" });
      if (res.user?.tempPassword) setTempPw({ email: res.user.email, password: res.user.tempPassword });
      loadUsers();
    } catch (e) {
      setFormErr(e.message);
    } finally {
      setSaving(false);
    }
  }

  async function toggleLock(u) {
    setBusyId(u.id);
    try {
      await voxApi(`/org-admin/users/${u.id}`, { method: "PUT", body: JSON.stringify({ isLocked: !u.isLocked }) });
      setUsers(list => list.map(x => x.id === u.id ? { ...x, isLocked: !u.isLocked } : x));
    } catch (e) {
      alert(e.message);
    } finally {
      setBusyId(null);
    }
  }

  async function changeOrgRole(u, orgRole) {
    setBusyId(u.id);
    try {
      await voxApi(`/org-admin/users/${u.id}`, { method: "PUT", body: JSON.stringify({ orgRole }) });
      setUsers(list => list.map(x => x.id === u.id ? { ...x, orgRole } : x));
    } catch (e) {
      alert(e.message);
    } finally {
      setBusyId(null);
    }
  }

  async function resetPassword(u) {
    if (!window.confirm(t("team.confirmResetPassword", { name: u.name, email: u.email }))) return;
    setBusyId(u.id);
    try {
      const res = await voxApi(`/org-admin/users/${u.id}/reset-password`, { method: "POST" });
      setTempPw({ email: u.email, password: res.tempPassword });
    } catch (e) {
      alert(e.message);
    } finally {
      setBusyId(null);
    }
  }

  async function deleteUser(u) {
    if (!window.confirm(t("team.confirmRemove", { name: u.name, email: u.email }))) return;
    setBusyId(u.id);
    try {
      await voxApi(`/org-admin/users/${u.id}`, { method: "DELETE" });
      setUsers(list => list.filter(x => x.id !== u.id));
    } catch (e) {
      alert(e.message);
    } finally {
      setBusyId(null);
    }
  }

  if (loading) return <div className="muted text-12" style={{ padding: 24 }}>{t("team.loading")}</div>;
  if (err) return <div style={{ padding: 24, color: "var(--err)", fontSize: 13 }}>{err}</div>;

  return (
    <>
      {showNew && (
        <div className="modal-back" onClick={() => setShowNew(false)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <div className="modal-head">
              <div className="card-title">{t("team.addTeammate")}</div>
              <Btn variant="ghost" size="sm" icon="x" onClick={() => setShowNew(false)} />
            </div>
            <div className="modal-body">
              <Field label={t("team.field.name")}><Input value={form.name} onChange={e => setForm(f => ({ ...f, name: e.target.value }))} placeholder={t("team.field.namePlaceholder")} /></Field>
              <Field label={t("team.field.email")}><Input type="email" value={form.email} onChange={e => setForm(f => ({ ...f, email: e.target.value }))} placeholder={t("team.field.emailPlaceholder")} /></Field>
              <Field label={t("team.field.phone")}><Input value={form.phone} onChange={e => setForm(f => ({ ...f, phone: e.target.value }))} placeholder={t("team.field.phonePlaceholder")} /></Field>
              <div className="muted text-11 mt-1">{t("team.newTeammateNote")}</div>
              {formErr && (
                <div style={{ marginTop: 10, padding: "8px 12px", background: "rgba(239,68,68,.10)", border: "1px solid rgba(239,68,68,.28)", borderRadius: 7, color: "#f87171", fontSize: 13 }}>
                  {formErr}
                </div>
              )}
            </div>
            <div className="modal-foot">
              <Btn variant="ghost" onClick={() => setShowNew(false)}>{t("team.cancel")}</Btn>
              <Btn variant="primary" onClick={createUser} disabled={saving}>{saving ? t("team.creating") : t("team.addTeammate")}</Btn>
            </div>
          </div>
        </div>
      )}

      {tempPw && (
        <div className="modal-back" onClick={() => setTempPw(null)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <div className="modal-head">
              <div className="card-title">{t("team.tempPasswordTitle")}</div>
              <Btn variant="ghost" size="sm" icon="x" onClick={() => setTempPw(null)} />
            </div>
            <div className="modal-body">
              <div className="muted text-12 mb-2">{t("team.shareOnce", { email: tempPw.email })}</div>
              <div className="mono" style={{ padding: "10px 12px", background: "var(--bg-2)", borderRadius: 7, fontSize: 15, fontWeight: 700, letterSpacing: "0.03em" }}>{tempPw.password}</div>
            </div>
            <div className="modal-foot">
              <Btn variant="primary" onClick={() => setTempPw(null)}>{t("team.done")}</Btn>
            </div>
          </div>
        </div>
      )}

      {mfaResetTarget && (
        <MfaResetModal
          target={mfaResetTarget}
          onClose={() => setMfaResetTarget(null)}
          onDone={() => {
            setUsers(list => list.map(x => x.id === mfaResetTarget.id ? { ...x, mfaEnabled: false } : x));
            setMfaResetTarget(null);
          }}
          lang={lang}
        />
      )}

      <Card pad="none">
        <div className="card-head">
          <span className="card-title">{t("team.teammateCount", { count: users.length, plural: users.length !== 1 ? "s" : "" })}</span>
          <Btn variant="ghost" size="sm" icon="plus" onClick={() => { setShowNew(true); setFormErr(null); }}>{t("team.addTeammate")}</Btn>
        </div>
        {users.length === 0 ? (
          <div className="empty-state" style={{ padding: 40 }}>
            <div className="empty-state-title">{t("team.noTeammatesYet")}</div>
            <div>{t("team.noTeammatesCopy")}</div>
          </div>
        ) : (
          <table style={{ width: "100%", borderCollapse: "collapse" }}>
            <thead>
              <tr style={{ borderBottom: "1px solid var(--c-line)" }}>
                {[t("team.table.name"), t("team.table.email"), t("team.table.role"), t("team.table.mfa"), t("team.table.status"), ""].map((h, i) => (
                  <th key={i} style={{ padding: "10px 16px", textAlign: "left", fontSize: 11, fontWeight: 500, color: "var(--text2)", textTransform: "uppercase", letterSpacing: "0.05em" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {users.map(u => {
                const isSelf = u.id === session?.clientId;
                return (
                  <tr key={u.id} style={{ borderBottom: "1px solid var(--c-line)" }}>
                    <td style={{ padding: "12px 16px" }}>
                      <div className="row gap-3">
                        <div className="agent-avatar" style={{ width: 30, height: 30, fontSize: 11, borderRadius: 7, flexShrink: 0 }}>{(u.name || "?").slice(0, 2).toUpperCase()}</div>
                        <span className="strong text-13">{u.name}{isSelf ? t("team.you") : ""}</span>
                      </div>
                    </td>
                    <td style={{ padding: "12px 16px", fontSize: 13, color: "var(--text2)" }}>{u.email}</td>
                    <td style={{ padding: "12px 16px" }}>
                      <Select
                        value={u.orgRole || "member"}
                        disabled={busyId === u.id}
                        onChange={e => changeOrgRole(u, e.target.value)}
                        style={{ fontSize: 12, padding: "4px 8px" }}
                      >
                        <option value="member">{t("team.role.member")}</option>
                        <option value="org_admin">{t("team.role.orgAdmin")}</option>
                      </Select>
                    </td>
                    <td style={{ padding: "12px 16px" }}>
                      {u.mfaEnabled ? (
                        <span className="badge" style={{ background: "rgba(34,197,94,.12)", color: "#22c55e" }}>{t("team.mfaEnabled")}</span>
                      ) : (
                        <span className="muted text-12">{t("team.mfaOff")}</span>
                      )}
                    </td>
                    <td style={{ padding: "12px 16px" }}>
                      <span className="badge" style={{ background: u.isLocked ? "rgba(239,68,68,.12)" : "rgba(34,197,94,.12)", color: u.isLocked ? "#f87171" : "#22c55e" }}>
                        {u.isLocked ? t("team.locked") : t("team.active")}
                      </span>
                    </td>
                    <td style={{ padding: "12px 16px", textAlign: "right" }}>
                      <div className="row gap-1" style={{ justifyContent: "flex-end", flexWrap: "wrap" }}>
                        {u.mfaEnabled && (
                          <Btn variant="ghost" size="sm" disabled={busyId === u.id} onClick={() => setMfaResetTarget(u)}>{t("team.resetMfa")}</Btn>
                        )}
                        <Btn variant="ghost" size="sm" disabled={busyId === u.id} onClick={() => resetPassword(u)}>{t("team.resetPassword")}</Btn>
                        <Btn variant="ghost" size="sm" disabled={busyId === u.id} onClick={() => toggleLock(u)}>{u.isLocked ? t("team.unlock") : t("team.lock")}</Btn>
                        {!isSelf && (
                          <Btn variant="ghost" size="sm" icon="trash" style={{ color: "var(--err)" }} disabled={busyId === u.id} onClick={() => deleteUser(u)}>{t("team.remove")}</Btn>
                        )}
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
        <div style={{ padding: "12px 16px", borderTop: users.length ? "1px solid var(--c-line)" : "none", fontSize: 11, color: "var(--text3)" }}>
          {t("team.footerNote")}
        </div>
      </Card>

      <div style={{ marginTop: 20 }}>
        <OrgAuditLog lang={lang} />
      </div>
    </>
  );
}

// Read-only, org-scoped audit trail — logins, account changes, and MFA
// events for this org's own users only (server-side scoped via
// GET /org-admin/audit-log, never another org's entries).
function OrgAuditLog({ lang = "en" } = {}) {
  const t = makeT(lang);
  const [entries, setEntries] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  const [loading, setLoading] = React.useState(true);
  const [expanded, setExpanded] = React.useState(null);

  function prettifyAuditCode(value) {
    return String(value || "")
      .split(".")
      .map(part => part.replace(/_/g, " "))
      .join(" ")
      .replace(/\b\w/g, ch => ch.toUpperCase());
  }

  function auditActionLabel(entry) {
    const action = entry?.action || "";
    const resource = entry?.resource || "";
    if (action === "report.access" && resource === "call_log_list") return t("audit.action.callLogsScreen");
    if (action === "report.export" && resource === "call_log_csv") return t("audit.action.callLogsCsvExport");
    if (action === "call_log.access" && resource === "call_log") return t("audit.action.callDetailsScreen");
    if (action === "recording.access" && resource === "call_recording") return t("audit.action.recordingPlayer");
    if (action === "login") return t("audit.action.login");
    if (action === "logout") return t("audit.action.logout");
    return prettifyAuditCode(action);
  }

  function auditEntryLink(entry) {
    const details = entry?.details || {};
    if (details.assetUrl) return details.assetUrl;
    if (details.screenUrl) return details.screenUrl;
    if (entry?.action === "report.access" && entry?.resource === "call_log_list") return `${window.location.origin}/#logs`;
    if (entry?.action === "report.export" && entry?.resource === "call_log_csv") return `${window.location.origin}/#logs`;
    if (entry?.action === "call_log.access" && entry?.resource === "call_log" && entry?.resourceId) return `${window.location.origin}/#logs/${entry.resourceId}`;
    if (entry?.action === "recording.access" && entry?.resource === "call_recording" && entry?.resourceId) return `${window.location.origin}/logs/${entry.resourceId}/recording`;
    return "";
  }

  async function load() {
    setLoading(true);
    try {
      const data = await voxApiOptional("/org-admin/audit-log?limit=200", { entries: [], total: 0 });
      setEntries(data.entries || []);
      setTotal(data.total || 0);
    } finally {
      setLoading(false);
    }
  }

  React.useEffect(() => { load(); }, []);

  return (
    <Card>
      <div className="row" style={{ justifyContent: "space-between", alignItems: "flex-start", marginBottom: 14, flexWrap: "wrap", gap: 12 }}>
        <div>
          <div className="strong" style={{ fontSize: 15 }}>{t("team.activity.title")}</div>
          <div className="muted text-12 mt-1">{t("team.activity.subtitle")}</div>
        </div>
        <Btn variant="ghost" size="sm" onClick={load}>{loading ? t("team.loading") : t("team.activity.refresh")}</Btn>
      </div>
      <div className="tbl-wrap">
        <table className="tbl">
          <thead>
            <tr><th>{t("team.activity.time")}</th><th>{t("team.activity.user")}</th><th>{t("team.activity.action")}</th><th>{t("team.activity.status")}</th><th></th></tr>
          </thead>
          <tbody>
            {entries.length === 0 && !loading && (
              <tr><td colSpan={5} style={{ textAlign: "center", color: "var(--c-text-4)", padding: 20 }}>{t("team.activity.noActivity")}</td></tr>
            )}
            {entries.map(e => (
              <React.Fragment key={e.seq}>
                <tr style={{ cursor: "pointer" }} onClick={() => setExpanded(prev => prev === e.seq ? null : e.seq)}>
                  <td className="mono" style={{ fontSize: 11 }}>{fmtDate(e.timestamp)}</td>
                  <td className="text-12">{e.email || e.userId || "—"}</td>
                  <td><Badge tone={auditActionTone(e.action, e.status)}>{auditActionLabel(e)}</Badge></td>
                  <td><Badge tone={e.status === "fail" ? "err" : "ok"} dot>{e.status}</Badge></td>
                  <td className="muted text-11">{expanded === e.seq ? "▲" : "▼"}</td>
                </tr>
                {expanded === e.seq && (auditEntryLink(e) || Object.keys(e.details || {}).length > 0) && (
                  <tr>
                    <td colSpan={5} style={{ background: "var(--c-bg)", padding: "10px 16px" }}>
                      {auditEntryLink(e) && (
                        <div className="mono text-11" style={{ marginBottom: 6, wordBreak: "break-all" }}>
                          <a href={auditEntryLink(e)} target="_blank" rel="noreferrer">{auditEntryLink(e)}</a>
                        </div>
                      )}
                      <div className="mono text-11">{JSON.stringify(e.details)}</div>
                    </td>
                  </tr>
                )}
              </React.Fragment>
            ))}
          </tbody>
        </table>
      </div>
      <div className="muted text-11 mt-2">{t("team.activity.showing", { count: entries.length, total })}</div>
    </Card>
  );
}

// Force-disabling a teammate's MFA needs the acting org_admin's OWN password
// as a safety confirmation (see /org-admin/users/:id/reset-mfa) — this is a
// small dedicated modal rather than a bare window.confirm() because of that.
function MfaResetModal({ target, onClose, onDone, lang = "en" }) {
  const t = makeT(lang);
  const [password, setPassword] = React.useState("");
  const [err, setErr] = React.useState(null);
  const [saving, setSaving] = React.useState(false);

  async function submit() {
    if (!password) { setErr(t("team.mfaModal.err.enterPassword")); return; }
    setSaving(true);
    setErr(null);
    try {
      await voxApi(`/org-admin/users/${target.id}/reset-mfa`, { method: "POST", body: JSON.stringify({ password }) });
      onDone();
    } catch (e) {
      setErr(e.message);
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="modal-back" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div className="card-title">{t("team.mfaModal.title", { name: target.name })}</div>
          <Btn variant="ghost" size="sm" icon="x" onClick={onClose} />
        </div>
        <div className="modal-body">
          <div className="muted text-12 mb-2">{t("team.mfaModal.body", { email: target.email })}</div>
          <Field label={t("team.mfaModal.yourPassword")}><Input type="password" value={password} onChange={e => setPassword(e.target.value)} /></Field>
          {err && (
            <div style={{ marginTop: 10, padding: "8px 12px", background: "rgba(239,68,68,.10)", border: "1px solid rgba(239,68,68,.28)", borderRadius: 7, color: "#f87171", fontSize: 13 }}>
              {err}
            </div>
          )}
        </div>
        <div className="modal-foot">
          <Btn variant="ghost" onClick={onClose}>{t("team.cancel")}</Btn>
          <Btn variant="primary" onClick={submit} disabled={saving}>{saving ? t("team.mfaModal.resetting") : t("team.resetMfa")}</Btn>
        </div>
      </div>
    </div>
  );
}
