import {
  useCallback,
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
} from "react";
import { Link } from "react-router";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import HeroSection from "../components/landing/HeroSection";
import SharedNavbar from "../components/SharedNavbar";
import { useProductTransition } from "../transitions/ProductTransitionContext";
import perfumes from "../data/perfumes";
import "../pages/LandingPage.css";
import "../style/navbar.css";

const INTRO_SESSION_KEY = "atmos-landing-intro-played";

gsap.registerPlugin(ScrollTrigger);

function LandingPage() {
  const pageRef = useRef(null);
  const overlayRef = useRef(null);
  const overlayTextRef = useRef(null);
  const heroImageWrapRef = useRef(null);
  const heroImageRef = useRef(null);
  const discoveryImageRef = useRef(null);
  const headlineLineRefs = useRef([]);
  const heroMetaRefs = useRef([]);
  const cardRefs = useRef([]);
  const { startProductTransition } = useProductTransition();

  const [introSettings] = useState(() => {
    if (typeof window === "undefined") {
      return { shouldPlayIntro: true };
    }

    const prefersReducedMotion = window.matchMedia(
      "(prefers-reduced-motion: reduce)"
    ).matches;
    const introAlreadyPlayed =
      window.sessionStorage.getItem(INTRO_SESSION_KEY) === "true";

    return {
      shouldPlayIntro: !prefersReducedMotion && !introAlreadyPlayed,
    };
  });
  const { shouldPlayIntro } = introSettings;

  const setHeadlinePrimaryRef = useCallback((element) => {
    headlineLineRefs.current[0] = element;
  }, []);

  const setHeadlineSecondaryRef = useCallback((element) => {
    headlineLineRefs.current[1] = element;
  }, []);

  const setDescriptionRef = useCallback((element) => {
    heroMetaRefs.current[0] = element;
  }, []);

  const setActionsRef = useCallback((element) => {
    heroMetaRefs.current[1] = element;
  }, []);

  useLayoutEffect(() => {
    const overlay = overlayRef.current;
    const overlayText = overlayTextRef.current;
    const heroImageWrap = heroImageWrapRef.current;
    const headlineLines = headlineLineRefs.current.filter(Boolean);
    const heroMeta = heroMetaRefs.current.filter(Boolean);

    if (!overlay || !overlayText || !heroImageWrap || headlineLines.length === 0) {
      return undefined;
    }

    const ctx = gsap.context(() => {
      gsap.set(heroImageWrap, {
        scale: 1.22,
        transformOrigin: "center center",
      });

      gsap.set(headlineLines, {
        yPercent: 115,
        rotate: 2.2,
        transformOrigin: "0% 100%",
        force3D: true,
      });

      gsap.set(heroMeta, {
        y: 36,
        autoAlpha: 0,
      });

      if (!shouldPlayIntro) {
        gsap.set(heroImageWrap, { scale: 1 });
        gsap.set(headlineLines, { yPercent: 0, rotate: 0 });
        gsap.set(heroMeta, { y: 0, autoAlpha: 1 });
        gsap.set(overlay, {
          yPercent: -100,
          autoAlpha: 0,
          display: "none",
        });
        return;
      }

      gsap.set(overlay, { yPercent: 0, autoAlpha: 1, display: "block" });
      gsap.set(overlayText, { xPercent: 28, yPercent: 140, autoAlpha: 0 });

      const introTimeline = gsap.timeline({
        defaults: { ease: "power3.out" },
        onComplete: () => {
          window.sessionStorage.setItem(INTRO_SESSION_KEY, "true");
        },
      });

      introTimeline
        .to(overlayText, {
          xPercent: 0,
          yPercent: 0,
          autoAlpha: 1,
          duration: 1.28,
          ease: "expo.out",
        })
        .to({}, { duration: 0.34 })
        .to(
          overlay,
          {
            yPercent: -100,
            duration: 1.46,
            ease: "power4.out",
          },
          ">"
        )
        .to(
          heroImageWrap,
          {
            scale: 1,
            duration: 1.6,
            ease: "power2.out",
          },
          "<0.03"
        )
        .to(
          headlineLines,
          {
            yPercent: 0,
            rotate: 0,
            duration: 1.18,
            stagger: 0.1,
            ease: "power4.out",
          },
          "<0.27"
        )
        .to(
          heroMeta,
          {
            y: 0,
            autoAlpha: 1,
            duration: 1.02,
            stagger: 0.12,
            ease: "power4.out",
          },
          "<0.16"
        )
        .set(overlay, { display: "none" });
    }, pageRef);

    return () => {
      ctx.revert();
    };
  }, [shouldPlayIntro]);

  useLayoutEffect(() => {
    const heroImageWrap = heroImageWrapRef.current;
    const heroImage = heroImageRef.current;
    const discoveryImage = discoveryImageRef.current;

    if (!heroImageWrap || !heroImage || !discoveryImage || typeof window === "undefined") {
      return undefined;
    }

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

    const heroSection = heroImageWrap.closest(".hero");
    const discoveryBanner = discoveryImage.closest(".discovery-banner");

    if (!heroSection || !discoveryBanner) {
      return undefined;
    }

    const ctx = gsap.context(() => {
      gsap.set(heroImage, {
        scale: 1.14,
        yPercent: -4,
        transformOrigin: "center center",
        force3D: true,
      });

      gsap.to(heroImage, {
        yPercent: 8,
        ease: "none",
        scrollTrigger: {
          trigger: heroSection,
          start: "top top",
          end: "bottom top",
          scrub: 1.15,
        },
      });

      gsap.set(discoveryImage, {
        scale: 1.16,
        yPercent: -8,
        transformOrigin: "center center",
        force3D: true,
      });

      gsap.to(discoveryImage, {
        yPercent: 10,
        ease: "none",
        scrollTrigger: {
          trigger: discoveryBanner,
          start: "top bottom",
          end: "bottom top",
          scrub: 1.2,
        },
      });
    }, pageRef);

    return () => {
      ctx.revert();
    };
  }, []);

  useEffect(() => {
    const cards = cardRefs.current.filter(Boolean);
    const cardStates = cards
      .map((card) => {
        const hoverFill = card.querySelector(".product-hover-fill");
        const hoverVideo = card.querySelector(".product-hover-video");
        const productImage = card.querySelector(".product-image");
        const arrow = card.querySelector(".arrow");

        if (!hoverFill || !productImage || !arrow) {
          return null;
        }

        gsap.set(hoverFill, { autoAlpha: 0, scale: 1.08 });
        gsap.set(productImage, { autoAlpha: 1, scale: 1 });
        gsap.set(arrow, { x: 0 });

        return { card, hoverFill, hoverVideo, productImage, arrow };
      })
      .filter(Boolean);

    const stopVideo = (video) => {
      if (!video) return;
      video.pause();
      try {
        video.currentTime = 0;
      } catch {
        // Ignore errors when setting currentTime.
      }
    };

    const playVideo = (video) => {
      if (!video) return;

      try {
        video.currentTime = 0;
      } catch {
        // Ignore errors when setting currentTime.
      }

      const playAttempt = video.play();
      if (playAttempt && typeof playAttempt.catch === "function") {
        playAttempt.catch(() => {});
      }
    };

    const deactivate = (state) => {
      gsap.killTweensOf([state.hoverFill, state.productImage, state.arrow]);
      stopVideo(state.hoverVideo);

      gsap.to(state.hoverFill, {
        autoAlpha: 0,
        scale: 1.08,
        duration: 0.35,
        ease: "power2.out",
        overwrite: "auto",
      });

      gsap.to(state.productImage, {
        scale: 1,
        autoAlpha: 1,
        duration: 0.35,
        ease: "power2.out",
        overwrite: "auto",
      });

      gsap.to(state.arrow, {
        x: 0,
        duration: 0.35,
        ease: "power2.out",
        overwrite: "auto",
      });
    };

    const activate = (state) => {
      cardStates.forEach((item) => {
        if (item !== state) {
          deactivate(item);
        }
      });

      gsap.killTweensOf([state.hoverFill, state.productImage, state.arrow]);
      playVideo(state.hoverVideo);

      gsap.to(state.hoverFill, {
        autoAlpha: 1,
        scale: 1,
        duration: 0.45,
        ease: "power2.out",
        overwrite: "auto",
      });

      gsap.to(state.productImage, {
        scale: 0.92,
        autoAlpha: 0.35,
        duration: 0.45,
        ease: "power2.out",
        overwrite: "auto",
      });

      gsap.to(state.arrow, {
        x: 8,
        duration: 0.45,
        ease: "power2.out",
        overwrite: "auto",
      });
    };

    const cardCleanups = cardStates.map((state) => {
      const onEnter = () => activate(state);
      const onLeave = () => deactivate(state);

      state.card.addEventListener("pointerenter", onEnter);
      state.card.addEventListener("pointerleave", onLeave);

      return () => {
        state.card.removeEventListener("pointerenter", onEnter);
        state.card.removeEventListener("pointerleave", onLeave);
      };
    });

    const resetAll = () => {
      cardStates.forEach((state) => deactivate(state));
    };

    const onMouseOutWindow = (event) => {
      if (!event.relatedTarget) {
        resetAll();
      }
    };

    window.addEventListener("blur", resetAll);
    document.addEventListener("mouseout", onMouseOutWindow);

    return () => {
      window.removeEventListener("blur", resetAll);
      document.removeEventListener("mouseout", onMouseOutWindow);
      cardCleanups.forEach((cleanup) => cleanup());
    };
  }, []);

  return (
    <div className="page" ref={pageRef}>
      <SharedNavbar variant="hero" active="atmos" />

      <HeroSection
        heroImageWrapRef={heroImageWrapRef}
        heroImageRef={heroImageRef}
        setHeadlinePrimaryRef={setHeadlinePrimaryRef}
        setHeadlineSecondaryRef={setHeadlineSecondaryRef}
        setDescriptionRef={setDescriptionRef}
        setActionsRef={setActionsRef}
        overlayRef={overlayRef}
        overlayTextRef={overlayTextRef}
      />

      <main>
        <section className="section" id="dufte" data-reveal-group>
          <div className="section-heading">
            <h2 data-reveal="lines">
              {"W\u00C4HLE EINE"}
              <br />
              {"ATMOSPH\u00C4RE"}
            </h2>
          </div>

          <div className="product-grid">
            {perfumes.map((item, index) => (
              <Link
                to={`/duft/${item.slug}`}
                className="product-card"
                key={item.id}
                onClick={(event) => startProductTransition(event, item)}
                ref={(element) => {
                  cardRefs.current[index] = element;
                }}
              >
                <div className="product-hover-fill" aria-hidden="true">
                  {item.fillVideo ? (
                    <video
                      className="product-hover-video"
                      src={item.fillVideo}
                      muted
                      loop
                      playsInline
                      preload="metadata"
                    />
                  ) : (
                    <div
                      className="product-hover-image"
                      style={{
                        backgroundImage: `url(${item.fillImage || item.image})`,
                      }}
                    />
                  )}
                </div>

                <div className="product-top">
                  <span className="product-id">{item.id}</span>
                  <h3>{item.name}</h3>
                </div>

                <div className="product-image-wrap">
                  <img
                    src={item.image}
                    alt={item.name}
                    className="product-image"
                    data-product-transition-source
                    loading={index < 3 ? "eager" : "lazy"}
                    decoding="async"
                  />
                </div>

                <div className="product-bottom">
                  <p>{item.text}</p>
                  <span className="arrow" aria-hidden="true" />
                </div>
              </Link>
            ))}
          </div>
        </section>

        <section
          className="discovery-section"
          id="testen"
          data-reveal-group
          data-reveal-start="top 82%"
        >
          <div className="discovery-copy">
            <h2 data-reveal="lines">
              DER SICHERE EINSTIEG
              <br />
              DISCOVERY SET
            </h2>
            <p data-reveal="fade">
              {"Alle 6 D\u00FCfte als 2ml Samples."}
              <br />
              Jeden Duft eine Woche tragen.
              <br />
              Verstehen, was funktioniert.
            </p>
            <Link to="/discovery-set" className="discovery-btn" data-reveal="fade">
              Discovery Set bestellen
            </Link>
          </div>

          <div className="discovery-banner">
            <img
              src="/atmos-discovery-set-thumbnail.png"
              alt="Discovery Set"
              loading="lazy"
              decoding="async"
              ref={discoveryImageRef}
            />
          </div>
        </section>
      </main>
    </div>
  );
}

export default LandingPage;
