// MostlyQR — free static QR generator at /qr-code-generator (the "see the difference" funnel).
// A no-login SEO free-tool like /Barcode: paste a link, download a real static QR (SVG/PNG),
// no sign-up, no watermark, generated entirely in the browser.
//
// The funnel is the page's centrepiece, not a banner: the user's static code renders NEXT TO
// its dynamic twin. The static code encodes the full URL, so it visibly densifies as the URL
// grows; the dynamic twin encodes only a short link (HTTPS://MQR.SH/XXXXX — uppercase, so the
// QR alphanumeric mode keeps it a version lower, see shared.jsx buildMatrix) and never changes.
// The module-count delta is computed live from the real matrices — the benefit is shown, not
// claimed. CTA deep-links to /builder?type=url&dest=<url> (Builder prefills the destination).
//
// English body copy by design (same as /Barcode, /Compare, /Enterprise, /Verify). IIFE-scoped
// so no top-level name leaks into the shared global scope (see enterprise.jsx).
(function () {
const { Icon: IconQG, MQMark: MQMarkQG, Wordmark: WordmarkQG, QR: QRQG, buildMatrix: buildMatrixQG, exportSVG: exportSVGQG, exportPNG: exportPNGQG } = window.MQR;
const { Button: BtnQG } = window.ForgeDesignSystem_e40d74;
const HOME_QG = "/";

// The dynamic twin's payload. QZ72M is the house demo code (see api.js demoLinks); a scan hits
// mqr.sh's clean not-found page, and the caption labels it a preview. Uppercase on purpose:
// alphanumeric mode → fewer modules — that IS the story this page tells.
const DYN_PREVIEW_QG = "HTTPS://MQR.SH/QZ72M";
const SAMPLE_URL_QG = "https://northbrew.co/spring-menu";
const UTM_DEMO_QG = "?utm_source=flyer&utm_medium=print&utm_campaign=spring";

// Visible FAQ — kept IDENTICAL to the `faq` array on the qrgen entry in seo.config.js
// (visible ↔ FAQPage JSON-LD parity, same contract as the compare pages).
const QG_FAQ = [
  { q: "Is this QR code generator really free?", a: "Yes. Paste a link and download your QR code as SVG or PNG — no sign-up, no watermark, no expiry tricks. The code is generated entirely in your browser and the image is yours forever." },
  { q: "What is the difference between a static and a dynamic QR code?", a: "A static QR code encodes your URL directly into the image — it works forever but can never be changed, and the longer the URL, the denser the code. A dynamic QR code encodes a short redirect link (like mqr.sh/QZ72M) instead, so the code stays simple, you can change the destination anytime without reprinting, and every scan can be counted." },
  { q: "Can I change where a QR code points after printing it?", a: "Only with a dynamic code. A static code is fixed forever the moment you create it. A MostlyQR dynamic code encodes a short link you can repoint anytime — fix a typo, swap a menu, or redirect a campaign after the posters are already up. Three dynamic codes are free, no card required." },
  { q: "Why is my QR code so dense and hard to scan?", a: "QR density grows with the amount of text you encode. A long URL with tracking parameters can need a 37×37 grid or more, which means smaller dots that demand bigger prints and closer scans. Encoding a short link instead (what a dynamic QR does) keeps the code at roughly 25×25 with larger dots that scan from farther away." },
  { q: "Do QR codes expire?", a: "A static QR code never expires — it is just your URL drawn as squares. Dynamic codes depend on the provider keeping the redirect alive, and many services kill your codes when a trial ends. MostlyQR dynamic codes never expire — a printed code keeps redirecting to its last destination even if you cancel." },
  { q: "Does this generator track my scans?", a: "No. A static QR code is a plain image — there is nothing to track, and this generator runs entirely in your browser, so your link never leaves your device. If you want scan counts, locations and device stats, that is exactly what a dynamic QR code adds." },
  { q: "Should I download SVG or PNG?", a: "SVG for print — it scales to any size with perfectly sharp edges. PNG for screens, documents and quick sharing. Both downloads are free here." },
  { q: "Can I add a logo and brand colours to my QR code?", a: "Yes — in the MostlyQR builder, which is free to use: colours, shapes, gradients, a centre logo and frames with a call-to-action. Dynamic codes keep extra error-correction headroom so a logo never breaks scannability." },
];

// Module stats from the REAL encoder (shared buildMatrix). n×n grid; version = (n−17)/4.
function qgStats(data) {
  try {
    const n = buildMatrixQG(data, "M").length;
    return { n, version: Math.round((n - 17) / 4) };
  } catch (_e) { return null; }
}

function QrGen() {
  const [url, setUrl] = React.useState(SAMPLE_URL_QG);
  // QR matrices depend on window.qrcode — render them only after mount so the SSR
  // prerender and the first client paint are identical (no hydration mismatch).
  const [mounted, setMounted] = React.useState(false);
  const staticRef = React.useRef(null);
  React.useEffect(() => { setMounted(true); }, []);

  const trimmed = String(url || "").trim();
  const isHttp = /^https?:\/\//i.test(trimmed);
  const looksBareDomain = !!trimmed && !isHttp && /^[a-z0-9-]+(\.[a-z0-9-]+)+([/?#]|$)/i.test(trimmed);
  const hasTags = trimmed.endsWith(UTM_DEMO_QG);

  const stat = mounted && trimmed ? qgStats(trimmed) : null;
  const dyn = mounted ? qgStats(DYN_PREVIEW_QG) : null;
  // Delta on module AREA (n² dark/light cells) — the honest "how much busier" number.
  const delta = stat && dyn && stat.n > dyn.n ? Math.round((1 - (dyn.n * dyn.n) / (stat.n * stat.n)) * 100) : 0;
  // At the same print size, dot size ∝ 1/n → the dynamic code's dots are n_static/n_dyn× bigger.
  const distX = stat && dyn && stat.n > dyn.n ? stat.n / dyn.n : 1;

  // Propagate ?demo=1 so a demo-mode session stays in demo mode across the handoff
  // (also what lets the e2e spec click straight through on the static smoke server).
  let inDemo = false;
  try { inDemo = new URLSearchParams(window.location.search).get("demo") === "1"; } catch (_e) { /* SSR */ }
  const builderHref = "/builder?type=url" + (inDemo ? "&demo=1" : "") + (isHttp ? "&dest=" + encodeURIComponent(trimmed.slice(0, 2048)) : "");

  const toggleTags = () => {
    if (hasTags) { setUrl(trimmed.slice(0, -UTM_DEMO_QG.length)); return; }
    // Demo suffix goes on the path as-is; if the URL already has a query, chain with &.
    setUrl(trimmed + (trimmed.includes("?") ? UTM_DEMO_QG.replace("?", "&") : UTM_DEMO_QG));
  };

  const download = (kind) => {
    const el = staticRef.current;
    if (!el) return;
    if (kind === "svg") exportSVGQG(el, "qr-code"); else exportPNGQG(el, "qr-code");
  };

  return (
    <div className="mk-root ent-root qg-page">
      <header className="mk-nav ent-nav">
        <div className="mk-wrap mk-nav__inner">
          <a className="mk-brand" href={HOME_QG}><MQMarkQG animate /><WordmarkQG /></a>
          <nav className="mk-nav__links"><a href="/#pricing">Pricing</a><a href="/barcode">Barcodes</a><a href="/enterprise">Enterprise</a></nav>
          <div className="mk-nav__cta" />
        </div>
      </header>

      <section className="bc-hero qg-hero">
        <div className="mk-wrap qg-hero__inner">
          <span className="mk-eyebrow" style={{ color: "var(--accent)" }}>Free QR code generator</span>
          <h1 className="ent-h1" style={{ color: "var(--fg)", fontSize: 40 }}>Make a QR code in seconds.</h1>
          <p className="mk-lead" style={{ marginInline: "auto" }}>Paste a link, download SVG or PNG — free, no sign-up, no watermark, generated in your browser. And see, live, what a <a href="#difference">dynamic code</a> would do better.</p>

          <div className="qg-inputrow">
            <input className="bc-input ent-mono qg-input" value={url} placeholder="https://your-site.com/page" onChange={(e) => setUrl(e.target.value)} aria-label="URL to encode" />
            <button type="button" className="qg-chip" data-on={hasTags} onClick={toggleTags} title="Watch the static code densify as the URL grows">
              {hasTags ? "− remove campaign tags" : "+ add campaign tags"}
            </button>
          </div>
          {looksBareDomain && <p className="qg-hint">Tip: include <span className="ent-mono">https://</span> so every camera opens it as a link.</p>}

          <div className="qg-duo" id="difference">
            {/* ── the user's static code ─────────────────────────────── */}
            <div className="qg-card" data-qg="static" data-modules={stat ? stat.n : 0}>
              <div className="qg-card__head">
                <h2 className="qg-card__title">Your static QR</h2>
                <span className="qg-card__tag">encodes the full URL</span>
              </div>
              <div className="qg-qrwrap">
                {mounted && stat
                  ? <QRQG data={trimmed} size={280} innerRef={staticRef} />
                  : <div className="qg-qrph" aria-hidden="true" />}
              </div>
              <p className="qg-stats">{stat ? <><strong>{stat.n}×{stat.n}</strong> modules · version {stat.version} · fixed forever</> : "Type a link above"}</p>
              <div className="bc-actions qg-actions">
                <BtnQG variant="primary" iconRight={<IconQG name="download" size={15} />} onClick={() => download("png")} disabled={!stat}>Download PNG</BtnQG>
                <BtnQG variant="secondary" onClick={() => download("svg")} disabled={!stat}>SVG</BtnQG>
              </div>
            </div>

            {/* ── the dynamic twin ───────────────────────────────────── */}
            <div className="qg-card qg-card--dyn" data-qg="dynamic" data-modules={dyn ? dyn.n : 0}>
              <div className="qg-card__head">
                <h2 className="qg-card__title">The same link, dynamic</h2>
                <span className="qg-card__tag qg-card__tag--dyn">encodes a short link</span>
              </div>
              <div className="qg-qrwrap">
                {mounted && dyn
                  ? <QRQG data={DYN_PREVIEW_QG} size={280} fg="#1d1d5f" />
                  : <div className="qg-qrph" aria-hidden="true" />}
              </div>
              <p className="qg-stats">{dyn ? <><strong>{dyn.n}×{dyn.n}</strong> modules · version {dyn.version} · editable, tracked</> : ""}</p>
              <div className="bc-actions qg-actions">
                <BtnQG variant="primary" iconRight={<IconQG name="arrow" size={15} />} onClick={() => { window.location.href = builderHref; }}>Make it dynamic — free</BtnQG>
              </div>
              <p className="qg-preview-note">Preview — your own short code is minted in the builder. 3 codes free, no card.</p>
            </div>
          </div>

          {mounted && delta > 0 && (
            <p className="qg-delta" data-testid="qg-delta">
              No matter how long your URL gets, the dynamic code stays this simple — right now yours needs <strong>{delta}% more modules</strong>. Printed at the same size, the dynamic code’s dots are <strong>{distX.toFixed(1)}× bigger</strong>, so it scans from farther away and survives smudges and small prints better.
            </p>
          )}

          <p className="vf-foot"><IconQG name="shield" size={14} sw={2.2} /> Generated in your browser — your link never leaves this page · free · no watermark.</p>
        </div>
      </section>

      {/* ── static vs dynamic, honestly ──────────────────────────────── */}
      <section className="qg-table">
        <div className="mk-wrap qg-table__inner">
          <h2 className="qg-h2">Static or dynamic — which do you need?</h2>
          <p className="qg-sub">Both are real QR codes. The difference is what happens after you print.</p>
          <div className="qg-tbl" role="table" aria-label="Static vs dynamic QR comparison">
            <div className="qg-tbl__row qg-tbl__row--head" role="row">
              <div role="columnheader" /> <div role="columnheader">Static (this page)</div> <div role="columnheader" className="qg-tbl__dyn">Dynamic (MostlyQR)</div>
            </div>
            {[
              ["Change the destination after printing", "Never — fixed at creation", "Anytime, without reprinting"],
              ["Scan analytics", "None — it’s just an image", "Scans, cities, devices, time of day"],
              ["Code density", "Grows with your URL", "Always compact — encodes a short link"],
              ["Logo & brand colours", "Plain black & white here", "Full styling in the free builder"],
              ["If you stop paying", "Nothing to pay — the image is yours", "Keeps redirecting forever — codes never expire"],
            ].map((r, i) => (
              <div className="qg-tbl__row" role="row" key={i}>
                <div role="cell" className="qg-tbl__label">{r[0]}</div>
                <div role="cell">{r[1]}</div>
                <div role="cell" className="qg-tbl__dyn">{r[2]}</div>
              </div>
            ))}
          </div>
          <div className="qg-tablecta">
            <BtnQG variant="primary" iconRight={<IconQG name="arrow" size={15} />} onClick={() => { window.location.href = builderHref; }}>Create a dynamic QR — free</BtnQG>
            <span className="qg-tablecta__note">3 dynamic codes free · no card · they never expire</span>
          </div>
        </div>
      </section>

      {/* ── FAQ (mirrors the FAQPage JSON-LD in seo.config.js) ───────── */}
      <section className="qg-faq">
        <div className="mk-wrap qg-faq__inner">
          <h2 className="qg-h2">Questions, answered plainly</h2>
          {QG_FAQ.map((f, i) => (
            <details className="qg-faq__item" key={i}>
              <summary>{f.q}</summary>
              <p>{f.a}</p>
            </details>
          ))}
        </div>
      </section>

      <window.MQRFooter />
    </div>
  );
}

window.MQRQrGen = QrGen;
})();
