// nbiot.io — domain acquisition listing page (production).

const { useState, useEffect, useRef } = React;
const { TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakColor, TweakToggle, TweakText } = window;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#f0a040",
  "live": true,
  "showSpectrum": true,
  "headline": "A narrow band. A wide market.",
  "price": "$15,000"
}/*EDITMODE-END*/;

const ACCENT_OPTIONS = [
  "#f0a040",
  "#7ee0a8",
  "#7eb8ff",
  "#ff6f5e",
];

// ─────────────────────────────────────────────────────────────────
// Bot-resistant contact email — never expose "@" in HTML source.
// Display: "info [at] linespotting.com"
// Click  : assembles a real mailto: at click time.
// ─────────────────────────────────────────────────────────────────
const EMAIL_USER = "info";
const EMAIL_DOMAIN = "linespotting.com";
const EMAIL_DISPLAY = `${EMAIL_USER} [at] ${EMAIL_DOMAIN}`;

function buildMailto(subject, body) {
  // String.fromCharCode(64) === "@" — assembled at runtime so HTML source is clean.
  const at = String.fromCharCode(64);
  const params = [];
  if (subject) params.push("subject=" + encodeURIComponent(subject));
  if (body) params.push("body=" + encodeURIComponent(body));
  const qs = params.length ? "?" + params.join("&") : "";
  return "mailto:" + EMAIL_USER + at + EMAIL_DOMAIN + qs;
}

function MailLink({ subject, body, children, className }) {
  return (
    <a
      href="#"
      className={className}
      onClick={(e) => {
        e.preventDefault();
        window.location.href = buildMailto(subject, body);
      }}
    >
      {children || EMAIL_DISPLAY}
    </a>
  );
}

// ─────────────────────────────────────────────────────────────────
// Top bar
// ─────────────────────────────────────────────────────────────────
function TopBar() {
  return (
    <header className="topbar">
      <div className="topbar-inner">
        <div className="brand">
          <span className="brand-dot" />
          <span className="mono">domain//listing</span>
        </div>
        <nav className="topnav mono">
          <a href="#listing">listing</a>
          <a href="#fit">fit</a>
          <a href="#buyers">buyers</a>
          <a href="#acquire">acquire</a>
        </nav>
        <div className="topbar-status mono">
          <span className="status-pill"><span className="dot live" /> LIVE</span>
          <LiveTicker />
        </div>
      </div>
    </header>
  );
}

// ─────────────────────────────────────────────────────────────────
// Hero
// ─────────────────────────────────────────────────────────────────
function Hero({ headline, price }) {
  return (
    <section className="hero">
      <PulseRings />
      <div className="hero-inner">
        <div className="hero-meta mono">
          <span>LISTING / 2026-005</span>
          <span className="sep">·</span>
          <span>STATUS: AVAILABLE</span>
          <span className="sep">·</span>
          <span>EXCLUSIVE</span>
        </div>

        <h1 className="wordmark">
          <span className="wm-name">nbiot</span><span className="wm-dot">.</span><span className="wm-tld">io</span>
          <span className="wm-cursor" />
        </h1>

        <p className="hero-headline">
          {headline}
        </p>

        <p className="hero-sub">
          The exact-match domain for <em>NB-IoT</em> — the 3GPP narrowband cellular standard
          powering an estimated <strong>2.4 billion</strong> low-power devices by 2030.
          One owner. One transfer. One asking price.
        </p>

        <div className="hero-cta">
          <MailLink
            className="btn btn-primary"
            subject={`nbiot.io — Acquire at ${price} USD`}
            body={`Hi,\n\nI'd like to acquire nbiot.io at the ${price} USD asking price.\n\nMy company / full name: \nPreferred escrow service: \nExpected transfer timeline: \n\nThanks,`}
          >
            <span>Acquire for {price}</span>
            <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
              <path d="M3 8h10m0 0L9 4m4 4L9 12" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="square"/>
            </svg>
          </MailLink>
          <a href="#inquire" className="btn btn-ghost">Make an offer</a>
          <span className="hero-cta-note mono">
            Escrow.com · 7-day transfer · invoice on request
          </span>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Spectrum block
// ─────────────────────────────────────────────────────────────────
function SpectrumBlock({ live }) {
  return (
    <section className="spectrum-block" aria-label="NB-IoT spectrum visualization">
      <div className="spec-head">
        <span className="mono small dim">FIG. 01 — DOWNLINK SPECTRUM, 1.4 MHz WINDOW</span>
        <span className="mono small dim">SOURCE: 3GPP TS 36.211</span>
      </div>
      <Spectrum height={200} live={live} />
      <div className="spec-foot mono small">
        <span><span className="legend-swatch accent" /> NB-IoT carrier — 200 kHz, in-band w/ LTE</span>
        <span><span className="legend-swatch line" /> Adjacent LTE PRBs</span>
        <span className="dim">The whole product category fits in the orange band.</span>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Listing card — auction-style spec sheet
// ─────────────────────────────────────────────────────────────────
function ListingCard({ price }) {
  const rows = [
    ["Domain",         "nbiot.io"],
    ["TLD",            ".io — Indian Ocean ccTLD, premium tech"],
    ["Length",         "5 letters · 8 chars total"],
    ["Pronounceable",  "yes — ‘N-B-eye-oh-tee dot eye-oh’"],
    ["Semantic match", "exact — NB-IoT (3GPP cellular standard)"],
    ["Trademark",      "clear — generic technical term"],
    ["Registered",     "2017 · 9 years held"],
    ["Renewal",        "paid through 2027"],
    ["DNS",            "fully delegated, no encumbrances"],
    ["Email history",  "none — clean reputation"],
    ["Backlinks",      "≈ 14 referring domains, all editorial"],
  ];
  return (
    <section id="listing" className="listing">
      <div className="section-head">
        <span className="mono small dim">§ 01</span>
        <h2 className="section-title">The listing.</h2>
      </div>

      <div className="listing-grid">
        <div className="listing-card">
          <div className="listing-card-head mono small">
            <span>LOT // <span className="accent-text">nbiot.io</span></span>
            <span className="dim">REF 2026-005</span>
          </div>

          <div className="listing-price">
            <div className="price-label mono small dim">ASKING / FIXED</div>
            <div className="price-value">
              <span className="price-currency">USD</span>
              <span className="price-amount">{price.replace("$","").replace(" ","")}</span>
            </div>
            <div className="price-sub mono small">
              <span>≈ €13,950</span>
              <span className="sep">·</span>
              <span>≈ £11,820</span>
              <span className="sep">·</span>
              <span>≈ ◎ 0.215 BTC</span>
            </div>
          </div>

          <div className="listing-actions">
            <MailLink
              className="btn btn-primary btn-block"
              subject={`nbiot.io — Buy now at ${price} USD`}
              body={`Hi,\n\nI'd like to buy nbiot.io at the ${price} USD asking price.\n\nMy company / full name: \nPreferred escrow service: \nExpected transfer timeline: \n\nThanks,`}
            >Buy Now — {price}</MailLink>
            <a href="#inquire" className="btn btn-ghost btn-block">Submit private offer</a>
          </div>

          <ul className="listing-features mono small">
            <li><span className="ok">✓</span> Escrow.com hold-and-release</li>
            <li><span className="ok">✓</span> Push at registrar (Namecheap → yours)</li>
            <li><span className="ok">✓</span> Wire, ACH, USDC, BTC accepted</li>
            <li><span className="ok">✓</span> Invoice + bill of sale provided</li>
          </ul>
        </div>

        <div className="listing-specs">
          <div className="specs-head mono small dim">
            <span>SPEC SHEET</span>
            <span>v1 · last verified 2026-04-30</span>
          </div>
          <dl className="specs">
            {rows.map(([k, v]) => (
              <div className="spec-row" key={k}>
                <dt className="mono small dim">{k}</dt>
                <dd>{v}</dd>
              </div>
            ))}
          </dl>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Why / fit
// ─────────────────────────────────────────────────────────────────
function Fit({ price }) {
  return (
    <section id="fit" className="fit">
      <div className="section-head">
        <span className="mono small dim">§ 02</span>
        <h2 className="section-title">Why this domain costs what it costs.</h2>
      </div>

      <div className="fit-grid">
        <div className="fit-card">
          <div className="fit-num serif">01</div>
          <h3>Exact match for a category, not a brand.</h3>
          <p>
            "NB-IoT" is the 3GPP-standardised name for narrowband cellular IoT.
            Every operator brochure, sensor datasheet, and module spec sheet uses
            those four letters. Owning <span className="mono">nbiot.io</span> is
            owning the URL people type when they already know what they want.
          </p>
        </div>
        <div className="fit-card">
          <div className="fit-num serif">02</div>
          <h3>The TLD does the work of a tagline.</h3>
          <p>
            <span className="mono">.io</span> reads as "input/output" to every
            engineer on earth. Pair it with a hardware standard and the domain
            tells your buyer what you do before the page loads. No wordmark,
            no pun, no misspelling.
          </p>
        </div>
        <div className="fit-card">
          <div className="fit-num serif">03</div>
          <h3>5 letters. 4 syllables. Zero ambiguity.</h3>
          <p>
            Short enough to fit in a logo lockup, an SDK package name, a
            T-shirt, a business card. Long enough that no one else on the
            planet has a legitimate prior claim. There is exactly one
            <span className="mono"> nbiot.io</span>.
          </p>
        </div>
        <div className="fit-card">
          <div className="fit-num serif">04</div>
          <h3>Priced like infrastructure, not jewellery.</h3>
          <p>
            {price} is a single seat of enterprise CRM, three days of contractor
            time, a corner of a trade-show booth. For a category-defining
            domain it is a rounding error — and you only pay it once.
          </p>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Buyer profiles
// ─────────────────────────────────────────────────────────────────
function Buyers() {
  const cards = [
    {
      tag: "OPERATOR",
      title: "Cellular IoT operator",
      lines: [
        "MVNO or tier-1 launching a narrowband service tier",
        "Need a destination URL for SIM-management portal",
        "Want a domain that survives a rebrand"
      ],
    },
    {
      tag: "OEM",
      title: "Module / sensor OEM",
      lines: [
        "Quectel, u-blox, Sierra-style hardware vendor",
        "Need a developer-facing portal: docs, AT commands, firmware",
        "Want a domain engineers can remember from a slide"
      ],
    },
    {
      tag: "PLATFORM",
      title: "Asset-tracking platform",
      lines: [
        "Logistics, agriculture, utilities, smart-meter co.",
        "Need credibility with telecom procurement teams",
        "Want SEO inheritance for ‘NB-IoT’ search intent"
      ],
    },
    {
      tag: "STARTUP",
      title: "Stealth IoT startup",
      lines: [
        "Pre-seed to Series A, hardware-adjacent",
        "Need a name and a domain in the same week",
        "Want to skip the naming agency"
      ],
    },
    {
      tag: "INVESTOR",
      title: "Domain portfolio holder",
      lines: [
        "Long the cellular-IoT thesis through 2030",
        "Want a holdable, defensible category match",
        "Comp: iot.com sold $7M, lora.io sold $42k"
      ],
    },
    {
      tag: "ENTERPRISE",
      title: "Industrial conglomerate",
      lines: [
        "Bosch, Siemens, GE-tier with an IoT subsidiary",
        "Need a clean URL for a spinout or product line",
        "Want to never explain the name again"
      ],
    },
  ];
  return (
    <section id="buyers" className="buyers">
      <div className="section-head">
        <span className="mono small dim">§ 03</span>
        <h2 className="section-title">Who this domain is for.</h2>
      </div>
      <div className="buyers-grid">
        {cards.map((c, i) => (
          <article className="buyer-card" key={i}>
            <div className="buyer-tag mono small">{c.tag}</div>
            <h3 className="buyer-title serif">{c.title}</h3>
            <ul>
              {c.lines.map((l, j) => <li key={j}>{l}</li>)}
            </ul>
          </article>
        ))}
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Comparable sales — ground the price
// ─────────────────────────────────────────────────────────────────
function Comps() {
  const comps = [
    { d: "iot.com",     p: "$7,000,000", y: "2014", n: "exact category, .com" },
    { d: "ai.com",      p: "$11,000,000", y: "2023", n: "letter category, .com" },
    { d: "lora.io",     p: "$42,000",    y: "2021", n: "competing LPWAN std" },
    { d: "5g.io",       p: "$28,500",    y: "2022", n: "adjacent cellular gen" },
    { d: "modbus.io",   p: "$18,400",    y: "2023", n: "industrial protocol" },
    { d: "zigbee.io",   p: "$22,000",    y: "2020", n: "competing IoT std" },
    { d: "nbiot.io",    p: "$15,000",    y: "2026", n: "← you are here", here: true },
  ];
  return (
    <section className="comps">
      <div className="section-head">
        <span className="mono small dim">§ 04</span>
        <h2 className="section-title">Comparable sales.</h2>
      </div>
      <div className="comps-table mono small">
        <div className="comps-row comps-head">
          <span>DOMAIN</span>
          <span>PRICE</span>
          <span>YEAR</span>
          <span>NOTE</span>
        </div>
        {comps.map((c, i) => (
          <div key={i} className={"comps-row" + (c.here ? " here" : "")}>
            <span className="d">{c.d}</span>
            <span className="p">{c.p}</span>
            <span className="y dim">{c.y}</span>
            <span className="n dim">{c.n}</span>
          </div>
        ))}
      </div>
      <p className="comps-note small dim">
        Public sales data via NameBio &amp; DNJournal. nbiot.io is priced below every relevant
        LPWAN comp, and three orders of magnitude below its TLD-up cousin.
      </p>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Acquire — process timeline
// ─────────────────────────────────────────────────────────────────
function Acquire({ price }) {
  const steps = [
    { t: "T+0",     h: "You click Buy Now", b: "Or submit a private offer. We respond inside 24h, usually faster." },
    { t: "T+1d",    h: "Escrow opens",      b: "Escrow.com transaction created in your name. We pay the 0.89% fee." },
    { t: "T+2d",    h: "You wire / pay",    b: "Wire, ACH, USDC, or BTC. Funds land in escrow, not in our pocket." },
    { t: "T+3d",    h: "Domain pushed",     b: "Account-level push at Namecheap, or auth-code transfer to your registrar." },
    { t: "T+5d",    h: "You confirm",       b: "DNS resolves to your nameservers. Whois shows your contact." },
    { t: "T+7d",    h: "Funds release",     b: "Escrow.com releases payment. Bill of sale issued. Done." },
  ];
  return (
    <section id="acquire" className="acquire">
      <div className="section-head">
        <span className="mono small dim">§ 05</span>
        <h2 className="section-title">From click to keys, in seven days.</h2>
      </div>
      <ol className="timeline">
        {steps.map((s, i) => (
          <li key={i} className="step">
            <span className="step-time mono small">{s.t}</span>
            <span className="step-rule" />
            <div className="step-body">
              <div className="step-h">{s.h}</div>
              <div className="step-b dim">{s.b}</div>
            </div>
          </li>
        ))}
      </ol>
      <div className="acquire-cta">
        <a href="#inquire" className="btn btn-primary btn-lg">Acquire nbiot.io for {price}</a>
        <span className="dim small">No agent. No commission. Direct from owner.</span>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Inquiry form — POSTs to /api/contact (Cloudflare Pages Function +
// Brevo). Falls back to mailto if the API call fails so a buyer never
// hits a true dead-end.
// ─────────────────────────────────────────────────────────────────
function Inquire({ price }) {
  const askNumeric = price.replace(/[^0-9]/g, "") || "15000";
  const [state, setState] = useState({
    company: "", email: "", offer: askNumeric, note: "",
    company_website: "", // honeypot — must stay empty
  });
  const [status, setStatus] = useState({ phase: "idle", error: "" });

  const submit = async (e) => {
    e.preventDefault();
    setStatus({ phase: "sending", error: "" });

    try {
      const r = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          source: "nbiot.io",
          company: state.company,
          email: state.email,
          offer: state.offer,
          note: state.note,
          company_website: state.company_website,
        }),
      });
      const data = await r.json().catch(() => ({}));
      if (r.ok && data.ok) {
        setStatus({ phase: "sent", error: "" });
      } else {
        // API failed — fall back to mailto so the buyer can still reach us.
        setStatus({ phase: "fallback", error: data.error || ("HTTP " + r.status) });
        const subject = `nbiot.io — Inquiry from ${state.company || "(company)"} — offer $${state.offer}`;
        const body =
          `Company: ${state.company}\n` +
          `Email:   ${state.email}\n` +
          `Offer:   $${state.offer} USD\n\n` +
          `Note:\n${state.note}\n`;
        setTimeout(() => { window.location.href = buildMailto(subject, body); }, 600);
      }
    } catch (err) {
      setStatus({ phase: "fallback", error: String(err) });
      const subject = `nbiot.io — Inquiry from ${state.company || "(company)"} — offer $${state.offer}`;
      const body =
        `Company: ${state.company}\n` +
        `Email:   ${state.email}\n` +
        `Offer:   $${state.offer} USD\n\n` +
        `Note:\n${state.note}\n`;
      setTimeout(() => { window.location.href = buildMailto(subject, body); }, 600);
    }
  };

  return (
    <section id="inquire" className="inquire">
      <div className="inquire-grid">
        <div>
          <div className="section-head">
            <span className="mono small dim">§ 06</span>
            <h2 className="section-title">Inquire.</h2>
          </div>
          <p className="inquire-lede">
            Direct line to the owner. No broker, no auto-responder. We read every
            message and reply within one business day. Offers below ask are
            considered if you tell us who you are.
          </p>
          <ul className="inquire-list mono small">
            <li><span className="dim">EMAIL ·</span> <MailLink /></li>
            <li><span className="dim">SIGNAL ·</span> on request</li>
            <li><span className="dim">JURISDICTION ·</span> Delaware, USA</li>
            <li><span className="dim">RESPONSE SLA ·</span> ≤ 24h, M–F</li>
          </ul>
        </div>

        {status.phase === "sent" ? (
          <div className="form form-sent">
            <div className="mono small dim">// MESSAGE TRANSMITTED</div>
            <h3 className="serif">Thanks — we'll be in touch.</h3>
            <p>
              Your inquiry is queued. Expect a reply from{" "}
              <span className="mono">{EMAIL_DISPLAY}</span> within 24 hours.
            </p>
            <button
              type="button"
              className="btn btn-ghost"
              onClick={() => setStatus({ phase: "idle", error: "" })}
            >
              Send another
            </button>
          </div>
        ) : (
          <form className="form" onSubmit={submit} noValidate>
            <label className="field">
              <span>Company</span>
              <input
                required
                value={state.company}
                onChange={e => setState({ ...state, company: e.target.value })}
                placeholder="Quectel Wireless / etc."
              />
            </label>
            <label className="field">
              <span>Email</span>
              <input
                required type="email"
                value={state.email}
                onChange={e => setState({ ...state, email: e.target.value })}
                placeholder="you at company.com"
              />
            </label>
            <label className="field">
              <span>Offer (USD)</span>
              <div className="input-prefix">
                <span className="mono prefix">$</span>
                <input
                  required inputMode="numeric"
                  value={state.offer}
                  onChange={e => setState({ ...state, offer: e.target.value.replace(/[^0-9]/g, "") })}
                />
              </div>
              <span className="field-hint mono small dim">
                Ask is {price}. Lower offers reviewed if accompanied by context.
              </span>
            </label>
            <label className="field">
              <span>Note (optional)</span>
              <textarea
                rows="3"
                value={state.note}
                onChange={e => setState({ ...state, note: e.target.value })}
                placeholder="What you're building, when you need the domain, terms you'd like…"
              />
            </label>
            {/* Honeypot — bots fill this, humans don't see it */}
            <label
              aria-hidden="true"
              tabIndex={-1}
              style={{ position: "absolute", left: "-10000px", width: "1px", height: "1px", overflow: "hidden" }}
            >
              Company website
              <input
                type="text"
                tabIndex={-1}
                autoComplete="off"
                value={state.company_website}
                onChange={e => setState({ ...state, company_website: e.target.value })}
              />
            </label>

            <button
              type="submit"
              className="btn btn-primary btn-block"
              disabled={status.phase === "sending"}
            >
              {status.phase === "sending" ? "Transmitting…" : "Transmit inquiry"}
            </button>

            {status.phase === "fallback" && (
              <p className="mono small dim" style={{ marginTop: 10 }}>
                Server unreachable — opening your email client as a fallback…
              </p>
            )}
          </form>
        )}
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────
// Footer
// ─────────────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer className="footer">
      <div className="footer-grid mono small">
        <div>
          <div className="dim">DOMAIN</div>
          <div>nbiot.io</div>
        </div>
        <div>
          <div className="dim">STATUS</div>
          <div><span className="dot live" /> available</div>
        </div>
        <div>
          <div className="dim">PRICE</div>
          <div>USD 15,000 fixed</div>
        </div>
        <div>
          <div className="dim">ESCROW</div>
          <div>escrow.com</div>
        </div>
        <div>
          <div className="dim">CONTACT</div>
          <div><MailLink /></div>
        </div>
        <div>
          <div className="dim">UPLINK</div>
          <div><LiveTicker /></div>
        </div>
      </div>
      <div className="footer-mark serif">nbiot<span className="accent-text">.</span>io</div>
      <div className="footer-fine mono small dim">
        © 2026 — domain offered for sale by current registrant. No affiliation with 3GPP, GSMA, or any standards body.
      </div>
    </footer>
  );
}

// ─────────────────────────────────────────────────────────────────
// App
// ─────────────────────────────────────────────────────────────────
function App() {
  const [t, set] = useTweaks(TWEAK_DEFAULTS);

  // apply accent
  useEffect(() => {
    const hex = t.accent;
    document.documentElement.style.setProperty("--accent", hex);
    document.documentElement.style.setProperty("--accent-2", hex);
  }, [t.accent]);

  return (
    <>
      <TopBar />
      <main>
        <Hero headline={t.headline} price={t.price} />
        {t.showSpectrum && <SpectrumBlock live={t.live} />}
        <ListingCard price={t.price} />
        <Fit price={t.price} />
        <Buyers />
        <Comps />
        <Acquire price={t.price} />
        <Inquire price={t.price} />
      </main>
      <Footer />
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
