function WorkCard({ item, onOpen }) {
  const { Card, Badge, Button } = window.ArnelBiscarraDesignSystem_2766cb;
  return (
    <Card padding={0} style={{ height: '100%', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <div className="work-click" onClick={() => onOpen(item)}>
        <div className="work-thumb">
          {item.img
            ? <img src={item.img} alt={item.title} loading="lazy" style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center top', display: 'block' }} />
            : <image-slot id={`work-${item.id}`} shape="rect" fit="contain" placeholder={item.title}></image-slot>}
        </div>
        <div className="work-body">
          <div className="work-badges"><Badge variant="neutral">{item.badge}</Badge></div>
          <div className="work-title">{item.title}</div>
          <div className="work-desc" dangerouslySetInnerHTML={{ __html: item.desc }}></div>
          {item.cta && (
            <div style={{ marginTop: 'auto' }}>
              <Button variant="dark" size="sm" arrow onClick={(e) => { e.stopPropagation(); window.open(item.href || '#', '_blank'); }}>
                {item.cta}
              </Button>
            </div>
          )}
        </div>
      </div>
    </Card>
  );
}

function WorkScrollCard({ item, onOpen }) {
  return (
    <div className="ws-card">
      <div className="ws-card-media" onClick={() => onOpen(item)}>
        {item.img
          ? <img src={item.img} alt={item.title} loading="lazy" />
          : <image-slot id={`work-${item.id}`} shape="rect" fit="contain" placeholder={item.title}></image-slot>}
      </div>
      <div className="ws-card-info">
        <div className="ws-card-title">{item.title}</div>
        <div className="ws-card-desc" dangerouslySetInnerHTML={{ __html: item.desc }}></div>
        <div className="ws-card-tags">
          <span className="ws-tag">{item.badge}</span>
          {item.href && <span className="ws-tag" onClick={(e) => { e.stopPropagation(); window.open(item.href, '_blank'); }}>Visit Site</span>}
        </div>
      </div>
    </div>
  );
}

function WorkScrollGallery({ items, onOpen }) {
  const pinRef = React.useRef(null);
  const trackRef = React.useRef(null);
  const introRef = React.useRef(null);

  React.useEffect(() => {
    const pin = pinRef.current, track = trackRef.current, intro = introRef.current;
    if (!pin || !track) return;
    // Mobile keeps the same vertical-drives-horizontal pin scroll as desktop
    // (mobile pin tuning lives in css/responsive.css).
    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) return;

    let current = 0, target = 0;
    const computeTarget = () => {
      const rect = pin.getBoundingClientRect();
      const total = pin.offsetHeight - window.innerHeight;
      if (total <= 0) { target = 0; return; }
      const progress = Math.max(0, Math.min(1, -rect.top / total));
      const maxScroll = Math.max(0, track.scrollWidth - track.parentElement.clientWidth);
      target = -progress * maxScroll;
    };

    // This used to run unconditionally for the page's entire lifetime —
    // a forced getBoundingClientRect() every frame, 60x/sec, even while
    // scrolling through totally unrelated sections. Now gated by an
    // IntersectionObserver so the loop only runs while this (tall,
    // 160-320vh) pinned section is anywhere near the viewport.
    let rafId = null;
    const loop = () => {
      computeTarget();
      current += (target - current) * 0.08;
      if (Math.abs(target - current) < 0.05) current = target;
      track.style.transform = `translate3d(${current}px,0,0)`;
      if (intro) {
        const fadeDist = 260;
        const opacity = Math.max(0, 1 - Math.abs(current) / fadeDist);
        intro.style.opacity = opacity;
        intro.style.pointerEvents = opacity < 0.05 ? 'none' : '';
      }
      rafId = requestAnimationFrame(loop);
    };
    const startLoop = () => { if (rafId === null) rafId = requestAnimationFrame(loop); };
    const stopLoop = () => { if (rafId !== null) { cancelAnimationFrame(rafId); rafId = null; } };

    const io = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) startLoop(); else stopLoop();
    }, { rootMargin: '50% 0px 50% 0px' });
    io.observe(pin);

    window.addEventListener('resize', computeTarget);
    return () => {
      stopLoop();
      io.disconnect();
      window.removeEventListener('resize', computeTarget);
    };
  }, [items.length]);

  return (
    <div className="work-scroll-pin" ref={pinRef} style={{ height: `${Math.min(Math.max(items.length * 55, 160), 320)}vh` }}>
      <div className="work-scroll-stage">
        <div className="ws-intro" ref={introRef}>
          <div className="eyebrow"><b>/</b> SELECTED WORK</div>
          <h3 className="ws-intro-title">Websites, Built to Perform.</h3>
          <p className="ws-intro-desc">A look at the sites I've designed and developed — fast, modern, and made to convert.</p>
          <div className="ws-scroll-cta">SCROLL <span>&rarr;</span></div>
        </div>
        <div className="work-scroll-track" ref={trackRef}>
          {items.map((item) => (
            <div className="work-scroll-card" key={item.id}>
              <WorkScrollCard item={item} onOpen={onOpen} />
            </div>
          ))}
          <div className="ws-outro">
            <div className="eyebrow"><b>/</b> AND MORE</div>
            <h3 className="ws-intro-title">More Than What's Shown.</h3>
            <p className="ws-intro-desc">The projects featured here are only a small selection of my work. I've built 10+ additional websites for clients over the years. Some are no longer online due to expired hosting, domain renewals, or business closures.</p>
          </div>
        </div>
      </div>
    </div>
  );
}

function Work() {
  const { Tag } = window.ArnelBiscarraDesignSystem_2766cb;
  const data = window.SITE_DATA;
  const [filter, setFilter] = React.useState('All');
  const [active, setActive] = React.useState(null);

  const visible = (cat) => filter === 'All' || filter === cat;
  const printItems = data.work.filter((w) => w.cat === 'Print');
  const otherItems = data.work.filter((w) => w.cat !== 'Print');
  const websiteItems = data.work.filter((w) => w.cat === 'Websites');
  const logoApparelItems = data.work.filter((w) => w.cat === 'Logos' || w.cat === 'Apparel');

  return (
    <section id="work" className="section container" data-screen-label="My Works">
      <Reveal><div className="eyebrow"><b>/</b> SELECTED WORK</div></Reveal>
      <Reveal><h2 className="h2"><window.AnimatedText parts={[{t:'My '},{t:'Works',accent:true},{t:'.'}]} repel /></h2></Reveal>
      {filter === 'All' ? (
        <>
          <WorkScrollGallery items={websiteItems} onOpen={setActive} />
          <div className="work-grid" style={{ marginTop: 24 }}>
            {logoApparelItems.map((item, i) => (
              <Reveal key={item.id} delay={(i % 3) * 60}>
                <WorkCard item={item} onOpen={setActive} />
              </Reveal>
            ))}
          </div>
        </>
      ) : (
        <div className="work-grid">
          {otherItems.map((item, i) => (
            <div key={item.id} className={visible(item.cat) ? '' : 'hidden'}>
              <Reveal delay={(i % 3) * 60}>
                <WorkCard item={item} onOpen={setActive} />
              </Reveal>
            </div>
          ))}
        </div>
      )}

      {visible('Print') && (
        <div className="print-masonry" style={{ marginTop: 24 }}>
          {printItems.map((item) => (
            <Reveal key={item.id} as="div">
              <WorkCard item={item} onOpen={setActive} />
            </Reveal>
          ))}
        </div>
      )}

      <window.Lightbox item={active} onClose={() => setActive(null)} />
    </section>
  );
}

window.Work = Work;
