/**
 * Ring Animation — scroll-scrubbed furniture wheel.
 * Scope: [data-ring] on .ring_section
 *
 * Cards should already exist in .ring_wheel (Webflow / export HTML).
 * Desktop: wheel on left, spins 360° while section scrolls.
 * Stacked ≤800px: bottom arc, smaller spin.
 *
 * Webflow: wait for footer GSAP (embed runs before site footer).
 * Reuse site Lenis if present so ScrollTrigger scrub stays in sync.
 */
(() => {
  function whenGsap(run) {
    if (typeof gsap !== "undefined" && typeof ScrollTrigger !== "undefined") {
      run();
      return;
    }
    let tries = 0;
    const id = setInterval(() => {
      tries += 1;
      if (typeof gsap !== "undefined" && typeof ScrollTrigger !== "undefined") {
        clearInterval(id);
        run();
      } else if (tries > 200) {
        clearInterval(id);
        console.warn("Ring Animation: GSAP/ScrollTrigger not found");
      }
    }, 50);
  }

  whenGsap(() => {
    gsap.registerPlugin(ScrollTrigger);

    const stackedQuery = window.matchMedia("(max-width: 800px)");
    const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
    const START_ROTATION = -18;

    function hookLenis() {
      if (reduceMotion.matches) return;
      const existing =
        window.lenis ||
        window.__servicesLenis ||
        window.imagesGridLenis ||
        null;
      if (existing && typeof existing.on === "function") {
        existing.on("scroll", ScrollTrigger.update);
        return;
      }
      if (typeof Lenis !== "function") return;
      if (window.__ringLenis) return;

      const lenis = new Lenis({
        duration: 1.15,
        easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
        smoothWheel: true,
        wheelMultiplier: 1,
      });
      window.__ringLenis = lenis;
      window.lenis = window.lenis || lenis;
      lenis.on("scroll", ScrollTrigger.update);
      gsap.ticker.add((time) => {
        lenis.raf(time * 1000);
      });
      gsap.ticker.lagSmoothing(0);
    }

    function metrics(section, visual) {
      const stacked = stackedQuery.matches;
      const visualH = Math.max(
        visual.clientHeight || 0,
        visual.offsetHeight || 0,
        stacked ? 400 : window.innerHeight * 0.7
      );
      const visualW = Math.max(
        visual.clientWidth || 0,
        visual.offsetWidth || 0,
        stacked ? window.innerWidth : window.innerWidth * 0.48
      );
      const scale = Math.min(1, window.innerWidth / 1280);

      if (stacked) {
        const cardScale = Math.min(1, visualW / 390);
        const cardW = 186 * cardScale;
        const cardH = 296 * cardScale;
        const radius = Math.min(visualW * 0.5, visualH * 0.56);

        section.style.setProperty("--ring--card-w", `${cardW}px`);
        section.style.setProperty("--ring--card-h", `${cardH}px`);

        return {
          radius,
          pivotX: visualW / 2,
          pivotY: visualH,
          startRotation: 0,
          spin: 80,
        };
      }

      const stageH = Math.min(630, window.innerHeight * 0.72);
      const cardW = 240 * scale;
      const cardH = 370 * scale;
      const radius = Math.max(window.innerHeight * 0.52, stageH * 0.75);

      section.style.setProperty("--ring--card-w", `${cardW}px`);
      section.style.setProperty("--ring--card-h", `${cardH}px`);

      return {
        radius,
        pivotX: 0,
        pivotY: visualH / 2,
        startRotation: START_ROTATION,
        spin: 360,
      };
    }

    function layout(section, visual, pivot, wheel, cards) {
      const { radius, pivotX, pivotY, startRotation } = metrics(section, visual);
      const slice = 360 / Math.max(cards.length, 1);

      gsap.set(pivot, {
        css: {
          left: `${pivotX}px`,
          top: `${pivotY}px`,
        },
      });

      cards.forEach((card, i) => {
        const angle = i * slice;
        const rad = (angle * Math.PI) / 180;

        gsap.set(card, {
          x: Math.cos(rad) * radius,
          y: Math.sin(rad) * radius,
          rotation: angle + 90,
          xPercent: -50,
          yPercent: -50,
          transformOrigin: "50% 50%",
        });
      });

      gsap.set(wheel, { rotation: startRotation });
    }

    function waitForImages(section) {
      const imgs = Array.from(section.querySelectorAll("img"));
      if (!imgs.length) return Promise.resolve();
      return Promise.all(
        imgs.map(
          (img) =>
            new Promise((resolve) => {
              if (img.complete) {
                resolve();
                return;
              }
              img.addEventListener("load", resolve, { once: true });
              img.addEventListener("error", resolve, { once: true });
            })
        )
      );
    }

    function initSection(section) {
      const visual = section.querySelector(".ring_visual");
      const pivot = section.querySelector(".ring_pivot");
      const wheel = section.querySelector(".ring_wheel");
      const cards = gsap.utils.toArray(".ring_card", section);
      if (!visual || !pivot || !wheel || !cards.length) {
        console.warn("Ring Animation: missing visual/pivot/wheel/cards", {
          visual: !!visual,
          pivot: !!pivot,
          wheel: !!wheel,
          cards: cards.length,
        });
        return null;
      }

      let ctx;

      function boot() {
        ctx?.revert();
        layout(section, visual, pivot, wheel, cards);

        ctx = gsap.context(() => {
          if (reduceMotion.matches) return;

          const { startRotation, spin } = metrics(section, visual);

          gsap.fromTo(
            wheel,
            { rotation: startRotation },
            {
              rotation: startRotation + spin,
              ease: "none",
              scrollTrigger: {
                trigger: section,
                start: "top bottom",
                end: "bottom top",
                scrub: 0.6,
                invalidateOnRefresh: true,
              },
            }
          );
        }, section);

        ScrollTrigger.refresh();
      }

      waitForImages(section).then(() => {
        requestAnimationFrame(() => {
          boot();
          requestAnimationFrame(() => {
            boot();
            ScrollTrigger.refresh();
          });
        });
      });

      let resizeTimer;
      const onResize = () => {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(() => {
          boot();
          ScrollTrigger.refresh();
        }, 80);
      };
      const onStackChange = () => {
        boot();
        ScrollTrigger.refresh();
      };

      window.addEventListener("resize", onResize);
      stackedQuery.addEventListener("change", onStackChange);

      return {
        revert() {
          window.removeEventListener("resize", onResize);
          stackedQuery.removeEventListener("change", onStackChange);
          clearTimeout(resizeTimer);
          ctx?.revert();
        },
      };
    }

    hookLenis();

    const sections = gsap.utils.toArray("[data-ring]");
    const fallback = sections.length
      ? sections
      : gsap.utils.toArray(".ring_section");

    if (!fallback.length) {
      console.warn("Ring Animation: no .ring_section / [data-ring] found");
      return;
    }

    fallback.forEach(initSection);

    // Webflow + late fonts / component paint
    window.addEventListener("load", () => ScrollTrigger.refresh());
    setTimeout(() => ScrollTrigger.refresh(), 400);
    setTimeout(() => ScrollTrigger.refresh(), 1200);
  });
})();
