/* ========================================================================
   roles-pages.jsx — Rules, role-aware Settings (Profile / Users and roles /
   Organisation)
   ======================================================================== */
const { useState: uP, useMemo: mP } = React;

/* =====================================================================
   RULES — operational configuration (Admin and above)
   ===================================================================== */
function RulesPage() {
  const ctx = useRoles();
  const [rules, setRules] = uP(() => window.RULES.map((r) => ({ ...r })));
  const [newOpen, setNewOpen] = uP(false);
  const [delRule, setDelRule] = uP(null);

  const toggle = (r) => {
    setRules((list) => list.map((x) => x.id === r.id ? { ...x, enabled: !x.enabled } : x));
    ctx.toast({ kind: "ok", title: r.enabled ? "Rule disabled" : "Rule enabled", body: "\u201c" + r.name + "\u201d is now " + (r.enabled ? "off" : "on") + "." });
  };

  return (
    <>
      <PageHead title="Rules" subtitle="Automatic actions that run against your SIMs when a condition is met." />
      <div>
        <Button variant="primary" icon="plus" onClick={() => setNewOpen(true)}>Create Rule</Button>
      </div>

      <Card>
        <TableScroll>
          <table className="mp-table">
            <thead>
              <tr><th>Rule</th><th>Action</th><th>Applies to</th><th>Last triggered</th><th>On</th><th></th></tr>
            </thead>
            <tbody>
              {rules.map((r) => (
                <tr key={r.id}>
                  <td>
                    <div className="mp-rule-name">{r.name}</div>
                    <div className="mp-rule-trigger">{r.trigger}</div>
                  </td>
                  <td>
                    {/^(suspend|bar|pause)/i.test(r.action)
                      ? <Badge variant="warn" icon="octagon-pause">{r.action}</Badge>
                      : <Badge variant="mist" icon="mail">{r.action}</Badge>}
                  </td>
                  <td style={{ color: "var(--fg-2)" }}>{r.scope}</td>
                  <td style={{ color: "var(--fg-3)" }}>{r.last_fired === "—" ? "Never" : window.fmtDate(r.last_fired)}</td>
                  <td>
                    <button type="button" className={"mp-sw" + (r.enabled ? " is-on" : "")} onClick={() => toggle(r)} aria-label={r.enabled ? "Disable rule" : "Enable rule"} />
                  </td>
                  <td style={{ textAlign: "right" }}>
                    <ActionsMenu items={[
                      { label: "Edit Rule", onClick: () => ctx.toast({ kind: "ok", title: "Rule editor", body: "Editing \u201c" + r.name + "\u201d is out of scope for this prototype." }) },
                      { label: "Delete Rule", onClick: () => setDelRule(r) }
                    ]} />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </TableScroll>
      </Card>

      {newOpen ? (
        <NewRuleModal onClose={() => setNewOpen(false)} onCreate={(rule) => {
          setRules((l) => [...l, { ...rule, id: Date.now(), enabled: true, last_fired: "—" }]);
          ctx.toast({ kind: "ok", title: "Rule created", body: "\u201c" + rule.name + "\u201d is live and will run on the next matching event." });
          setNewOpen(false);
        }} />
      ) : null}

      {delRule ? (
        <div className="mp-modal-overlay" onClick={() => setDelRule(null)}>
          <div className="mp-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 440 }}>
            <div className="mp-modal-ic mp-modal-ic--danger"><Icon name="trash-2" size={20} /></div>
            <h3 className="mp-modal-title">Delete "{delRule.name}"?</h3>
            <p className="mp-modal-text">This rule will stop running immediately. SIMs it has already acted on are not changed.</p>
            <div className="mp-modal-actions">
              <Button variant="secondary" onClick={() => setDelRule(null)}>Cancel</Button>
              <Button variant="danger-solid" icon="trash-2" onClick={() => {
                setRules((l) => l.filter((x) => x.id !== delRule.id));
                ctx.toast({ kind: "ok", title: "Rule deleted", body: "\u201c" + delRule.name + "\u201d no longer runs." });
                setDelRule(null);
              }}>Delete Rule</Button>
            </div>
          </div>
        </div>
      ) : null}
    </>
  );
}

function NewRuleModal({ onClose, onCreate }) {
  const [name, setName] = uP("");
  const [trigger, setTrigger] = uP("Data usage reaches 80% of plan allowance");
  const [action, setAction] = uP("Email account admins");
  const [scope, setScope] = uP("All SIMs");
  const [err, setErr] = uP(null);
  const destructive = /^(suspend|bar|pause)/i.test(action);
  return (
    <div className="mp-modal-overlay" onClick={onClose}>
      <div className="mp-modal mp-modal--form" onClick={(e) => e.stopPropagation()}>
        <div className="mp-modal-ic mp-modal-ic--neutral"><Icon name="workflow" size={20} /></div>
        <h3 className="mp-modal-title">Create a rule</h3>
        <p className="mp-modal-sub">Rules run automatically. Anything that suspends or bars service takes effect without further approval.</p>
        <div className="mp-field">
          <label className="mp-field-label">Rule name</label>
          <input className={"mp-field-input" + (err ? " has-err" : "")} autoFocus value={name} placeholder="Suspend at 150% of plan" onChange={(e) => { setName(e.target.value); setErr(null); }} />
          {err ? <div className="mp-inline-err"><Icon name="triangle-alert" size={13} /><span>{err}</span></div> : null}
        </div>
        <div className="mp-field">
          <label className="mp-field-label">When</label>
          <Select value={trigger} onChange={setTrigger} options={[
            "Data usage reaches 80% of plan allowance",
            "Data usage exceeds 100% of plan allowance",
            "Roaming spend exceeds £40 in a period",
            "No data session for 60 days"
          ]} />
        </div>
        <div className="mp-field">
          <label className="mp-field-label">Then</label>
          <Select value={action} onChange={setAction} options={["Email account admins", "Suspend service", "Bar service", "Pause SIM"]} />
        </div>
        <div className="mp-field">
          <label className="mp-field-label">Applies to</label>
          <Select value={scope} onChange={setScope} options={["All SIMs", "Tag: Field team", "Tag: IoT sensors", "Tag: Leadership"]} />
        </div>
        {destructive ? (
          <div className="mp-modal-note mp-modal-note--warn">
            <Icon name="triangle-alert" size={15} />
            <span>This rule stops service for the SIMs it matches. Affected users lose connectivity until an administrator restores it.</span>
          </div>
        ) : null}
        <div className="mp-modal-actions">
          <Button variant="secondary" onClick={onClose}>Cancel</Button>
          <Button variant="primary" icon="check" onClick={() => name.trim() ? onCreate({ name: name.trim(), trigger, action, scope }) : setErr("Give the rule a name so you can recognise it later.")}>Create Rule</Button>
        </div>
      </div>
    </div>
  );
}

/* =====================================================================
   SETTINGS — role-aware tabs (overrides the shared SettingsPage)
   ===================================================================== */
function RoleSettingsPage({ sub }) {
  const ctx = useRoles();
  const tabs = window.SETTINGS_TABS.filter((t) => ctx.can(t.cap));
  const active = tabs.find((t) => t.key === sub) || tabs[0];

  return (
    <>
      <div className="mp-page-head">
        <div className="mp-page-head-text">
          <h1 className="mp-page-head-title">{active.title}</h1>
          <p className="mp-settings-sub">{active.subtitle}</p>
        </div>
      </div>
      <div className="mp-page-tabs" role="tablist">
        {tabs.map((t) => (
          <a key={t.key} role="tab" href={"#" + t.path} className={"mp-page-tab" + (active.key === t.key ? " is-active" : "")}>{t.label}</a>
        ))}
      </div>
      {active.key === "profile" ? <ProfileTab /> : null}
      {active.key === "security" ? <SecurityTab /> : null}
      {active.key === "users" ? <UsersRolesTab /> : null}
      {active.key === "organisation" ? <OrganisationTab /> : null}
    </>
  );
}

/* ---------- Inline edit field + its modal ---------- */
function InlineEditField({ label, value, placeholder, hint, editable = true, icon = "pencil", lockNote,
                           tipLabel, modalTitle, modalBody, modalHelp, type = "text", requirePassword, confirmChange, onSave }) {
  const [open, setOpen] = uP(false);
  return (
    <div className={"mp-ie" + (editable ? "" : " is-locked")}>
      <div className="mp-ie-main">
        <div className="mp-ie-label">
          <span>{label}</span>
          {editable ? (
            <button type="button" className="mp-ie-pencil" onClick={() => setOpen(true)} aria-label={tipLabel || ("Edit " + label)}>
              <Icon name={icon} size={14} />
              <span className="mp-ie-tip">{tipLabel || ("Edit " + label)}</span>
            </button>
          ) : (
            <span className="mp-ie-lock"><Icon name="lock" size={13} /></span>
          )}
        </div>
        <div className={"mp-ie-value" + (value ? "" : " is-empty")}>{value || placeholder || "Not set"}</div>
        {hint ? <div className="mp-ie-hint">{hint}</div> : null}
        {!editable && lockNote ? <div className="mp-ie-locknote">{lockNote}</div> : null}
      </div>
      {open ? (
        <EditFieldModal
          title={modalTitle || ("Edit " + label)}
          body={modalBody}
          help={modalHelp}
          label={label}
          value={value}
          type={type}
          requirePassword={requirePassword}
          confirmChange={confirmChange}
          onClose={() => setOpen(false)}
          onSave={(next) => { const err = onSave(next); if (err) return err; setOpen(false); }}
        />
      ) : null}
    </div>
  );
}

function EditFieldModal({ title, body, help, label, value, type, requirePassword, confirmChange, onClose, onSave }) {
  const [draft, setDraft] = uP(value || "");
  const [pw, setPw] = uP("");
  const [err, setErr] = uP(null);
  const [pending, setPending] = uP(null);
  const commit = (next) => {
    const problem = onSave(next);
    if (problem) { setPending(null); setErr(problem); }
  };
  const submit = () => {
    if (requirePassword && !pw) return setErr("Enter your current password to confirm this change.");
    const next = draft.trim();
    if (confirmChange) return setPending(next);
    commit(next);
  };
  if (pending !== null) return (
    <div className="mp-modal-overlay" onClick={() => setPending(null)}>
      <div className="mp-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 480 }}>
        <div className="mp-modal-ic mp-modal-ic--neutral"><Icon name="pencil" size={20} /></div>
        <h3 className="mp-modal-title">{confirmChange}</h3>
        <p className="mp-modal-sub">This will change this user's {String(label).toLowerCase()} to <strong>{pending}</strong>.</p>
        <p className="mp-modal-sub">Please confirm you wish to make this change?</p>
        <div className="mp-modal-actions">
          <Button variant="secondary" onClick={() => setPending(null)}>Cancel</Button>
          <Button variant="primary" onClick={() => commit(pending)}>Confirm</Button>
        </div>
      </div>
    </div>
  );
  return (
    <div className="mp-modal-overlay" onClick={onClose}>
      <div className="mp-modal mp-modal--form" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 520 }}>
        <div className="mp-modal-ic mp-modal-ic--neutral"><Icon name="pencil" size={20} /></div>
        <h3 className="mp-modal-title">{title}</h3>
        {body ? <p className="mp-modal-sub">{body}</p> : null}
        <div className="mp-field">
          <label className="mp-field-label">{label}</label>
          <input className={"mp-field-input" + (err ? " has-err" : "")} type={type} autoFocus value={draft}
            onChange={(e) => { setDraft(e.target.value); setErr(null); }}
            onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
          {help && !err ? <div className="mp-ie-hint">{help}</div> : null}
          {err ? <div className="mp-inline-err"><Icon name="triangle-alert" size={13} /><span>{err}</span></div> : null}
        </div>
        {requirePassword ? (
          <div className="mp-field">
            <label className="mp-field-label">Current password</label>
            <input className="mp-field-input" type="password" value={pw} placeholder="••••••••"
              onChange={(e) => { setPw(e.target.value); setErr(null); }} />
          </div>
        ) : null}
        <div className="mp-modal-actions">
          <Button variant="secondary" onClick={onClose}>Cancel</Button>
          <Button variant="primary" icon="check" onClick={submit}>Save</Button>
        </div>
      </div>
    </div>
  );
}

/* ---------- Pending email change ---------- */
function PendingEmailRow({ me }) {
  const ctx = useRoles();
  const [cooling, setCooling] = uP(false);
  const [cancelOpen, setCancelOpen] = uP(false);
  const expires = new Date(new Date(me.pending_email_at).getTime() + window.EMAIL_TTL_H * 3600000);

  const resend = () => {
    if (cooling) return;
    setCooling(true);
    ctx.toast({ kind: "ok", title: "Verification link resent", body: "A new link is on its way to " + me.pending_email + ". The previous link no longer works." });
    setTimeout(() => setCooling(false), 30000);
  };

  return (
    <div className="mp-ie is-pending-change">
      <div className="mp-ie-main">
        <div className="mp-ie-label">
          <span>Email</span>
          <Badge variant="clay" icon="clock">Pending</Badge>
        </div>
        <div className="mp-ie-value">{me.email}</div>
        <div className="mp-pendmail">
          <Icon name="mail-check" size={15} />
          <div>
            <p>
              We've sent a link to <strong>{me.pending_email}</strong>. Your sign-in email is unchanged until you confirm it.
            </p>
            <div className="mp-pendmail-actions">
              <button type="button" className="mp-linkbtn" onClick={resend} disabled={cooling}>
                <Icon name="send" size={14} /><span>{cooling ? "Link sent — try again shortly" : "Resend link"}</span>
              </button>
              <button type="button" className="mp-linkbtn mp-linkbtn--quiet" onClick={() => setCancelOpen(true)}>
                <Icon name="x" size={14} /><span>Cancel change</span>
              </button>
            </div>
          </div>
        </div>
      </div>
      {cancelOpen ? (
        <div className="mp-modal-overlay" onClick={() => setCancelOpen(false)}>
          <div className="mp-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 440 }}>
            <div className="mp-modal-ic mp-modal-ic--warn"><Icon name="mail-x" size={20} /></div>
            <h3 className="mp-modal-title">Cancel this email change?</h3>
            <p className="mp-modal-text">The link sent to {me.pending_email} will stop working and your sign-in email stays as {me.email}. You can request the change again at any time.</p>
            <div className="mp-modal-actions">
              <Button variant="secondary" onClick={() => setCancelOpen(false)}>Keep it pending</Button>
              <Button variant="primary" icon="mail-x" onClick={() => { ctx.cancelEmailChange(me); setCancelOpen(false); }}>Cancel Change</Button>
            </div>
          </div>
        </div>
      ) : null}
    </div>
  );
}

/* ---------- Profile: your details + your access ---------- */
function ProfileTab() {
  const ctx = useRoles();
  const me = ctx.actor;
  const r = window.ROLES[me.role];

  const update = (patch, what) => {
    ctx.setMembers((l) => l.map((m) => m.id === me.id ? { ...m, ...patch } : m));
    ctx.toast({ kind: "ok", title: what + " updated", body: "Your " + what.toLowerCase() + " has been saved." });
  };

  return (
    <>
      <Card>
        <div className="mp-acc-body" style={{ paddingTop: 26 }}>
          <div>
            <h3 className="mp-acc-title">Your Details</h3>
            <p className="mp-acc-sub">Your name and account email address are as listed below. Changing either of these needs your current password.</p>
          </div>
          <div className="mp-ie-list">
            <InlineEditField
              label="Full Name" value={me.name}
              tipLabel="Edit your name" modalTitle="Edit your name"
              modalBody="This is the name other people on your account see."
              requirePassword
              onSave={(next) => {
                if (!next) return "Enter your full name.";
                if (next === me.name) return "That's already your name.";
                update({ name: next, initials: next.split(/\s+/).map((w) => w[0]).slice(0, 2).join("").toUpperCase() }, "Name");
              }} />
            {me.pending_email
              ? <PendingEmailRow me={me} />
              : <InlineEditField
                  label="Email" value={me.email} type="email"
                  tipLabel="Change your email" modalTitle="Change your email address"
                  modalBody="We'll send a link to the new address to check it reaches you. Nothing changes until you follow it."
                  modalHelp="You'll keep signing in with your current address in the meantime."
                  requirePassword
                  onSave={(next) => {
                    if (!window.EMAIL_RE.test(next)) return "Enter a valid email address, for example name@company.co.uk.";
                    if (next.toLowerCase() === me.email.toLowerCase()) return "That's already your email address.";
                    if (ctx.members.some((m) => m.id !== me.id && m.email.toLowerCase() === next.toLowerCase())) return "Someone else on this account already uses that email address.";
                    ctx.requestEmailChange(me, next.toLowerCase());
                  }} />}
          </div>
        </div>
      </Card>

      <Card>
        <div className="mp-card-head">
          <div>
            <h3>Your Role and Access</h3>
            <div className="mp-card-head-sub">What your role lets you do on the platform</div>
          </div>
          <RoleBadge role={me.role} />
        </div>
        <div className="mp-card-body" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <div className={"mp-only-role mp-only-role--" + me.role}>
            <Icon name={r.icon} size={17} style={{ marginTop: 1 }} />
            <div>
              <div className="mp-role-opt-name">{r.label}</div>
              <div className="mp-role-opt-desc">{r.long}</div>
            </div>
          </div>
          {me.role === "owner" ? (
            <ReadOnlyNote icon="shield-check">
              You are the <strong>Account Owner</strong> for {window.MILO_DATA.COMPANY}. Your role is protected and can't be changed or removed from within the platform. If you need to change the account owner please contact Meaningful Planet support to request to transfer ownership.
            </ReadOnlyNote>
          ) : null}
        </div>
      </Card>
    </>
  );
}

/* ---------- Security: change password + two-factor ---------- */
const PW_REQS = [
  { label: "12+ characters",     test: (v) => v.length >= 12 },
  { label: "An uppercase letter", test: (v) => /[A-Z]/.test(v) },
  { label: "A lowercase letter",  test: (v) => /[a-z]/.test(v) },
  { label: "A number",            test: (v) => /\d/.test(v) }
];
const PW_WORDS = ["", "Weak", "Fair", "Good", "Strong"];

function Accordion({ title, sub, open, onToggle, children }) {
  return (
    <div className="mp-acc">
      <button type="button" className="mp-acc-head" onClick={onToggle} aria-expanded={open}>
        <div>
          <h3 className="mp-acc-title">{title}</h3>
          <p className="mp-acc-sub">{sub}</p>
        </div>
        <span className={"mp-acc-caret" + (open ? " is-open" : "")}><Icon name="chevron-down" size={19} /></span>
      </button>
      {open ? <div className="mp-acc-body">{children}</div> : null}
    </div>
  );
}

function SecurityTab() {
  const ctx = useRoles();
  const [open, setOpen] = uP(null);
  const [twoFa, setTwoFa] = uP(false);
  const toggle = (k) => setOpen((o) => o === k ? null : k);
  const S = window.MP_SSO;
  if (S) S.useSso();
  /* An SSO managed member has no password of their own to change. */
  if (S && S.isSsoManaged(ctx.actor)) return window.SsoSecurityNotice ? <window.SsoSecurityNotice member={ctx.actor} /> : null;

  return (
    <>
      <Accordion
        title="Change Password"
        sub="Choose a new password. You'll need to enter your current password to confirm."
        open={open === "password"}
        onToggle={() => toggle("password")}>
        <ChangePasswordForm onDone={() => ctx.toast({ kind: "ok", title: "Password updated", body: "Use your new password the next time you sign in." })} />
      </Accordion>

      <Card>
        <div className="mp-acc-body" style={{ paddingTop: 26 }}>
          <div>
            <h3 className="mp-acc-title">Two-Factor Authentication</h3>
            <p className="mp-acc-sub">
              Currently, you have Two Factor Authentication <strong>{twoFa ? "enabled" : "disabled"}</strong>.
            </p>
            {window.SsoOwnerNote ? <window.SsoOwnerNote /> : null}
          </div>
          <div className="mp-acc-foot" style={{ justifyContent: "flex-start" }}>
            <Button variant="primary" onClick={() => setTwoFa((v) => !v)}>{twoFa ? "Disable" : "Enable"}</Button>
          </div>
        </div>
      </Card>
    </>
  );
}

function ChangePasswordForm({ onDone }) {
  const [pw, setPw] = uP("");
  const [again, setAgain] = uP("");
  const [current, setCurrent] = uP("");
  const [err, setErr] = uP(null);
  const met = PW_REQS.map((r) => r.test(pw));
  const score = pw ? met.filter(Boolean).length : 0;

  const submit = () => {
    if (score < 4) return setErr("Your new password doesn't meet all of the requirements yet.");
    if (again !== pw) return setErr("The two new passwords don't match.");
    if (!current) return setErr("Enter your current password to confirm this change.");
    setErr(null); setPw(""); setAgain(""); setCurrent("");
    onDone();
  };

  return (
    <>
      <div className="mp-field">
        <label className="mp-field-label">New password</label>
        <input className="mp-field-input" type="password" value={pw} placeholder="Create a secure password" onChange={(e) => { setPw(e.target.value); setErr(null); }} />
      </div>
      <div className="mp-pw-strength">
        <div className="mp-pw-bars">
          {[1, 2, 3, 4].map((i) => <span key={i} className={"mp-pw-bar" + (score >= i ? " is-on-" + score : "")} />)}
        </div>
        <div className="mp-pw-label">{score ? <>Password strength: <strong>{PW_WORDS[score]}</strong></> : "Password strength"}</div>
        <div className="mp-pw-reqs">
          {PW_REQS.map((r, i) => (
            <div key={r.label} className={"mp-pw-req" + (met[i] ? " is-met" : "")}>
              <span className="mp-pw-req-dot"><Icon name="check" size={10} /></span>
              <span>{r.label}</span>
            </div>
          ))}
        </div>
      </div>
      <div className="mp-field">
        <label className="mp-field-label">Re-enter new password</label>
        <input className="mp-field-input" type="password" value={again} placeholder="Type the new password again" onChange={(e) => { setAgain(e.target.value); setErr(null); }} />
      </div>
      <div className="mp-field">
        <label className="mp-field-label">Current password</label>
        <input className="mp-field-input" type="password" value={current} placeholder="••••••••" onChange={(e) => { setCurrent(e.target.value); setErr(null); }} />
        {err ? <div className="mp-inline-err"><Icon name="triangle-alert" size={13} /><span>{err}</span></div> : null}
      </div>
      <div className="mp-acc-foot">
        <Button variant="primary" size="lg" onClick={submit}>Update Password</Button>
      </div>
    </>
  );
}

function OrganisationTab() {
  const ctx = useRoles();
  const [org, setOrg] = uP({
    name: window.MILO_DATA.COMPANY,
    address: "Unit 7, Wharf Studios, 12 Canal Street, Manchester M1 3HE",
    contact: "operations@acmeco.co.uk",
    companies_house: "09482716",
    vat: "GB 384 9271 04"
  });
  const canIdentity = ctx.can("org.identity");
  const set = (key, value, what) => {
    setOrg((o) => ({ ...o, [key]: value }));
    ctx.toast({ kind: "ok", title: what + " updated", body: "Your organisation details have been saved." });
  };

  return (
    <>
      <Card>
        <div className="mp-acc-body" style={{ paddingTop: 26 }}>
          <div className="mp-zone-head">
            <div>
              <h3 className="mp-acc-title">Organisation Identity</h3>
              <p className="mp-acc-sub">Who you are on contracts and invoices.</p>
            </div>
            {canIdentity ? null : (
              <span className="mp-viewonly" tabIndex={0}>
                <Badge variant="muted" icon="lock">View only</Badge>
                <span className="mp-viewonly-tip" role="tooltip">These organisation settings can only be changed by the Account Owner.</span>
              </span>
            )}
          </div>
          <div className="mp-ie-list">
            <InlineEditField
              label="Organisation name" value={org.name} editable={canIdentity}
              tipLabel="Rename organisation" modalTitle="Rename organisation"
              modalBody="Use the name your team will recognise. It appears on your invoices and contracts."
              onSave={(next) => { if (!next) return "Enter your organisation's name."; set("name", next, "Organisation name"); }} />
            <InlineEditField
              label="Registered address" value={org.address} editable={canIdentity}
              tipLabel="Edit registered address" modalTitle="Edit registered address"
              modalHelp="The address as registered with Companies House."
              onSave={(next) => { if (!next) return "Enter your registered address."; set("address", next, "Registered address"); }} />
            <InlineEditField
              label="Contact details" value={org.contact} type="email" editable={canIdentity}
              tipLabel="Edit contact details" modalTitle="Edit contact details"
              modalBody="The main address we use for anything about your account."
              onSave={(next) => { if (!window.EMAIL_RE.test(next)) return "Enter a valid email address."; set("contact", next.toLowerCase(), "Contact details"); }} />
            <InlineEditField
              label="Companies House number" value={org.companies_house} editable={canIdentity}
              tipLabel="Edit registration number" modalTitle="Edit Companies House number"
              modalHelp="Eight characters, as shown on the Companies House register."
              onSave={(next) => { if (!/^[A-Z0-9]{8}$/i.test(next)) return "Enter an eight-character Companies House number."; set("companies_house", next.toUpperCase(), "Companies House number"); }} />
            <InlineEditField
              label="VAT number" value={org.vat} placeholder="Not registered" editable={canIdentity}
              tipLabel="Edit VAT number" modalTitle="Edit VAT number"
              modalHelp="Leave blank if your business isn't VAT registered."
              onSave={(next) => set("vat", next, "VAT number")} />
          </div>
        </div>
      </Card>

      {window.SsoCard ? <window.SsoCard /> : null}

      <Card>
        <div className="mp-acc-body" style={{ paddingTop: 26 }}>
          <div>
            <h3 className="mp-acc-title">Billing</h3>
            <p className="mp-acc-sub">Payment details and invoice history are managed securely through Stripe.</p>
          </div>
          <div className="mp-acc-foot" style={{ justifyContent: "flex-start" }}>
            <Button variant="secondary" icon="external-link" onClick={(e) => {
  if (window.DEMO_TOAST) window.DEMO_TOAST("Manage Billing opens in Stripe in the live platform.", e);
}}>Manage Billing in Stripe</Button>
          </div>
        </div>
      </Card>
    </>
  );
}

Object.assign(window, { PW_REQS, PW_WORDS, RulesPage, NewRuleModal, RoleSettingsPage, ProfileTab, PendingEmailRow, InlineEditField, EditFieldModal, SecurityTab, Accordion, ChangePasswordForm, OrganisationTab });
