// ImageFeature.jsx — case-study cards with B&W animal video heroes.
function ImageFeature({
  video,
  poster,
  label,
  title,
  body,
  position = "70% 50%",
  size = "lg",
  index,
}) {
  const mediaRef = React.useRef(null);
  const videoRef = React.useRef(null);
  const [videoPlaying, setVideoPlaying] = React.useState(false);
  const mobile = useMobileLayout(900);

  React.useEffect(() => {
    const media = mediaRef.current;
    const video = videoRef.current;
    if (!media || !video) return undefined;

    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)");
    if (reduced.matches) return undefined;

    let cancelled = false;
    let booted = false;
    let inView = false;

    const onPlaying = () => {
      if (!cancelled) setVideoPlaying(true);
    };

    const playVideo = () => {
      if (cancelled || reduced.matches) return;
      if (!booted) {
        booted = true;
        if (mobile) {
          video.preload = "auto";
          video.load();
        }
      }
      if (video.paused) video.play().catch(() => {});
    };

    const pauseVideo = () => {
      video.pause();
    };

    video.addEventListener("playing", onPlaying);

    const io = new IntersectionObserver(
      ([entry]) => {
        inView = entry.isIntersecting;
        if (inView) playVideo();
        else if (booted) pauseVideo();
      },
      { threshold: 0.12, rootMargin: "48px 0px" }
    );

    const onVisibility = () => {
      if (!document.hidden && inView) playVideo();
    };

    const onUnexpectedPause = () => {
      if (inView && !document.hidden && !cancelled) {
        window.requestAnimationFrame(() => {
          if (inView && video.paused) video.play().catch(() => {});
        });
      }
    };

    document.addEventListener("visibilitychange", onVisibility);
    video.addEventListener("pause", onUnexpectedPause);

    io.observe(media);

    return () => {
      cancelled = true;
      io.disconnect();
      document.removeEventListener("visibilitychange", onVisibility);
      video.removeEventListener("playing", onPlaying);
      video.removeEventListener("pause", onUnexpectedPause);
      video.pause();
    };
  }, [mobile, video]);

  const mediaStyle = { objectPosition: position };

  return (
    <article className={`zg-image-feat ${size === "lg" ? "lg" : "sm"}`}>
      <div
        ref={mediaRef}
        className={`zg-image-feat-media${
          videoPlaying ? " zg-image-feat-media--playing" : ""
        }`}
      >
        <img
          className={`zg-image-feat-photo zg-image-feat-photo-poster${
            videoPlaying ? " is-hidden" : ""
          }`}
          src={poster}
          alt=""
          loading="lazy"
          decoding="async"
          style={mediaStyle}
          aria-hidden="true"
        />
        <video
          ref={videoRef}
          className={`zg-image-feat-photo zg-image-feat-photo-video${
            videoPlaying ? " is-active" : ""
          }`}
          src={video}
          poster={poster}
          loop
          muted
          playsInline
          preload={mobile ? "none" : "metadata"}
          style={mediaStyle}
          aria-hidden="true"
        />
      </div>
      <div className="zg-image-feat-scrim" aria-hidden="true" />
      <div className="zg-image-feat-rail" aria-hidden="true" />

      {index != null && (
        <span className="zg-image-feat-index" aria-hidden="true">
          {String(index).padStart(2, "0")}
        </span>
      )}

      <div className="zg-image-feat-content">
        <h3 className="zg-image-feat-title">{title}</h3>
        <p className="zg-image-feat-body">{body}</p>
        {label ? <div className="zg-image-feat-meta">{label}</div> : null}
      </div>
    </article>
  );
}

function animateWorkCard(tl, card, position, photoScale = 1.1) {
  const photo = card.querySelector(".zg-image-feat-media");
  const title = card.querySelector(".zg-image-feat-title");
  const body = card.querySelector(".zg-image-feat-body");
  const meta = card.querySelector(".zg-image-feat-meta");
  const index = card.querySelector(".zg-image-feat-index");
  const rail = card.querySelector(".zg-image-feat-rail");

  tl.fromTo(
    card,
    { opacity: 0, y: 56, scale: 0.98, transformOrigin: "50% 100%" },
    { opacity: 1, y: 0, scale: 1, duration: 0.9, transformOrigin: "50% 100%" },
    position
  );

  if (photo) {
    tl.fromTo(
      photo,
      { scale: photoScale, opacity: 0.72 },
      { scale: 1, opacity: 1, duration: 1.15, ease: "power2.out" },
      "<"
    );
  }

  if (rail) {
    tl.fromTo(rail, { opacity: 0 }, { opacity: 1, duration: 0.75 }, "<0.18");
  }

  if (index) {
    tl.fromTo(index, { opacity: 0, y: 18 }, { opacity: 1, y: 0, duration: 0.62 }, "<0.12");
  }

  if (title) {
    tl.fromTo(title, { opacity: 0, y: 26 }, { opacity: 1, y: 0, duration: 0.68 }, "<0.08");
  }

  if (body) {
    tl.fromTo(body, { opacity: 0, y: 18 }, { opacity: 1, y: 0, duration: 0.58 }, "<0.08");
  }

  if (meta) {
    tl.fromTo(meta, { opacity: 0, x: -14 }, { opacity: 1, x: 0, duration: 0.52 }, "<0.06");
  }
}

function ImageFeatureSection() {
  const sectionRef = React.useRef(null);
  const playedRef = React.useRef(false);

  React.useEffect(() => {
    const section = sectionRef.current;
    if (!section) return undefined;

    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const gsap = window.gsap;

    const clearMotion = (cards) => {
      if (!gsap) return;
      cards.forEach((card) => {
        gsap.set(card, { clearProps: "transform,opacity" });
        card
          .querySelectorAll(
            ".zg-image-feat-media, .zg-image-feat-rail, .zg-image-feat-index, .zg-image-feat-title, .zg-image-feat-body, .zg-image-feat-meta"
          )
          .forEach((el) => {
            gsap.set(el, { clearProps: "all" });
          });
      });
    };

    const play = () => {
      if (playedRef.current) return;
      playedRef.current = true;

      const opener = section.querySelector(".zg-work-opener");
      const label = section.querySelector(".zg-work-opener .label");
      const title = section.querySelector(".zg-work-opener h2");
      const lgCard = section.querySelector(".zg-image-feat.lg");
      const smCards = section.querySelectorAll(".zg-image-feat.sm");

      if (reduced || !gsap) {
        section.classList.add("zg-work-section--revealed");
        return;
      }

      const tl = gsap.timeline({ defaults: { ease: "power3.out" } });

      tl.from(opener, { opacity: 0, y: 28, duration: 0.7 })
        .from(label, { opacity: 0, y: 14, duration: 0.55 }, "-=0.55")
        .from(title, { opacity: 0, y: 24, duration: 0.78 }, "-=0.45");

      if (lgCard) {
        animateWorkCard(tl, lgCard, "-=0.08", 1.12);
      }

      smCards.forEach((card, index) => {
        animateWorkCard(tl, card, index === 0 ? "-=0.42" : "-=0.48", 1.08);
      });

      tl.add(() => {
        section.classList.add("zg-work-section--revealed");
        clearMotion(section.querySelectorAll(".zg-image-feat"));
      });
    };

    const io = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          play();
          io.disconnect();
        }
      },
      { threshold: 0.16 }
    );

    io.observe(section);

    let parallaxRaf = 0;
    let parallaxCleanup = () => {};

    if (!reduced) {
      const cards = Array.from(section.querySelectorAll(".zg-image-feat"));
      const paint = () => {
        parallaxRaf = 0;
        const viewportH = window.innerHeight || document.documentElement.clientHeight;
        const center = viewportH / 2;
        cards.forEach((card) => {
          const rect = card.getBoundingClientRect();
          if (rect.bottom < -200 || rect.top > viewportH + 200) return;
          const cardCenter = rect.top + rect.height / 2;
          const normalized = (cardCenter - center) / viewportH;
          const range = card.classList.contains("lg") ? 22 : 14;
          const offset = Math.max(-range, Math.min(range, -normalized * range * 2));
          card.style.setProperty("--parallax-y", `${offset.toFixed(2)}px`);
        });
      };

      const onScroll = () => {
        if (parallaxRaf) return;
        parallaxRaf = window.requestAnimationFrame(paint);
      };

      window.addEventListener("scroll", onScroll, { passive: true });
      window.addEventListener("resize", onScroll);
      paint();

      parallaxCleanup = () => {
        window.removeEventListener("scroll", onScroll);
        window.removeEventListener("resize", onScroll);
        if (parallaxRaf) cancelAnimationFrame(parallaxRaf);
      };
    }

    return () => {
      io.disconnect();
      parallaxCleanup();
    };
  }, []);

  return (
    <section
      id="work"
      ref={sectionRef}
      className="zg-work-section"
      aria-labelledby="zg-work-title"
    >
      <div className="zg-container">
        <header className="zg-work-header">
          <div className="zg-work-opener">
            <span className="label">Case studies</span>
            <h2 id="zg-work-title">
              AI that <span className="zg-highlight">moved work</span>.
              <span className="muted">
                Messy processes turned into AI-enabled workflows.
              </span>
            </h2>
          </div>
        </header>

        <div className="zg-work-grid">
          <ImageFeature
            index={1}
            size="lg"
            video="assets/videos/animals/leopard.mp4"
            poster="assets/animals/hero/leopard-poster.png"
            position="68% 42%"
            title={
              <>
                Payroll data,
                <br />
                <span className="zg-highlight">clean upload</span>.
              </>
            }
            body="An anesthesia management company cleaned payroll exports by hand every cycle. Zaigo built a workflow that applies pay rules and outputs upload-ready files."
          />
          <div className="zg-work-stack">
            <ImageFeature
              index={2}
              size="sm"
              video="assets/videos/animals/tiger.mp4"
              poster="assets/animals/hero/tiger-poster.png"
              position="50% 28%"
              title={
                <>
                  Internal knowledge,
                  <br />
                  <span className="zg-highlight">searchable</span>.
                </>
              }
              body="An executive compensation firm couldn't search years of scattered governance files. Zaigo built a platform for source-backed answers across the full library."
            />
            <ImageFeature
              index={3}
              size="sm"
              video="assets/videos/animals/giraffe.mp4"
              poster="assets/animals/hero/giraffe-poster.png"
              position="52% 35%"
              title={
                <>
                  Client reporting,
                  <br />
                  <span className="zg-highlight">made clear</span>.
                </>
              }
              body="A payment optimization firm's clients tracked savings and refunds in spreadsheets. Zaigo built reporting that shows processing performance and account health in one place."
            />
          </div>
        </div>
      </div>
    </section>
  );
}

window.ImageFeature = ImageFeature;
window.ImageFeatureSection = ImageFeatureSection;
