// Shared primitives: wireframe "page skeleton" used to explain conversion structure,
// plus the floating island navigation, scroll indicator, and responsive screenshot helpers.
const { useState, useEffect, useRef } = React;

function useInView(threshold = 0.35) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((es) => { es.forEach(e => { if (e.isIntersecting) { setSeen(true); io.disconnect(); } }); }, { threshold });
    io.observe(el);
    return () => io.disconnect();
  }, [threshold]);
  return [ref, seen];
}

function Eyebrow({ children, accent }) {
  return <div className={"eyebrow" + (accent ? " eyebrow--accent" : "")}>{children}</div>;
}

function Bar({ w, h = 8, tone = "mid", r = 2 }) {
  return <div className={"wf-bar wf-bar--" + tone} style={{ width: w, height: h, borderRadius: r }} />;
}

function Lines({ n, tone = "faint", w = ["96%", "88%", "92%", "70%"] }) {
  return <div className="wf-lines">{Array.from({ length: n }).map((_, i) => <Bar key={i} w={w[i % w.length]} h={5} tone={tone} />)}</div>;
}

// Responsive screenshot. WebP at two widths, PNG fallback for old browsers.
// `eager` is for the one comparison above the fold; everything else waits.
function Shot({ name, alt, eager }) {
  return (
    <picture>
      <source
        type="image/webp"
        srcSet={`assets/${name}-768.webp 768w, assets/${name}.webp 1100w`}
        sizes="(max-width: 1000px) 100vw, 700px"
      />
      <img
        src={`assets/${name}.png`}
        alt={alt}
        draggable="false"
        loading={eager ? "eager" : "lazy"}
        decoding="async"
      />
    </picture>
  );
}

// Read position for pages that run ten screens deep on a phone.
function ScrollProgress() {
  const [p, setP] = useState(0);
  useEffect(() => {
    let raf = 0;
    const update = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        const max = document.documentElement.scrollHeight - window.innerHeight;
        setP(max > 0 ? Math.min(1, Math.max(0, window.scrollY / max)) : 0);
      });
    };
    update();
    window.addEventListener("scroll", update, { passive: true });
    window.addEventListener("resize", update);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("scroll", update);
      window.removeEventListener("resize", update);
    };
  }, []);
  return <div className="progress" aria-hidden="true"><span style={{ transform: `scaleX(${p})` }} /></div>;
}

// Floating island nav — the site's only navigation, at every viewport width.
// Closed: a small glass pill detached from the top. Open: a full-screen glass
// overlay with the hamburger morphed into an X and links staggering in.
function IslandNav({ links, ctaHref, email, wordmarkHref = "#top" }) {
  const [open, setOpen] = useState(false);
  const panelRef = useRef(null);
  const btnRef = useRef(null);

  useEffect(() => {
    if (!open) return;
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";

    const focusables = () => panelRef.current
      ? panelRef.current.querySelectorAll('a[href], button:not([disabled])')
      : [];

    const onKey = (e) => {
      if (e.key === "Escape") {
        setOpen(false);
        if (btnRef.current) btnRef.current.focus();
        return;
      }
      if (e.key !== "Tab") return;
      const f = focusables();
      if (!f.length) return;
      const first = f[0];
      const last = f[f.length - 1];
      if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
      else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
    };

    document.addEventListener("keydown", onKey);
    const f = focusables();
    if (f.length) f[0].focus();

    return () => {
      document.body.style.overflow = prevOverflow;
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const close = () => setOpen(false);

  return (
    <>
      <div className="pillnav">
        <a className="wordmark" href={wordmarkHref}>KMY</a>
        <a className="pillnav__cta" href={ctaHref} target="_blank" rel="noopener">Get a free audit</a>
        <button
          ref={btnRef}
          type="button"
          className={"navbtn" + (open ? " is-open" : "")}
          aria-expanded={open}
          aria-controls="kmy-nav-panel"
          aria-label={open ? "Close menu" : "Open menu"}
          onClick={() => setOpen(o => !o)}
        >
          <span className="navbtn__bars" aria-hidden="true"><i /><i /><i /></span>
        </button>
      </div>

      <div id="kmy-nav-panel" className={"mnav" + (open ? " is-open" : "")}>
        <div className="mnav__scrim" onClick={close} />
        <nav className="mnav__panel" ref={panelRef} aria-label="Site">
          {links.map(([href, label], i) => (
            <a className="mnav__link" key={href} href={href} onClick={close} style={{ transitionDelay: (open ? 100 + i * 50 : 0) + "ms" }}>{label}</a>
          ))}
          <a className="mnav__cta kmy-btn kmy-btn--primary kmy-btn--lg" href={ctaHref} target="_blank" rel="noopener" onClick={close} style={{ transitionDelay: (open ? 100 + links.length * 50 : 0) + "ms" }}>
            Get a free website audit
          </a>
          <a className="mnav__mail" href={"mailto:" + email} onClick={close} style={{ transitionDelay: (open ? 150 + links.length * 50 : 0) + "ms" }}>{email}</a>
        </nav>
      </div>
    </>
  );
}

// mode: "weak" | "strong"
function PageSkeleton({ mode, compact }) {
  const strong = mode === "strong";
  return (
    <div className={"wf" + (compact ? " wf--compact" : "")} aria-hidden="true">
      <div className="wf__chrome"><span /><span /><span /></div>
      {strong ? (
        <div className="wf__body">
          <div className="wf__nav">
            <Bar w={26} h={9} tone="bright" />
            <div className="wf__navlinks"><Bar w={22} h={5} tone="mid" /><Bar w={26} h={5} tone="mid" /><Bar w={18} h={5} tone="mid" /></div>
            <div className="wf-pill wf-pill--accent" />
          </div>
          <div className="wf__hero">
            <Bar w="82%" h={14} tone="bright" />
            <Bar w="56%" h={14} tone="bright" />
            <Bar w="64%" h={5} tone="faint" />
            <div className="wf__actions"><div className="wf-pill wf-pill--accent wf-pill--lg" /><Bar w={52} h={10} tone="mid" r={8} /></div>
          </div>
          <div className="wf__proof">
            {[0, 1, 2].map(i => <div className="wf-chip" key={i}><span className="wf-star" /><Bar w={i === 1 ? 30 : 24} h={4} tone="mid" /></div>)}
          </div>
          <div className="wf__svc">
            {[0, 1, 2].map(i => <div className="wf-row" key={i}><Bar w={9} h={9} tone="accentline" r={9} /><Bar w={i === 2 ? "44%" : "58%"} h={6} tone="mid" /><Bar w={10} h={6} tone="faint" /></div>)}
          </div>
          <div className="wf__logos">{[0, 1, 2, 3].map(i => <Bar key={i} w="100%" h={16} tone="plate" r={2} />)}</div>
          <div className="wf__stickybar"><Bar w={64} h={5} tone="mid" /><div className="wf-pill wf-pill--accent" /></div>
        </div>
      ) : (
        <div className="wf__body wf__body--weak">
          <div className="wf__nav wf__nav--crowded">
            <Bar w={18} h={6} tone="mid" />
            <div className="wf__navlinks wf__navlinks--many">{Array.from({ length: 7 }).map((_, i) => <Bar key={i} w={i % 2 ? 22 : 17} h={5} tone="faint" />)}</div>
          </div>
          <div className="wf__slab"><Bar w="42%" h={7} tone="mid" /><Lines n={2} /></div>
          <Lines n={6} />
          <div className="wf__grid4">{[0, 1, 2, 3].map(i => <div className="wf-plate" key={i}><Bar w="70%" h={5} tone="faint" /><Bar w="46%" h={5} tone="faint" /></div>)}</div>
          <Lines n={4} />
          <div className="wf__buried"><Bar w={38} h={4} tone="faint" /></div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { useInView, Eyebrow, Bar, Lines, PageSkeleton, Shot, ScrollProgress, IslandNav });
