// Maple Pavers Explorer — GALLERY (before/after), 5 variants.
(function () {
  const { Badge } = window.MaplePaversDesignSystem_8de4d8;
  const { Icon, Overline, PHOTO } = window.MP;
  const G = window.MP.data.gallery;
  const BEFORE = 'grayscale(0.9) brightness(0.62) contrast(0.92)';

  const Heading = ({ onDark, sub }) => (
    <div style={{ textAlign: 'center', marginBottom: 24 }}>
      <Overline onDark>Recent Work</Overline>
      <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 28, lineHeight: 1.12, color: onDark ? 'var(--beige-150)' : 'var(--text-strong)', margin: '10px 0 0' }}>See what we've built.</h2>
      {sub && <p style={{ fontFamily: 'var(--font-body)', fontSize: 13.5, color: 'var(--text-muted)', margin: '8px auto 0', maxWidth: 300 }}>{sub}</p>}
    </div>
  );

  // Reusable interactive before/after slider. Accepts an `item` from MP.data.gallery.
  // If the item has real `before` + `after` images, both are used. Otherwise we fall
  // back to the legacy grayscale-on-after fake (single `img`).
  function BASlider({ item, height = 230, label }) {
    const [pos, setPos] = React.useState(52);
    const ref = React.useRef(null);
    const beforeImg = item.before || item.img;
    const afterImg = item.after || item.img;
    const beforeFilter = item.before ? 'none' : BEFORE;
    const set = (clientX) => {
      const r = ref.current.getBoundingClientRect();
      setPos(Math.max(2, Math.min(98, ((clientX - r.left) / r.width) * 100)));
    };
    const down = (e) => {
      e.preventDefault();
      const move = (ev) => set(ev.touches ? ev.touches[0].clientX : ev.clientX);
      move(e.nativeEvent);
      const up = () => {
        window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up);
      };
      window.addEventListener('pointermove', move); window.addEventListener('pointerup', up);
    };
    return (
      <div className="mp-ba" ref={ref} style={{ height, borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow)' }} onPointerDown={down}>
        <div style={{ position: 'absolute', inset: 0, backgroundImage: `url(${PHOTO}${beforeImg})`, backgroundSize: 'cover', backgroundPosition: 'center', filter: beforeFilter }} />
        <span style={{ position: 'absolute', top: 12, left: 12, zIndex: 3 }}><Badge variant="on-dark" size="sm">Before</Badge></span>
        <div className="mp-ba-after" style={{ clipPath: `inset(0 ${100 - pos}% 0 0)` }}>
          <div style={{ position: 'absolute', inset: 0, backgroundImage: `url(${PHOTO}${afterImg})`, backgroundSize: 'cover', backgroundPosition: 'center' }} />
          <span style={{ position: 'absolute', top: 12, right: 12 }}><Badge variant="solid" size="sm">After</Badge></span>
        </div>
        <div className="mp-ba-handle" style={{ left: `${pos}%` }}>
          <div className="mp-ba-knob"><Icon name="move-h" size={18} /></div>
        </div>
        {label && <span style={{ position: 'absolute', bottom: 12, left: 12, zIndex: 3, fontFamily: 'var(--font-body)', fontSize: 12, fontWeight: 700, whiteSpace: 'nowrap', color: 'var(--beige-150)', textShadow: '0 1px 4px rgba(0,0,0,0.6)' }}>{label}</span>}
      </div>
    );
  }

  // V1 — Interactive slider + horizontally-scrollable thumbnail rail
  function GalSlider() {
    const items = G;
    const [active, setActive] = React.useState(0);
    const railRef = React.useRef(null);
    const didMount = React.useRef(false);

    // Auto-scroll the active thumb into view so it's never hidden offscreen.
    // Skip on initial render — the gallery sits mid-page, and scrolling thumb 0
    // into view at mount would yank the whole page down past the hero.
    React.useEffect(() => {
      if (!didMount.current) {
        didMount.current = true;
        return;
      }
      const rail = railRef.current;
      if (!rail) return;
      const btn = rail.children[active];
      if (!btn) return;
      // Use the rail's own scrollLeft (not Element.scrollIntoView, which can
      // scroll the whole document on engines that don't honor block:'nearest').
      const target = btn.offsetLeft - (rail.clientWidth - btn.clientWidth) / 2;
      rail.scrollTo({ left: target, behavior: 'smooth' });
    }, [active]);

    return (
      <section style={{ background: 'var(--color-bg)', padding: '52px 22px' }}>
        <Heading sub="Drag to reveal the transformation. Swipe the thumbs for more." />
        <BASlider item={items[active]} label={items[active].title} />
        <div
          ref={railRef}
          className="mp-hide-sb"
          style={{
            display: 'flex',
            gap: 8,
            marginTop: 12,
            // Negative side margins + matching padding let the rail bleed to
            // the section edges so the next thumb visibly peeks past the
            // content boundary — strong "more here, swipe" affordance.
            marginLeft: -22,
            marginRight: -22,
            paddingLeft: 22,
            paddingRight: 22,
            overflowX: 'auto',
            overflowY: 'hidden',
            scrollSnapType: 'x mandatory',
            WebkitOverflowScrolling: 'touch',
          }}
        >
          {items.map((it, i) => (
            <button
              key={it.title}
              onClick={() => setActive(i)}
              aria-label={it.title}
              style={{
                flex: '0 0 80px',
                height: 56,
                padding: 0,
                border: i === active ? '2px solid var(--terracotta)' : '1px solid var(--border-default)',
                borderRadius: 'var(--radius)',
                overflow: 'hidden',
                cursor: 'pointer',
                background: `center/cover url(${PHOTO}${it.img})`,
                scrollSnapAlign: 'center',
                transition: 'border-color 0.2s',
              }}
            />
          ))}
        </div>
      </section>
    );
  }

  // V2 — Masonry grid with tags
  function GalGrid() {
    return (
      <section style={{ background: 'var(--beige-300)', padding: '52px 22px' }}>
        <Heading />
        <div style={{ columnCount: 2, columnGap: 10 }}>
          {G.map((it, i) => (
            <div key={it.title} style={{ breakInside: 'avoid', marginBottom: 10, position: 'relative', borderRadius: 'var(--radius)', overflow: 'hidden', boxShadow: 'var(--shadow-sm)' }}>
              <img src={PHOTO + it.img} alt={it.title} style={{ width: '100%', display: 'block', height: i % 3 === 0 ? 180 : 130, objectFit: 'cover' }} />
              <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 50%, rgba(26,26,26,0.7))' }} />
              <span style={{ position: 'absolute', bottom: 10, left: 10 }}><Badge variant="on-dark" size="sm">{it.cat}</Badge></span>
            </div>
          ))}
        </div>
      </section>
    );
  }

  // V3 — Swipe carousel with dots
  function GalCarousel() {
    const [i, setI] = React.useState(0);
    const ref = React.useRef(null);
    const onScroll = () => {
      const el = ref.current; if (!el) return;
      setI(Math.round(el.scrollLeft / el.clientWidth));
    };
    return (
      <section style={{ background: 'var(--color-bg)', padding: '52px 0' }}>
        <div style={{ padding: '0 22px' }}><Heading /></div>
        <div ref={ref} onScroll={onScroll} className="mp-hide-sb" style={{ display: 'flex', overflowX: 'auto', scrollSnapType: 'x mandatory', gap: 0 }}>
          {G.slice(0, 6).map((it) => (
            <div key={it.title} style={{ flex: '0 0 100%', scrollSnapAlign: 'center', padding: '0 22px', boxSizing: 'border-box' }}>
              <div style={{ position: 'relative', height: 250, borderRadius: 'var(--radius-lg)', overflow: 'hidden', boxShadow: 'var(--shadow)' }}>
                <img src={PHOTO + it.img} alt={it.title} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 55%, rgba(26,26,26,0.8))' }} />
                <div style={{ position: 'absolute', bottom: 16, left: 16 }}>
                  <Badge variant="solid" size="sm">{it.cat}</Badge>
                  <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 21, color: 'var(--beige-150)', margin: '8px 0 0' }}>{it.title}</h3>
                </div>
              </div>
            </div>
          ))}
        </div>
        <div style={{ display: 'flex', justifyContent: 'center', gap: 7, marginTop: 16 }}>
          {G.slice(0, 6).map((_, d) => (
            <span key={d} style={{ width: d === i ? 20 : 7, height: 7, borderRadius: 999, background: d === i ? 'var(--terracotta)' : 'var(--border-default)', transition: 'all var(--dur)' }} />
          ))}
        </div>
      </section>
    );
  }

  // V4 — Side-by-side before|after stacked
  function GalSplit() {
    const items = G.slice(0, 2);
    return (
      <section style={{ background: 'var(--graphite)', padding: '52px 22px' }}>
        <Heading onDark sub="No staged stock photos. Actual driveways we tore out and rebuilt." />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
          {items.map((it) => (
            <div key={it.title}>
              <div style={{ display: 'flex', gap: 6 }}>
                <div style={{ flex: 1, position: 'relative', height: 130, borderRadius: 'var(--radius)', overflow: 'hidden' }}>
                  <div style={{ position: 'absolute', inset: 0, backgroundImage: `url(${PHOTO}${it.img})`, backgroundSize: 'cover', backgroundPosition: 'center', filter: BEFORE }} />
                  <span style={{ position: 'absolute', bottom: 8, left: 8 }}><Badge variant="on-dark" size="sm">Before</Badge></span>
                </div>
                <div style={{ flex: 1, position: 'relative', height: 130, borderRadius: 'var(--radius)', overflow: 'hidden' }}>
                  <img src={PHOTO + it.img} alt={it.title} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                  <span style={{ position: 'absolute', bottom: 8, right: 8 }}><Badge variant="solid" size="sm">After</Badge></span>
                </div>
              </div>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-on-dark-muted)', marginTop: 8 }}>{it.title} · {it.cat}</div>
            </div>
          ))}
        </div>
      </section>
    );
  }

  // V5 — Category chips + filmstrip
  function GalFilmstrip() {
    const cats = ['All', ...Array.from(new Set(G.map((g) => g.cat)))];
    const [cat, setCat] = React.useState('All');
    const items = G.filter((g) => cat === 'All' || g.cat === cat);
    return (
      <section style={{ background: 'var(--beige-300)', padding: '52px 0' }}>
        <div style={{ padding: '0 22px' }}><Heading /></div>
        <div className="mp-hide-sb" style={{ display: 'flex', gap: 8, overflowX: 'auto', padding: '0 22px 14px' }}>
          {cats.map((c) => (
            <button key={c} onClick={() => setCat(c)} style={{ flex: 'none', padding: '8px 16px', borderRadius: 999, border: '1px solid ' + (c === cat ? 'var(--terracotta)' : 'var(--border-default)'), background: c === cat ? 'var(--terracotta)' : 'transparent', color: c === cat ? '#fff' : 'var(--text-body)', fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 11.5, letterSpacing: '0.06em', textTransform: 'uppercase', cursor: 'pointer' }}>{c}</button>
          ))}
        </div>
        <div className="mp-hide-sb" style={{ display: 'flex', gap: 10, overflowX: 'auto', padding: '0 22px', scrollSnapType: 'x mandatory' }}>
          {items.map((it) => (
            <div key={it.title} style={{ flex: '0 0 180px', scrollSnapAlign: 'start' }}>
              <div style={{ position: 'relative', height: 200, borderRadius: 'var(--radius-lg)', overflow: 'hidden', boxShadow: 'var(--shadow)' }}>
                <img src={PHOTO + it.img} alt={it.title} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 55%, rgba(26,26,26,0.78))' }} />
                <div style={{ position: 'absolute', bottom: 12, left: 12, right: 12 }}>
                  <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 16, color: 'var(--beige-150)', margin: 0 }}>{it.title}</h3>
                </div>
              </div>
            </div>
          ))}
          <div style={{ flex: '0 0 12px' }} />
        </div>
      </section>
    );
  }

  window.MP.register('gallery', {
    label: 'Gallery',
    options: [
      { id: 'slider', name: '1 · Before/after slider', Render: GalSlider },
      { id: 'grid', name: '2 · Masonry grid', Render: GalGrid },
      { id: 'carousel', name: '3 · Swipe carousel', Render: GalCarousel },
      { id: 'split', name: '4 · Before | After split', Render: GalSplit },
      { id: 'filmstrip', name: '5 · Filtered filmstrip', Render: GalFilmstrip },
    ],
  });
})();
