import { onBeforeUnmount, onMounted, unref } from "vue";

export function useGsapReveal(rootRef) {
  let ctx;
  const cleanup = [];

  onMounted(() => {
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
      return;
    }

    const root = unref(rootRef);
    const { $gsap } = useNuxtApp();

    if (!root || !$gsap) {
      return;
    }

    ctx = $gsap.context(() => {
      const isTouch = window.matchMedia("(hover: none), (pointer: coarse)").matches;
      const heroItems = root.querySelectorAll("[data-hero-reveal]");

      if (heroItems.length) {
        $gsap.fromTo(
          heroItems,
          {
            autoAlpha: 0,
            y: 34,
            filter: "blur(10px)",
          },
          {
            autoAlpha: 1,
            y: 0,
            filter: "blur(0px)",
            duration: 0.95,
            stagger: 0.12,
            ease: "power3.out",
          },
        );
      }

      root.querySelectorAll("[data-reveal]").forEach((element, index) => {
        $gsap.fromTo(
          element,
          {
            autoAlpha: 0,
            y: 26,
          },
          {
            autoAlpha: 1,
            y: 0,
            duration: 0.72,
            delay: index * 0.025,
            ease: "power2.out",
            scrollTrigger: {
              trigger: element,
              start: "top 85%",
              once: true,
            },
          },
        );
      });

      root.querySelectorAll("[data-stagger]").forEach((element) => {
        const children = element.querySelectorAll("[data-stagger-item]");

        if (!children.length) {
          return;
        }

        $gsap.fromTo(
          children,
          {
            autoAlpha: 0,
            y: 22,
          },
          {
            autoAlpha: 1,
            y: 0,
            duration: 0.64,
            stagger: 0.09,
            ease: "power2.out",
            scrollTrigger: {
              trigger: element,
              start: "top 82%",
              once: true,
            },
          },
        );
      });

      root.querySelectorAll("[data-parallax]").forEach((element) => {
        const distance = Number(element.dataset.parallax) || 42;

        $gsap.fromTo(
          element,
          { y: distance * -0.35 },
          {
            y: distance,
            ease: "none",
            scrollTrigger: {
              trigger: element,
              start: "top bottom",
              end: "bottom top",
              scrub: 0.8,
            },
          },
        );
      });

      root.querySelectorAll("[data-geo-loop]").forEach((element) => {
        const nodes = element.querySelectorAll("[data-geo-node]");

        if (!nodes.length) {
          return;
        }

        $gsap.fromTo(
          nodes,
          { autoAlpha: 0.48, x: -10 },
          {
            autoAlpha: 1,
            x: 0,
            duration: 0.45,
            stagger: 0.11,
            ease: "power2.out",
            scrollTrigger: {
              trigger: element,
              start: "top 75%",
              once: true,
            },
          },
        );
      });

      root.querySelectorAll("[data-flow-line]").forEach((element) => {
        $gsap.fromTo(
          element,
          { width: "0%" },
          {
            width: "100%",
            duration: 1,
            ease: "power2.out",
            scrollTrigger: {
              trigger: element,
              start: "top 82%",
              once: true,
            },
          },
        );
      });

      if (isTouch) {
        return;
      }

      root.querySelectorAll("[data-hover-card]").forEach((element) => {
        const onMove = (event) => {
          const rect = element.getBoundingClientRect();
          const x = ((event.clientX - rect.left) / rect.width - 0.5) * 10;
          const y = ((event.clientY - rect.top) / rect.height - 0.5) * -10;

          $gsap.to(element, {
            rotateX: y,
            rotateY: x,
            y: -6,
            duration: 0.35,
            ease: "power2.out",
            transformPerspective: 900,
          });
        };

        const onLeave = () => {
          $gsap.to(element, {
            rotateX: 0,
            rotateY: 0,
            y: 0,
            duration: 0.42,
            ease: "power2.out",
          });
        };

        element.addEventListener("mousemove", onMove);
        element.addEventListener("mouseleave", onLeave);
        cleanup.push(() => {
          element.removeEventListener("mousemove", onMove);
          element.removeEventListener("mouseleave", onLeave);
        });
      });
    }, root);
  });

  onBeforeUnmount(() => {
    cleanup.forEach((dispose) => dispose());
    ctx?.revert();
  });
}
