/* ========================================================================
   purchase-sims.jsx — Purchase Additional SIMs, in-app (3 screens)

   Ported from the production website checkout, not from travel-buy.jsx:
   configurator + sticky order summary, step breadcrumb, review callout,
   confirmation card and next steps. The marketing top chrome, the
   summary "included" sales list and the promo code block are all out, and
   the small-caps eyebrow treatment is deliberately dropped.

   New capability: choosing which invoice the SIMs appear on.

   This file adds NO route to roles-main.jsx. The router already falls
   through to DashboardPage for unknown paths, so the journey composes over
   it and hands back control when the hash is not ours. No existing file is
   modified.
   ======================================================================== */
const { useState: uQ, useMemo: mQ } = React;
const QD = window.MILO_DATA;

const ROUTE = "/sims/purchase";

const gbpQ = (n) => "£" + Number(n).toFixed(2);
const simCount = (n) => n + (n === 1 ? " SIM" : " SIMs");
const VAT = 0.2;

/* Fictional pricing, per SIM per month excluding VAT. */
const DATA_PLANS = [
  { id: "5gb", label: "5GB", price: 6.50 },
  { id: "10gb", label: "10GB", price: 8.50 },
  { id: "20gb", label: "20GB", price: 11.00 },
  { id: "50gb", label: "50GB", price: 14.50 },
  { id: "unlimited", label: "Unlimited", price: 19.00 }
];

const SIM_TYPES = [
  { id: "esim", label: "eSIM", sub: "Instant activation", icon: "qr-code" },
  { id: "physical", label: "SIM card", sub: "Delivered in 2 to 3 days", icon: "card-sim" }
];

/* Eligible invoices: plain subscriptions only. Data pool subscriptions are
   excluded by rule, since adding SIMs to a pool changes how their data works
   and belongs in its own journey. Oldest first, so the default is the first. */
const INVOICES = [
  { id: 4699, name: "Main account", sims: 24, monthly: 264.00, unnamed: true },
  { id: 4821, name: "Finance Team", sims: 9, monthly: 103.50 },
  { id: 4903, name: "Depot 2", sims: 14, monthly: 154.00 },
  { id: 5012, name: "SUB-5012", sims: 3, monthly: 34.50, unnamed: true }
];

/* Proration: the days left in the month, over its length. */
function prorateFactor() {
  const now = new Date();
  const days = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
  return (days - now.getDate() + 1) / days;
}
const nextBillMonth = () => {
  const n = new Date();
  return new Date(n.getFullYear(), n.getMonth() + 1, 1)
    .toLocaleDateString("en-GB", { day: "numeric", month: "long" });
};

/* ---------- Breadcrumb ---------- */
function Crumb({ step }) {
  const steps = ["Order", "Review", "Confirmed"];
  return (
    <nav className="mp-pj-crumb" aria-label="Purchase progress">
      {steps.map((s, i) =>
        <React.Fragment key={s}>
          <span className={"mp-pj-crumb-item " + (i < step ? "is-done" : i === step ? "is-current" : "is-upcoming")}
            aria-current={i === step ? "step" : undefined}>
            <span className="mp-pj-crumb-num">{i < step ? <Icon name="check" size={11} /> : i + 1}</span>
            <span className="mp-pj-crumb-label">{s}</span>
          </span>
          {i < steps.length - 1 ? <span className="mp-pj-crumb-sep" aria-hidden="true"></span> : null}
        </React.Fragment>
      )}
    </nav>
  );
}

function JourneyHead({ title, sub }) {
  return (
    <div className="mp-pj-head">
      <h1 className="mp-pj-head-title">{title}</h1>
      {sub ? <p className="mp-pj-head-sub">{sub}</p> : null}
    </div>
  );
}

/* ---------- Screen 1: configurator ---------- */
function Configurator({ onAdd, onPending }) {
  const [plan, setPlan] = uQ("");
  const [type, setType] = uQ("");
  const [qty, setQty] = uQ(1);
  const [added, setAdded] = uQ(false);
  const p = DATA_PLANS.find((d) => d.id === plan) || null;
  /* The journey has one live CTA at a time: while a selection is complete but
     not yet added, Add to Order leads and Continue waits. */
  const pending = !!(p && type);
  React.useEffect(() => { if (onPending) onPending(pending); }, [pending]);

  const add = () => {
    if (!p || !type) return;
    onAdd({ planId: plan, planLabel: p.label, price: p.price, type, qty: Number(qty) || 1 });
    setAdded(true);
    setTimeout(() => { setAdded(false); setPlan(""); setType(""); setQty(1); }, 1100);
  };

  return (
    <section className="mp-pj-config">
      <div className="mp-pj-row">
        <header className="mp-pj-row-head">
          <span className="mp-pj-dot"><Icon name="signal" size={16} /></span>
          <h3 className="mp-pj-row-title">Choose data plan</h3>
        </header>
        <div className="mp-pj-plan-grid">
          {DATA_PLANS.map((d) =>
            <button type="button" key={d.id} className={"mp-pj-plan-opt" + (plan === d.id ? " is-active" : "")}
              onClick={() => setPlan(d.id)}>
              <span className="mp-pj-plan-num">{d.label}</span>
              <span className="mp-pj-plan-price">{gbpQ(d.price)}/SIM</span>
              <span className="mp-pj-plan-check" aria-hidden="true"><Icon name="check" size={10} /></span>
            </button>
          )}
        </div>
        <div className="mp-pj-plan-note">
          <Icon name="check" size={14} />
          <span>Unlimited UK calls and texts included with every plan</span>
        </div>
      </div>

      {plan ?
      <div className="mp-pj-row">
        <header className="mp-pj-row-head">
          <span className="mp-pj-dot"><Icon name="smartphone" size={16} /></span>
          <h3 className="mp-pj-row-title">Choose SIM type</h3>
        </header>
        <div className="mp-pj-type-grid">
          {SIM_TYPES.map((s) =>
            <button type="button" key={s.id} className={"mp-pj-type-opt" + (type === s.id ? " is-active" : "")}
              onClick={() => setType(s.id)}>
              <span className="mp-pj-type-icon"><Icon name={s.icon} size={22} /></span>
              <span className="mp-pj-type-body">
                <span className="mp-pj-type-label">{s.label}</span>
                <span className="mp-pj-type-sub">{s.sub}</span>
              </span>
              <span className="mp-pj-type-check" aria-hidden="true"><Icon name="check" size={12} /></span>
            </button>
          )}
        </div>
      </div> : null}

      {plan && type ?
      <div className="mp-pj-row">
        <header className="mp-pj-row-head">
          <span className="mp-pj-dot"><Icon name="hash" size={16} /></span>
          <h3 className="mp-pj-row-title">How many SIMs?</h3>
        </header>
        <div className="mp-pj-qty-row">
          <div className="mp-pj-qty">
            <button type="button" className="mp-pj-qty-btn" aria-label="Decrease quantity"
              disabled={qty <= 1} onClick={() => setQty((q) => Math.max(1, Number(q) - 1))}><Icon name="minus" size={14} /></button>
            <input type="number" className="mp-pj-qty-input" min="1" max="999" value={qty} autoComplete="off"
              onChange={(e) => setQty(e.target.value.replace(/[^0-9]/g, "").slice(0, 3))} />
            <button type="button" className="mp-pj-qty-btn" aria-label="Increase quantity"
              onClick={() => setQty((q) => Math.min(999, Number(q) + 1))}><Icon name="plus" size={14} /></button>
          </div>
          <div className="mp-pj-qty-preview">
            <span>{(Number(qty) || 1)} × {gbpQ(p.price)} =</span>
            <strong>{gbpQ((Number(qty) || 1) * p.price)}</strong>
            <span>/ month excl. VAT</span>
          </div>
          <Button variant={added ? "secondary" : "primary"} icon={added ? "check" : "plus"}
            className="mp-pj-add" onClick={add}>{added ? "Added to Order" : "Add to Order"}</Button>
        </div>
      </div> : null}
    </section>
  );
}

/* ---------- Screen 1: order summary ---------- */
function OrderSummary({ lines, onRemove }) {
  const [incVat, setIncVat] = uQ(false);
  const [pop, setPop] = uQ(false);
  const totalSims = lines.reduce((a, l) => a + l.qty, 0);
  const exVat = lines.reduce((a, l) => a + l.qty * l.price, 0);
  const vat = exVat * VAT;
  const shown = incVat ? exVat + vat : exVat;
  const prorate = shown * prorateFactor();

  return (
    <section className="mp-pj-sum" aria-label="Order summary">
      <header className="mp-pj-sum-head">
        <h2 className="mp-pj-sum-title">Order Summary</h2>
      </header>

      {lines.length === 0 ?
      <div className="mp-pj-sum-empty">
        <span className="mp-pj-sum-empty-ic"><Icon name="shopping-bag" size={18} /></span>
        <p>No SIMs in your order yet. Configure your first plan on the left.</p>
      </div> :
      <>
        <ul className="mp-pj-lines">
          {lines.map((l, i) =>
            <li key={i} className="mp-pj-line">
              <span className="mp-pj-line-ic"><Icon name={l.type === "esim" ? "qr-code" : "card-sim"} size={18} /></span>
              <div className="mp-pj-line-body">
                <div className="mp-pj-line-title">{l.qty} × {l.planLabel} {l.type === "esim" ? "eSIM" : "SIM card"}</div>
                <div className="mp-pj-line-sub">{gbpQ(incVat ? l.price * (1 + VAT) : l.price)}/SIM{incVat ? "" : " excl. VAT"}</div>
              </div>
              <div className="mp-pj-line-price">{gbpQ(l.qty * (incVat ? l.price * (1 + VAT) : l.price))}</div>
              <button type="button" className="mp-pj-line-x" aria-label="Remove line" onClick={() => onRemove(i)}>
                <Icon name="x" size={10} />
              </button>
            </li>
          )}
        </ul>

        <div className="mp-pj-totals">
          <div className="mp-pj-trow">
            <span>Total SIMs</span>
            <span className="mp-pj-trow-val">{totalSims}</span>
          </div>
          {incVat ?
          <div className="mp-pj-trow mp-pj-trow--muted">
            <span>VAT (20%)</span>
            <span>{gbpQ(vat)}</span>
          </div> : null}
          <div className="mp-pj-trow mp-pj-trow--total">
            <span>Monthly total</span>
            <span className="mp-pj-trow-val">
              <strong>{gbpQ(shown)}</strong>
              <em>{incVat ? "inc. VAT / month" : "excl. VAT / month"}</em>
            </span>
          </div>
          <label className="mp-pj-vat" title="Toggle VAT inclusion">
            <input type="checkbox" checked={incVat} onChange={(e) => setIncVat(e.target.checked)} />
            <span className="mp-pj-vat-track"><span className="mp-pj-vat-thumb"></span></span>
            <span className="mp-pj-vat-label">inc. VAT</span>
          </label>
        </div>

        <div className="mp-pj-pro">
          <div className="mp-pj-pro-label">
            This month's bill will be prorated at:
            <span className="mp-pj-pro-help" onMouseEnter={() => setPop(true)} onMouseLeave={() => setPop(false)}>
              <button type="button" className="mp-pj-pro-trigger" aria-label="More information"
                onClick={() => setPop((v) => !v)}><Icon name="info" size={14} /></button>
              {pop ?
              <span className="mp-pj-pro-pop" role="dialog">
                Your first bill is prorated for the days remaining this month. After that, you will be billed monthly at your selected plan rate on the 1st day of each month.
              </span> : null}
            </span>
          </div>
          <div className="mp-pj-pro-val">{gbpQ(prorate)}</div>
          <div className="mp-pj-pro-note">From next month you will pay the full monthly amount.</div>
        </div>
      </>}
    </section>
  );
}

/* ---------- Screen 2: the invoice selector ---------- */
function InvoiceSelector({ invoices, value, onChange, newName, onNewName }) {
  const [open, setOpen] = uQ(false);
  React.useEffect(() => {
    if (!open) return;
    const close = () => setOpen(false);
    window.addEventListener("click", close);
    return () => window.removeEventListener("click", close);
  }, [open]);

  /* Where there is no eligible subscription the selector does not render and
     the order proceeds as a new invoice. */
  if (!invoices.length) return null;

  const isNew = value === "new";
  const picked = invoices.find((i) => String(i.id) === String(value)) || null;
  const label = isNew ? "Create a New Invoice" : picked ? picked.name : "";

  return (
    <div className="mp-pj-inv">
      <h2 className="mp-pj-inv-title">Confirm which invoice to add these SIMs to</h2>
      <div className="mp-pj-inv-row">
        <span className="mp-pj-inv-label">Adding to</span>
        <div className="mp-pj-inv-pick" onClick={(e) => e.stopPropagation()}>
          <button type="button" className="mp-pj-inv-trigger" onClick={() => setOpen((v) => !v)}
            aria-haspopup="listbox" aria-expanded={open}>
            <span>{label}</span>
            <Icon name="chevron-down" size={16} />
          </button>
          {open ?
          <div className="mp-pj-inv-menu" role="listbox">
            {invoices.map((inv) =>
              <button type="button" key={inv.id} role="option" aria-selected={String(inv.id) === String(value)}
                className={"mp-pj-inv-opt" + (String(inv.id) === String(value) ? " is-selected" : "")}
                onClick={() => { onChange(String(inv.id)); setOpen(false); }}>
                <span className="mp-pj-inv-opt-body">
                  <span className="mp-pj-inv-opt-name">{inv.name}</span>
                  <span className="mp-pj-inv-opt-meta">{inv.sims} SIMs · {gbpQ(inv.monthly)}/month</span>
                </span>
                {String(inv.id) === String(value) ?
                  <Icon name="check" size={16} className="mp-pj-inv-opt-tick" /> : null}
              </button>
            )}
            <div className="mp-pj-inv-sep"></div>
            <button type="button" role="option" aria-selected={isNew}
              className={"mp-pj-inv-opt" + (isNew ? " is-selected" : "")}
              onClick={() => { onChange("new"); setOpen(false); }}>
              <span className="mp-pj-inv-opt-body">
                <span className="mp-pj-inv-opt-name">Create a New Invoice</span>
              </span>
              {isNew ? <Icon name="check" size={16} className="mp-pj-inv-opt-tick" /> : null}
            </button>
          </div> : null}
        </div>
      </div>
      <div className="mp-pj-inv-note">
        {isNew ?
          <>These SIMs will start a new invoice from {nextBillMonth()}.</> :
          <>These SIMs will appear on this invoice from {nextBillMonth()}.</>}
      </div>
      {isNew ?
      <div className="mp-pj-inv-name">
        <div className="mp-field">
          <label className="mp-field-label">Invoice Name (Optional)</label>
          <input className="mp-field-input" value={newName} placeholder="For example, Sales Team"
            onChange={(e) => onNewName(e.target.value)} />
          <div className="mp-field-hint">Name this invoice so your team can recognise it later. You can change it at any time.</div>
        </div>
      </div> : null}
    </div>
  );
}

/* ---------- Screen 2 ---------- */
function ReviewScreen({ lines, invoices, invoice, setInvoice, newName, setNewName, onBack, onConfirm, isOwner }) {
  const exVat = lines.reduce((a, l) => a + l.qty * l.price, 0);
  const prorate = exVat * prorateFactor();
  const hasPhysical = lines.some((l) => l.type === "physical");

  return (
    <>
      <Crumb step={1} />
      <JourneyHead title="Review and Confirm" sub="Check the order and choose which invoice it appears on." />

      <div className="mp-pj-review">
        <div className="mp-pj-rrow">
          <span className="mp-pj-rrow-label">Billing to</span>
          <span className="mp-pj-rrow-val">{QD.COMPANY} · finance@acmeindustries.com</span>
        </div>
        {hasPhysical ?
        <div className="mp-pj-rrow">
          <span className="mp-pj-rrow-label">Delivery address</span>
          <span className="mp-pj-rrow-val">Unit 4, Waterside Park, Leeds, LS10 1AB</span>
        </div> : null}
        <div className="mp-pj-rrow">
          <span className="mp-pj-rrow-label">Paying with</span>
          <span className="mp-pj-rrow-val">
            Visa ending 4242
            {!isOwner ? <span className="mp-pj-rrow-note">This is billed to your account owner.</span> : null}
          </span>
        </div>
        <div className="mp-pj-rrow mp-pj-rrow--bill">
          <span className="mp-pj-rrow-label">Initial charge</span>
          <span className="mp-pj-rrow-val"><strong>{gbpQ(prorate)}</strong> excl. VAT, prorated</span>
        </div>
      </div>

      <InvoiceSelector invoices={invoices} value={invoice} onChange={setInvoice}
        newName={newName} onNewName={setNewName} />

      <div>
        <div className="mp-pj-foot">
          <Button variant="secondary" icon="arrow-left" onClick={onBack}>Back to Order</Button>
          <Button variant="primary" onClick={onConfirm}>Confirm and Pay</Button>
        </div>
        <p className="mp-pj-foot-note">This is added to your next invoice and charged to your saved payment method.</p>
      </div>
    </>
  );
}

/* ---------- Screen 3 ---------- */
function ConfirmedScreen({ lines, invoiceName, startedNew }) {
  const totalSims = lines.reduce((a, l) => a + l.qty, 0);
  const exVat = lines.reduce((a, l) => a + l.qty * l.price, 0);
  const prorate = exVat * prorateFactor();
  const hasPhysical = lines.some((l) => l.type === "physical");
  const hasEsim = lines.some((l) => l.type === "esim");

  const steps = [];
  if (hasPhysical) steps.push({ icon: "package", title: "SIM Delivery", body: "Your physical SIMs will arrive in 2 to 3 working days. Activation instructions are in the packaging." });
  if (hasEsim) steps.push({ icon: "qr-code", title: "eSIM Activation", body: "Your eSIMs are ready to activate. Assign each one to a user, then send them the install instructions." });
  steps.push({ icon: "user-plus", title: "Assign Your SIMs", body: "Assign these SIMs to users from SIM Management so they can start using them." });
  if (hasPhysical) steps.push({ icon: "arrow-right-left", title: "Number Transfer", body: "Keeping an existing number? Start a transfer from the SIM's details page." });
  steps.push({ icon: "headset", title: "Support", body: "Visit the help site, use Live Chat, or email support@meaningfulplanet.co.uk." });

  return (
    <>
      <Crumb step={2} />
      <div className="mp-pj-confirm">
        <div className="mp-pj-hero">
          <span className="mp-pj-hero-mark"><Icon name="check" size={28} /></span>
          <div>
            <div className="mp-pj-hero-ref">Order MP-4821</div>
            <h1 className="mp-pj-hero-title">Order Confirmed</h1>
            <p className="mp-pj-hero-sub">{simCount(totalSims)} added. A confirmation has been sent to finance@acmeindustries.com.</p>
          </div>
        </div>

        <div className="mp-pj-card">
          <div className="mp-pj-card-head">
            <h2>Your Order</h2>
            <span className="mp-pj-card-meta">{simCount(totalSims)}</span>
          </div>
          <ul className="mp-pj-clines">
            {lines.map((l, i) =>
              <li key={i} className="mp-pj-cline">
                <span className="mp-pj-cline-ic"><Icon name={l.type === "esim" ? "qr-code" : "card-sim"} size={20} /></span>
                <div className="mp-pj-line-body">
                  <div className="mp-pj-line-title">{l.qty} × {l.planLabel} {l.type === "esim" ? "eSIM" : "SIM card"}</div>
                  <div className="mp-pj-line-sub">{gbpQ(l.price)}/SIM excl. VAT</div>
                </div>
                <div className="mp-pj-cline-price">{gbpQ(l.qty * l.price)}</div>
              </li>
            )}
          </ul>
          <div className="mp-pj-ctot">
            <span>Monthly total</span>
            <span><strong>{gbpQ(exVat)}</strong> excl. VAT</span>
          </div>

          <div className="mp-pj-callout">
            <span className="mp-pj-callout-ic"><Icon name="calendar-clock" size={18} /></span>
            <div>
              <div className="mp-pj-callout-title">Your initial charge is {gbpQ(prorate)} excl. VAT</div>
              <div className="mp-pj-callout-sub">This is charged pro rata, for the days remaining this month. It is added to your next invoice rather than taken today. From {nextBillMonth()} you will pay the full monthly amount.</div>
            </div>
          </div>

          <div className="mp-pj-callout">
            <span className="mp-pj-callout-ic"><Icon name="file-text" size={18} /></span>
            <div>
              <div className="mp-pj-callout-title">Appearing on {invoiceName}</div>
              <div className="mp-pj-callout-sub">{startedNew ?
                "These SIMs start a new invoice, billed separately from your other SIMs. You can rename it from Billing at any time." :
                "These SIMs join your existing invoice. Your next bill will cover your whole estate on this invoice."}</div>
            </div>
          </div>
        </div>

        <div className="mp-pj-next">
          <h2>What happens next</h2>
          <ol className="mp-pj-next-list">
            {steps.map((s, i) =>
              <li key={s.title} className="mp-pj-next-item">
                <span className="mp-pj-next-num">{i + 1}</span>
                <div>
                  <div className="mp-pj-next-title"><Icon name={s.icon} size={16} />{s.title}</div>
                  <div className="mp-pj-next-text">{s.body}</div>
                </div>
              </li>
            )}
          </ol>
        </div>

        <div className="mp-pj-foot">
          <Button variant="primary" href="#/sims">Go to SIM Management</Button>
          <Button variant="secondary" href="#/subscriptions">View Invoice</Button>
        </div>
      </div>
    </>
  );
}

/* ---------- The journey ---------- */
function PurchaseSimsPage({ tweaks }) {
  const ctx = window.useRoles ? window.useRoles() : null;
  const [step, setStep] = uQ(0);
  const [lines, setLines] = uQ([]);
  const [invoice, setInvoice] = uQ(String(INVOICES[0].id));
  const [newName, setNewName] = uQ("");
  const [pending, setPending] = uQ(false);
  React.useEffect(() => { if (window.lucide) { try { window.lucide.createIcons(); } catch (e) {} } });

  /* Both selector states are reviewable from the demo panel's own tweaks
     where present; the no-eligible-invoice variant is the empty list. */
  const noInvoices = /[?&]invoices=none/.test(location.hash) ||
    (tweaks && tweaks.purchase_invoices === "none");
  const invoices = noInvoices ? [] : INVOICES;
  const isOwner = !ctx || ctx.role === "owner";

  const startedNew = invoices.length === 0 || invoice === "new";
  const invoiceName = startedNew
    ? (newName.trim() || "a new invoice")
    : (invoices.find((i) => String(i.id) === String(invoice)) || INVOICES[0]).name;

  if (step === 2) return (
    <PurchaseShell>
      <ConfirmedScreen lines={lines} invoiceName={invoiceName} startedNew={startedNew} />
    </PurchaseShell>
  );

  if (step === 1) return (
    <PurchaseShell>
      <ReviewScreen lines={lines} invoices={invoices} invoice={invoice} setInvoice={setInvoice}
        newName={newName} setNewName={setNewName} isOwner={isOwner}
        onBack={() => setStep(0)}
        onConfirm={() => {
          setStep(2);
          if (ctx) ctx.toast({ kind: "ok", title: "Order confirmed", body: simCount(lines.reduce((a, l) => a + l.qty, 0)) + " added to your account." });
        }} />
    </PurchaseShell>
  );

  return (
    <PurchaseShell>
      <Crumb step={0} />
      <JourneyHead title="Build Your Order"
        sub="Choose a data allowance, a SIM type and how many you need. You can combine eSIMs and physical SIMs in one order." />
      <div className="mp-pj">
        <div className="mp-pj-left">
          <Configurator onAdd={(l) => setLines((ls) => ls.concat([l]))} onPending={setPending} />
          <div className="mp-pj-foot">
            <Button variant={lines.length && !pending ? "primary" : "secondary"} iconAfter="arrow-right"
              className={lines.length ? "" : "is-disabled"}
              onClick={lines.length ? () => setStep(1) : undefined}>Continue to Review</Button>
          </div>
        </div>
        <div className="mp-pj-right">
          <OrderSummary lines={lines} onRemove={(i) => setLines((ls) => ls.filter((_, x) => x !== i))} />
        </div>
      </div>
    </PurchaseShell>
  );
}

/* The journey carries its own heading, so no PageHead above it: production's
   checkout goes breadcrumb, then section head. */
function PurchaseShell({ children }) {
  return (
    <>
      <BackLink href="#/sims">Back to SIMs</BackLink>
      {children}
    </>
  );
}

/* ---------- Mounting without touching the router ----------
   #/sims/purchase is matched by the router's `parts[0] === "sims" && parts[1]`
   branch, which reaches SimShowPage with id="purchase" long before the final
   fallthrough. So SimShowPage is the component to wrap, not DashboardPage.
   Anything that is not our id hands straight back. Gated on sim.order. */
(function mount() {
  const Show = window.SimShowPage;
  if (!Show) return;
  window.SimShowPage = function SimShowOrPurchase(props) {
    if (String(props.id) !== "purchase") return <Show {...props} />;
    if (!window.MP_ALLOW("sim.order")) return <window.PermissionDeniedPage />;
    /* Keyed on the hash: the router's path is unchanged by a query string, so
       without this a variant link would inherit the previous journey state. */
    return <PurchaseSimsPage key={location.hash} {...props} />;
  };
})();

Object.assign(window, { PurchaseSimsPage, PURCHASE_SIMS_ROUTE: ROUTE });

/* ---------- The entry point now has somewhere to go ----------
   Purchase Additional SIM Plans showed the "not available in this demo"
   popover because no in-app journey existed. On this page it does, so the
   button becomes a normal link to it. Patched here rather than in
   pages-1.jsx or data-pool.jsx, which this branch must not modify. */
(function repointEntry() {
  const wire = () => {
    document.querySelectorAll("button, a").forEach((el) => {
      if (el.dataset.pjWired) return;
      if (el.textContent.trim() !== "Purchase Additional SIM Plans") return;
      el.dataset.pjWired = "1";
      el.addEventListener("click", (e) => {
        e.preventDefault();
        e.stopImmediatePropagation();
        location.hash = "/sims/purchase";
      }, true);
    });
  };
  const obs = new MutationObserver(wire);
  const start = () => {
    const root = document.getElementById("app") || document.getElementById("root") || document.body;
    wire();
    obs.observe(root, { childList: true, subtree: true });
  };
  start();
})();
