/* Wellpaged Builder — onboarding.jsx
   The few-screen "what is this" welcome, phone-app style, shown ONCE and only to a
   visitor who arrived from one of our ads (app.jsx: isAdArrival, which mirrors
   functions/lib/attr.js). An ad visitor lands here cold — the middleware sends them
   straight past the homepage — so these slides do the homepage's job in five swipes.
   Someone who came through the homepage already read it and goes straight to the
   CoachTour instead.

   Every illustration is plain DOM + CSS (builder.css, .ob-*): no video, no Lottie,
   nothing extra to download on a phone that just tapped an ad. Each slide's art is
   remounted when it becomes active so its animation plays from the start. */
const { useState: obS, useEffect: obE, useRef: obR } = React;

// Real template thumbnails for the "pick a design" fan. While a season is showing
// (components.jsx CATALOG_META), its designs sit in front.
const OB_FAN = ["riso", "neon", "editorial", "luxury", "claymorphism"];  // index 2 sits in front
const fanFor = (season) => {
  if (!season || !season.templates.length) return OB_FAN;
  const t = season.templates;
  return ["editorial", t[1] || "neon", t[0], "neon", "riso"].filter((v, i, a) => a.indexOf(v) === i).concat(OB_FAN).slice(0, 5);
};

function ObPhoneArt() {
  return (
    <div className="ob-phone" aria-hidden="true">
      <div className="ob-notch" />
      <div className="ob-avatar" />
      <div className="ob-bar ob-bar--name" />
      <div className="ob-bar ob-bar--tag" />
      {[0, 1, 2].map((n) => <div key={n} className={"ob-card" + (n === 0 ? " ob-card--feat" : "")} style={{ "--n": n }}><span className="ob-dot" /><span className="ob-line" /></div>)}
      <div className="ob-socials">{[0, 1, 2, 3].map((n) => <span key={n} style={{ "--n": n }} />)}</div>
    </div>
  );
}

function ObFanArt({ season }) {
  const ids = fanFor(season);
  return (
    <div className="ob-fan" aria-hidden="true">
      {ids.map((id, n) => (
        <div key={id} className="ob-fan-card" style={{ "--n": n, backgroundImage: "url(/previews/" + id + "/thumb.jpg)" }} />
      ))}
    </div>
  );
}

function ObTypeArt() {
  return (
    <div className="ob-type" aria-hidden="true">
      <div className="ob-field"><span className="ob-field-lab">Link title</span><span className="ob-typed">Watch my latest video</span></div>
      <div className="ob-field"><span className="ob-field-lab">Link</span><span className="ob-typed ob-typed--2">youtube.com/@you</span></div>
      <div className="ob-arrow">↓</div>
      <div className="ob-result"><span className="ob-result-ico">▶</span><span>Watch my latest video</span></div>
    </div>
  );
}

function ObBuildArt() {
  return (
    <div className="ob-build" aria-hidden="true">
      <svg className="ob-ring" viewBox="0 0 120 120"><circle cx="60" cy="60" r="52" className="ob-ring-bg" /><circle cx="60" cy="60" r="52" className="ob-ring-fg" /></svg>
      <div className="ob-check">✓</div>
      {[0, 1, 2, 3, 4, 5].map((n) => <span key={n} className="ob-spark" style={{ "--n": n }} />)}
      <div className="ob-price">Free to build</div>
    </div>
  );
}

function ObLiveArt() {
  return (
    <div className="ob-live" aria-hidden="true">
      <div className="ob-url"><span className="ob-lock">🔒</span><span className="ob-url-text">yourname<b>.wellpaged.com</b></span></div>
      <div className="ob-page">
        <div className="ob-edit-line">Hi, I’m <span className="ob-edit-word">you</span> ✎</div>
        <div className="ob-bar" /><div className="ob-bar ob-bar--short" />
        <div className="ob-tap" />
      </div>
    </div>
  );
}

function Onboarding({ designs, onDone }) {
  const [season, setSeason] = obS(null);
  obE(() => { CATALOG_META.then((d) => { if (d && d.season) setSeason(d.season); }); }, []);
  const slides = [
    { art: ObPhoneArt, kicker: "Welcome to Wellpaged", title: <React.Fragment>Your whole online world, <em>on one page.</em></React.Fragment>,
      body: "Links, socials, your story and your rates — on a designed page that looks like you, not like everyone else’s link-in-bio." },
    { art: ObFanArt, kicker: "Step 1 · Pick a look", title: <React.Fragment>Choose from <em>{designs} designs.</em></React.Fragment>,
      body: season
        ? "Clean, bold, retro, dramatic — plus limited-time " + season.label + " designs. Build on one now and it’s yours to keep."
        : "Clean, bold, retro, dramatic — something for every kind of creator. Switch any time; nothing is locked in." },
    { art: ObTypeArt, kicker: "Step 2 · Add your stuff", title: <React.Fragment>Type it once. <em>Watch it appear.</em></React.Fragment>,
      body: "Add your links, a few lines about you and your socials. The preview fills in live as you type." },
    { art: ObBuildArt, kicker: "Step 3 · We build it", title: <React.Fragment>See it first. <em>Pay only if you love it.</em></React.Fragment>,
      body: "Building is free. You review your real, finished page before you pay anything — and you only pay if you launch." },
    { art: ObLiveArt, kicker: "Step 4 · Go live", title: <React.Fragment>yourname<em>.wellpaged.com</em></React.Fragment>,
      body: "Your page goes live at your own address. Change any word or photo right on the page, whenever you like." },
  ];
  const last = slides.length - 1;
  const [i, setI] = obS(0);
  const rootRef = obR(null);
  const drag = obR(null);
  const [dx, setDx] = obS(0);

  // The privacy notice (assets/js/cookie-consent.js) docks at the bottom of the
  // screen for exactly this visitor, and it must stay readable — so make room for
  // it rather than drawing the slides over it.
  const [notice, setNotice] = obS(0);
  obE(() => {
    const measure = () => {
      const el = document.getElementById("wp-cookie");
      const r = el && !el.hidden && getComputedStyle(el).display !== "none" ? el.getBoundingClientRect() : null;
      const h = r && r.height ? Math.ceil(window.innerHeight - r.top) : 0;
      setNotice((p) => (Math.abs(p - h) > 2 ? Math.max(0, h) : p));
    };
    measure();
    const t = setInterval(measure, 400);
    window.addEventListener("resize", measure);
    return () => { clearInterval(t); window.removeEventListener("resize", measure); };
  }, []);

  const go = (n) => setI(Math.max(0, Math.min(last, n)));
  const next = () => (i < last ? go(i + 1) : onDone("done"));

  obE(() => {
    const onKey = (e) => {
      if (e.key === "Escape") onDone("skip");
      else if (e.key === "ArrowRight") setI((x) => Math.min(last, x + 1));
      else if (e.key === "ArrowLeft") setI((x) => Math.max(0, x - 1));
    };
    window.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    try { rootRef.current && rootRef.current.focus(); } catch (e) {}
    return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = prev; };
  }, []);

  // Swipe: follow the finger, then settle on the nearest slide past a 50px pull.
  const onDown = (e) => {
    if (e.pointerType === "mouse" && e.button !== 0) return;
    if (e.target.closest && e.target.closest("button")) return;
    drag.current = { x: e.clientX, y: e.clientY, on: false };
  };
  const onMove = (e) => {
    const d = drag.current; if (!d) return;
    const mx = e.clientX - d.x, my = e.clientY - d.y;
    if (!d.on && Math.abs(mx) > 8 && Math.abs(mx) > Math.abs(my)) d.on = true;
    if (d.on) setDx(mx);
  };
  const onUp = () => {
    const d = drag.current; drag.current = null;
    if (d && d.on) { if (dx < -50) go(i + 1); else if (dx > 50) go(i - 1); }
    setDx(0);
  };

  return (
    <div className="ob" role="dialog" aria-modal="true" aria-roledescription="carousel" aria-label="Welcome to Wellpaged"
         tabIndex={-1} ref={rootRef} style={notice ? { paddingBottom: notice + 12 } : undefined}>
      <div className="ob-glow" aria-hidden="true" />
      <div className="ob-top">
        <span className="ob-mark">WELLPAGED</span>
        <button type="button" className="ob-skip" onClick={() => onDone("skip")}>Skip</button>
      </div>
      <div className="ob-viewport" onPointerDown={onDown} onPointerMove={onMove} onPointerUp={onUp} onPointerCancel={onUp} onPointerLeave={onUp}>
        <div className={"ob-track" + (dx ? " is-drag" : "")} style={{ transform: "translateX(calc(" + (-i * 100) + "% + " + dx + "px))" }}>
          {slides.map((s, n) => {
            const Art = s.art;
            return (
              <section key={n} className={"ob-slide" + (n === i ? " is-on" : "")} aria-roledescription="slide"
                       aria-label={(n + 1) + " of " + slides.length} aria-hidden={n !== i}>
                <div className="ob-art">{n === i && <Art season={season} />}</div>
                <div className="ob-copy">
                  <span className="ob-kicker">{s.kicker}</span>
                  <h2 className="ob-title">{s.title}</h2>
                  <p className="ob-body">{s.body}</p>
                </div>
              </section>
            );
          })}
        </div>
      </div>
      <div className="ob-foot">
        <div className="ob-dots" role="tablist" aria-label="Slides">
          {slides.map((_, n) => (
            <button key={n} type="button" role="tab" aria-selected={n === i} aria-label={"Slide " + (n + 1)}
                    className={"ob-dot-btn" + (n === i ? " on" : "")} onClick={() => go(n)} />
          ))}
        </div>
        <div className="ob-nav">
          {i > 0 && <button type="button" className="btn ob-back" onClick={() => go(i - 1)}>Back</button>}
          <button type="button" className="btn primary ob-next" onClick={next}>{i < last ? "Next" : "Start building →"}</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Onboarding });
