/* ============================================================
   Sumoria Quiz — React app (11-question spec build)
   No opening screen. Rotating formats. State in memory only.
   ============================================================ */
const { useState, useEffect, useRef, useCallback } = React;
const Q = window.QUIZ;

/* ---------- icons ---------- */
const Check = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round">
    <path d="M5 13l4 4L19 7" />
  </svg>
);
const Arrow = () => (
  <svg className="arrow" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
    <path d="M5 12h14M13 6l6 6-6 6" />
  </svg>
);
const BackChevron = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
    <path d="M15 6l-6 6 6 6" />
  </svg>
);
const roomIcons = {
  bath: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 3.5c3.6 4.6 5.5 7.6 5.5 10.3a5.5 5.5 0 0 1-11 0c0-2.7 1.9-5.7 5.5-10.3z" />
    </svg>
  ),
  kitchen: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M7 3v5a2 2 0 0 0 4 0V3" /><path d="M9 8v13" />
      <path d="M17 3c-1.8 0-3 2.6-3 5.5S15.2 13 17 13v8" />
    </svg>
  ),
  living: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 11V9a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v2" />
      <path d="M4 11a2 2 0 0 1 2 2v3h12v-3a2 2 0 0 1 2-2v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1z" />
      <path d="M7 17v2M17 17v2" />
    </svg>
  ),
  home: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 11l8-7 8 7" /><path d="M6 9.5V19h12V9.5" /><path d="M10 19v-5h4v5" />
    </svg>
  ),
};
const benefitIcons = {
  torque: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 3a9 9 0 1 0 9 9" /><path d="M12 12l5-5" /><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none" />
    </svg>
  ),
  handle: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 19L16 8" /><path d="M14 6l4 4" /><circle cx="6" cy="18" r="3" /><path d="M16 4l4 4" />
    </svg>
  ),
  feather: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M20 4c-7 0-11 4-13 9l-2 5 5-2c5-2 9-6 9-13z" /><path d="M16 8l-6 6" />
    </svg>
  ),
};
const ShieldIcon = () => (
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M12 3l7 3v5c0 4.5-3 8-7 10-4-2-7-5.5-7-10V6z" /><path d="M9 12l2 2 4-4" />
  </svg>
);

/* ---------- bold a word inside body text ---------- */
function emphasize(text, word) {
  if (!word || !text.includes(word)) return text;
  const parts = text.split(word);
  const out = [];
  parts.forEach((p, i) => {
    out.push(p);
    if (i < parts.length - 1) out.push(<strong key={i}>{word}</strong>);
  });
  return out;
}

/* ---------- Top bar / progress ---------- */
function TopBar({ step, onBack, canBack }) {
  const isQ = !!Q.questions[step];
  const total = Q.totalQuestions;
  const num = isQ ? Q.questions[step].num : null;

  // most recent question at/before this step (for cards holding progress)
  const order = Q.flow;
  const idx = order.indexOf(step);
  let qNum = 0;
  for (let i = idx; i >= 0; i--) {
    if (Q.questions[order[i]]) { qNum = Q.questions[order[i]].num; break; }
  }
  let pct = (qNum / total) * 100;
  if (step === "loader" || step === "results") pct = 100;

  const hidden = step === "loader" || step === "results";

  return (
    <div className={"topbar" + (hidden ? " hidden" : "")}>
      <div className="topbar-row">
        <button className={"back-btn" + (canBack ? "" : " invisible")} onClick={onBack} aria-label="Go back">
          <BackChevron /> Back
        </button>
        <div className="brand"><span className="dot"></span>SUMORIA</div>
        <div className="qcount">{isQ ? `Question ${num} of ${total}` : "\u00A0"}</div>
      </div>
      <div className="progress-track">
        <div className="progress-fill" style={{ width: pct + "%" }}></div>
      </div>
    </div>
  );
}

/* ---------- shared question chrome ---------- */
function Nudge({ text }) {
  if (!text) return null;
  return (
    <div className="nudge">
      <span className="nudge-dot"></span>{text}
    </div>
  );
}

function FactCard({ fact }) {
  if (!fact) return null;
  return (
    <div className="factcard">
      <div className="factcard-label">{fact.label}</div>
      <p className="factcard-text">{fact.text}</p>
      <div className="factcard-stats">
        {fact.stats.map((s, i) => (
          <div className="factstat" key={i}>
            <div className="factstat-num">{s.num}</div>
            <div className="factstat-label">{s.label}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Single-select (list) ---------- */
function SingleQuestion({ qkey, data, onAnswer }) {
  const [flash, setFlash] = useState(null);
  const locked = useRef(false);
  const pick = (key) => {
    if (locked.current) return;
    locked.current = true;
    setFlash(key);
    setTimeout(() => onAnswer(qkey, key), 320);
  };
  return (
    <div className="screen screen-enter">
      <Nudge text={data.nudge} />
      <FactCard fact={data.fact} />
      <h2 className="qhead">{data.headline}</h2>
      {data.subhead && <p className="subhead small">{data.subhead}</p>}
      <div className="options">
        {data.options.map((o) => (
          <button key={o.key} className={"option" + (flash === o.key ? " flash" : "")} onClick={() => pick(o.key)}>
            <span className="marker"><Check /></span>
            <span className="option-label">{o.label}</span>
          </button>
        ))}
      </div>
    </div>
  );
}

/* ---------- Yes / No (pills) ---------- */
function YesNoQuestion({ qkey, data, onAnswer }) {
  const [flash, setFlash] = useState(null);
  const locked = useRef(false);
  const pick = (key) => {
    if (locked.current) return;
    locked.current = true;
    setFlash(key);
    setTimeout(() => onAnswer(qkey, key), 320);
  };
  return (
    <div className="screen screen-enter">
      <h2 className="qhead">{data.headline}</h2>
      <div className="yesno">
        {data.options.map((o) => (
          <button key={o.key} className={"yesno-btn" + (flash === o.key ? " flash" : "")} onClick={() => pick(o.key)}>
            {o.label}
          </button>
        ))}
      </div>
    </div>
  );
}

/* ---------- Image-select (icon grid) ---------- */
function ImageSelect({ qkey, data, onAnswer }) {
  const [flash, setFlash] = useState(null);
  const locked = useRef(false);
  const pick = (key) => {
    if (locked.current) return;
    locked.current = true;
    setFlash(key);
    setTimeout(() => onAnswer(qkey, key), 320);
  };
  return (
    <div className="screen screen-enter">
      <h2 className="qhead">{data.headline}</h2>
      <div className="img-grid">
        {data.options.map((o) => (
          <button key={o.key} className={"img-card" + (flash === o.key ? " flash" : "")} onClick={() => pick(o.key)}>
            <span className="img-ico">{roomIcons[o.icon]}</span>
            <span className="img-label">{o.label}</span>
          </button>
        ))}
      </div>
    </div>
  );
}

/* ---------- Multi-select ---------- */
function MultiQuestion({ qkey, data, onAnswer }) {
  const [sel, setSel] = useState([]);
  const toggle = (key) => setSel((s) => (s.includes(key) ? s.filter((k) => k !== key) : [...s, key]));
  return (
    <div className="screen screen-enter">
      <Nudge text={data.nudge} />
      <FactCard fact={data.fact} />
      <h2 className="qhead">{data.headline}</h2>
      {data.subhead && <p className="subhead small">{data.subhead}</p>}
      <div className="options">
        {data.options.map((o) => (
          <button key={o.key} className={"option multi" + (sel.includes(o.key) ? " selected" : "")}
            onClick={() => toggle(o.key)} aria-pressed={sel.includes(o.key)}>
            <span className="marker"><Check /></span>
            <span className="option-label">{o.label}</span>
          </button>
        ))}
      </div>
      <div className="btn-stack">
        <button className={"btn" + (sel.length ? "" : " dim")} onClick={() => onAnswer(qkey, sel)}>
          {data.button} <Arrow />
        </button>
      </div>
    </div>
  );
}

/* ---------- Number picker (stepper + quick chips) ---------- */
function NumberPicker({ qkey, data, onAnswer }) {
  const [val, setVal] = useState(data.default ?? 0);
  const holdRef = useRef(null);
  const dec = () => setVal((v) => Math.max(0, v - 1));
  const inc = () => setVal((v) => v + 1);
  const startHold = (fn) => {
    fn();
    let delay = 380;
    const step = () => {
      fn();
      delay = Math.max(60, delay * 0.82);
      holdRef.current = setTimeout(step, delay);
    };
    holdRef.current = setTimeout(step, delay);
  };
  const endHold = () => { clearTimeout(holdRef.current); holdRef.current = null; };
  return (
    <div className="screen screen-enter">
      <h2 className="qhead">{data.headline}</h2>
      {data.subhead && <p className="subhead small">{data.subhead}</p>}
      <div className="numpick">
        <button className="num-step" onPointerDown={() => startHold(dec)} onPointerUp={endHold}
          onPointerLeave={endHold} aria-label="Fewer" disabled={val === 0}>−</button>
        <div className="num-display">
          <span className="num-val">{val}</span>
          <span className="num-unit">{data.unit}</span>
        </div>
        <button className="num-step" onPointerDown={() => startHold(inc)} onPointerUp={endHold}
          onPointerLeave={endHold} aria-label="More">+</button>
      </div>
      <div className="num-quick">
        {data.quick.map((q, i) => {
          const last = i === data.quick.length - 1;
          return (
            <button key={q} className={"num-chip" + (val === q ? " active" : "")} onClick={() => setVal(q)}>
              {q}{last ? "+" : ""}
            </button>
          );
        })}
      </div>
      <div className="btn-stack">
        <button className="btn" onClick={() => onAnswer(qkey, val)}>{data.button} <Arrow /></button>
      </div>
    </div>
  );
}

/* ---------- Slider (1–10) ---------- */
function SliderQuestion({ qkey, data, onAnswer }) {
  const [val, setVal] = useState(data.default);
  const pctPos = ((val - data.min) / (data.max - data.min)) * 100;
  return (
    <div className="screen screen-enter">
      <h2 className="qhead">{data.headline}</h2>
      <div className="slider-wrap">
        <div className="slider-readout"><span className="slider-num">{val}</span><span className="slider-out">/ 10</span></div>
        <div className="slider-track-wrap">
          <input type="range" className="slider" min={data.min} max={data.max} step="1" value={val}
            style={{ "--pct": pctPos + "%" }}
            onChange={(e) => setVal(parseInt(e.target.value, 10))} />
        </div>
        <div className="slider-ends">
          <span>{data.minLabel}</span>
          <span>{data.maxLabel}</span>
        </div>
      </div>
      <div className="btn-stack">
        <button className="btn" onClick={() => onAnswer(qkey, val)}>{data.button} <Arrow /></button>
      </div>
    </div>
  );
}

/* ---------- Intra-quiz Card ---------- */
function Card({ data, answers, path, onNext }) {
  const rv = (f) => (typeof f === "function" ? f(answers, path) : f);

  // special: time-math gut-punch card
  if (data.kind === "math") {
    const hrs = answers.q7h || 0;
    const annual = hrs * 52;
    const days = Math.round(annual / 24);
    return (
      <div className="screen screen-enter stagger">
        <div style={{ animationDelay: "0s" }}>
          <p className="eyebrow pine">{rv(data.lead)}</p>
        </div>
        <div className="mathcard" style={{ animationDelay: "0.06s" }}>
          <div className="math-row">
            <span className="math-chip">{hrs} hrs / week</span>
            <span className="math-x">×</span>
            <span className="math-chip">52 weeks</span>
          </div>
          <div className="math-hero">
            <div className="math-num">{annual.toLocaleString()}</div>
            <div className="math-unit">hours a year, scrubbing</div>
          </div>
          <div className="math-days">That's about <strong>{days} full days</strong> a year.</div>
        </div>
        <p className="inter-body" style={{ animationDelay: "0.12s" }}>{rv(data.closer)}</p>
        <div className="fill"></div>
        <div className="btn-stack" style={{ animationDelay: "0.18s" }}>
          <button className="btn" onClick={onNext}>{data.button} <Arrow /></button>
        </div>
      </div>
    );
  }

  return (
    <div className="screen screen-enter stagger">
      <img className="inter-img" src={data.img} alt="" style={{ animationDelay: "0s" }} />
      <div style={{ animationDelay: "0.08s" }}>
        <h2 className="card-head">{rv(data.head)}</h2>
        <p className="inter-body">{emphasize(rv(data.body), data.boldWord)}</p>
      </div>
      <div className="fill"></div>
      <div className="btn-stack" style={{ animationDelay: "0.16s" }}>
        <button className="btn" onClick={onNext}>{data.button} <Arrow /></button>
      </div>
    </div>
  );
}

/* ---------- Loader ---------- */
function Loader({ onDone }) {
  const [pct, setPct] = useState(0);
  const [microIdx, setMicroIdx] = useState(0);
  const R = 56;
  const C = 2 * Math.PI * R;
  const doneRef = useRef(onDone);
  doneRef.current = onDone;

  useEffect(() => {
    const DUR = 3600;
    const start = performance.now();
    let raf, done = false;
    const finish = () => { if (done) return; done = true; doneRef.current(); };
    const tick = (now) => {
      const t = Math.min(1, (now - start) / DUR);
      const eased = 1 - Math.pow(1 - t, 1.7);
      setPct(Math.round(eased * 100));
      if (t < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    const micro = setInterval(() => setMicroIdx((i) => (i + 1) % Q.loader.micro.length), 1300);
    const fallback = setTimeout(() => { setPct(100); finish(); }, DUR + 400);
    return () => { cancelAnimationFrame(raf); clearInterval(micro); clearTimeout(fallback); };
  }, []);

  return (
    <div className="loader-screen screen-enter">
      <div className="ring-wrap">
        <svg width="132" height="132" viewBox="0 0 132 132">
          <circle className="ring-bg" cx="66" cy="66" r={R} />
          <circle className="ring-fg" cx="66" cy="66" r={R} strokeDasharray={C} strokeDashoffset={C * (1 - pct / 100)} />
        </svg>
        <div className="ring-pct">{pct}%</div>
      </div>
      <div className="loader-head">{Q.loader.head}</div>
      <div className="loader-micro" key={microIdx}>{Q.loader.micro[microIdx]}</div>
    </div>
  );
}

/* ---------- Results ---------- */
function Results({ answers, onRestart }) {
  const { winner } = Q.score(answers);
  const r = Q.results;
  const arc = r.archetypes[winner];
  const tollData = r.vision(answers);
  const sentinel = useRef(null);
  const [showSticky, setShowSticky] = useState(false);

  useEffect(() => {
    const el = sentinel.current;
    if (!el) return;
    const io = new IntersectionObserver(([e]) => setShowSticky(!e.isIntersecting), { rootMargin: "0px 0px -40px 0px" });
    io.observe(el);
    return () => io.disconnect();
  }, []);

  const open = () => window.open(r.productUrl, "_blank", "noopener");

  const InlineCTA = ({ label, note }) => (
    <div className="cta-inline">
      <button className="btn" onClick={open}>{label} <Arrow /></button>
      {note && <p className="cta-inline-note">{note}</p>}
    </div>
  );

  return (
    <div className="screen screen-enter" key="results">
      {/* future-facing vision moment */}
      <div className="toll">
        <p className="eyebrow pine" style={{ textAlign: "center", marginBottom: 6 }}>Here's your new normal</p>
        <p className="vision-lead">Picture next week, once it's handled:</p>
        <div className="toll-grid">
          {tollData.map((t, i) => (
            <div className={"toll-tile" + (i === 0 ? " hero" : "")} key={i}>
              <div className="toll-value">{t.value}</div>
              <div className="toll-label">{t.label}</div>
            </div>
          ))}
        </div>
      </div>

      {/* product reveal */}
      <div className="result-hero">
        <span className="result-badge"><span style={{ fontSize: 13 }}>✦</span> Your Hosting Readiness Profile</span>
        <img src={r.heroImg} alt="ScrubForce Pro" />
      </div>

      {/* diagnosis */}
      <div className="diagnosis">
        <div className="diag-label">You're</div>
        <div className="diag-name">{arc.name}</div>
        <p className="diag-read">{arc.read}</p>
      </div>

      <div className="verdict">
        And the good news is the same for everyone who lands here:{" "}
        <strong>it was never you. It was the equipment.</strong>
      </div>

      <InlineCTA label="Show me the fix" note="The exact tool the pros use — below." />

      <div className="divider"><span>The fix</span></div>

      <h3 className="prescribe-head">Meet the ScrubForce&nbsp;Pro</h3>
      <p className="prescribe-sub">A commercial-grade cordless power scrubber that lets you deep-clean a whole bathroom standing upright — no kneeling, no bending, no scrubbing by hand.</p>

      <div className="benefits">
        {r.benefits.map((b, i) => (
          <div className="benefit" key={i}>
            <div className="ico">{benefitIcons[b.icon]}</div>
            <div>
              <div className="benefit-spec">{b.spec}</div>
              <div className="benefit-copy">{b.copy}</div>
            </div>
          </div>
        ))}
      </div>

      <div className="spec-strip">
        {r.specChips.map((c, i) => <span className="spec-chip" key={i}>{c}</span>)}
      </div>

      <InlineCTA label={r.cta} note="Spring Sale — 9 brush heads free" />

      <div className="brush-block">
        <img src={r.brushImg} alt="The 9 included brush heads" />
        <p className="brush-cap">{r.brushCap}</p>
      </div>

      <div className="proof">
        <p className="eyebrow pine" style={{ textAlign: "center", marginBottom: 14 }}>Real reviews</p>
        {r.testimonials.map((qt, i) => (
          <div className="quote-card faced" key={i}>
            <div className="quote-head">
              <img className="quote-face" src={qt.face} alt={qt.n} loading="lazy" />
              <div>
                <div className="quote-name">{qt.n}<span className="quote-age">, {qt.age}</span></div>
                <div className="quote-meta"><span className="stars">★★★★★</span><span className="verified">✓ Verified buyer</span></div>
              </div>
            </div>
            <p>{qt.t}</p>
          </div>
        ))}
      </div>

      <div className="risk">
        <span className="ico"><ShieldIcon /></span>
        <div>{r.risk.split("60-day money-back guarantee").map((p, i) => i === 0 ? p : <React.Fragment key={i}><strong>60-day money-back guarantee</strong>{p}</React.Fragment>)}</div>
      </div>

      <div ref={sentinel}></div>

      <div className="cta-block">
        <button className="btn" onClick={open}>{r.cta} <Arrow /></button>
        <p className="cta-fine">{r.fine}</p>
      </div>

      <div className={"sticky-cta" + (showSticky ? " show" : "")}>
        <button className="btn" onClick={open}>{r.cta} <Arrow /></button>
      </div>
    </div>
  );
}

/* ============================================================
   App
   ============================================================ */
function App() {
  const params = new URLSearchParams(window.location.search);
  const path = (params.get("path") || "A").toUpperCase() === "B" ? "B" : "A";

  const first = Q.flow[0];
  const [step, setStep] = useState(first);
  const [answers, setAnswers] = useState({});
  const [history, setHistory] = useState([]);
  const scrollRef = useRef(null);

  const go = useCallback((next) => {
    setHistory((h) => [...h, step]);
    setStep(next);
  }, [step]);

  // next step, skipping any card whose skipIf(answers) is true.
  const nextOf = (s, ans) => {
    const a = ans || answers;
    let i = Q.flow.indexOf(s) + 1;
    while (i < Q.flow.length) {
      const st = Q.flow[i];
      const card = Q.cards[st];
      if (card && typeof card.skipIf === "function" && card.skipIf(a)) { i++; continue; }
      return st;
    }
    return Q.flow[Q.flow.length - 1];
  };

  const answer = (qkey, value) => {
    const merged = { ...answers, [qkey]: value };
    setAnswers(merged);
    go(nextOf(qkey, merged));
  };
  const advance = () => go(nextOf(step));

  const back = () => {
    setHistory((h) => {
      if (!h.length) return h;
      setStep(h[h.length - 1]);
      return h.slice(0, -1);
    });
  };

  const restart = () => {
    setAnswers({});
    setHistory([]);
    setStep(first);
  };

  useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = 0;
    window.scrollTo({ top: 0, behavior: "instant" in window ? "instant" : "auto" });
  }, [step]);

  const canBack = history.length > 0 && step !== "loader" && step !== "results";

  let body;
  const qd = Q.questions[step];
  if (qd) {
    const common = { key: step, qkey: step, data: qd, onAnswer: answer };
    if (qd.type === "yesno")      body = <YesNoQuestion {...common} />;
    else if (qd.type === "image") body = <ImageSelect {...common} />;
    else if (qd.type === "number")body = <NumberPicker {...common} />;
    else if (qd.type === "multi") body = <MultiQuestion {...common} />;
    else if (qd.type === "slider")body = <SliderQuestion {...common} />;
    else                          body = <SingleQuestion {...common} />;
  } else if (Q.cards[step]) {
    body = <Card key={step} data={Q.cards[step]} answers={answers} path={path} onNext={advance} />;
  } else if (step === "loader") {
    body = <Loader onDone={() => setStep("results")} />;
  } else if (step === "results") {
    body = <Results answers={answers} onRestart={restart} />;
  }

  return (
    <div className="stage">
      <div className="shell" ref={scrollRef}>
        <TopBar step={step} onBack={back} canBack={canBack} />
        <div className="screen-wrap">{body}</div>
      </div>
    </div>
  );
}

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