import { gsap } from "gsap";
import { useEffect, useMemo, useRef, useState } from "react";

export default function HeroSection({ settings, data }: { settings: any; data: any }) {
  const SLICE_COUNT = 10;
  const sec1Repeater = Array.isArray(data?.sec_1_repeater) ? data.sec_1_repeater : [];
  const heroSlides = sec1Repeater.length > 0 ? sec1Repeater : [{ value_text_1: "[]", value_text_2: "", value_text_3: "#", value_media_1: "" }];
  const [activeIndex, setActiveIndex] = useState(0);
  const [isPaused, setIsPaused] = useState(false);
  const [isTransitioning, setIsTransitioning] = useState(false);
  const previousIndexRef = useRef(0);
  const isTransitioningRef = useRef(false);
  const slideRefs = useRef<Array<HTMLDivElement | null>>([]);
  const contentRefs = useRef<Array<HTMLDivElement | null>>([]);
  const transitionLayerRef = useRef<HTMLDivElement | null>(null);
  const outgoingSliceRefs = useRef<Array<HTMLDivElement | null>>([]);
  const incomingSliceRefs = useRef<Array<HTMLDivElement | null>>([]);

  const parsedSlides = useMemo(() => {
    return heroSlides.map((hero: any) => {
      let texts: string[] = [];

      try {
        const parsedTexts = JSON.parse(hero?.value_text_1 ?? "[]");
        texts = Array.isArray(parsedTexts) ? parsedTexts : [];
      } catch {
        texts = [];
      }

      return {
        ...hero,
        title: texts[0] ?? "",
        subtitle: texts[1] ?? "",
        description: texts[2] ?? "",
      };
    });
  }, [heroSlides]);
  const isRtl = typeof document !== "undefined" && document.documentElement.dir === "rtl";

  useEffect(() => {
    slideRefs.current.forEach((slide, index) => {
      if (!slide) return;

      gsap.set(slide, {
        autoAlpha: index === activeIndex ? 1 : 0,
        scale: index === activeIndex ? 1 : 1.04,
      });
    });

    const initialContent = contentRefs.current[activeIndex];
    if (initialContent) {
      gsap.set(initialContent.children, { autoAlpha: 1, y: 0 });
    }

    if (transitionLayerRef.current) {
      gsap.set(transitionLayerRef.current, { autoAlpha: 0 });
    }
  }, []);

  useEffect(() => {
    const previousIndex = previousIndexRef.current;
    if (previousIndex === activeIndex) return;

    const outgoingSlide = slideRefs.current[previousIndex];
    const outgoingContent = contentRefs.current[previousIndex];
    const incomingSlide = slideRefs.current[activeIndex];
    const incomingContent = contentRefs.current[activeIndex];
    const transitionLayer = transitionLayerRef.current;
    const outgoingImage = parsedSlides[previousIndex]?.value_media_1 ?? "";
    const incomingImage = parsedSlides[activeIndex]?.value_media_1 ?? "";

    const timeline = gsap.timeline({ defaults: { ease: "power3.out" } });
    isTransitioningRef.current = true;
    setIsTransitioning(true);

    outgoingSliceRefs.current.forEach((slice) => {
      if (!slice) return;
      slice.style.backgroundImage = `url('${outgoingImage}')`;
    });

    incomingSliceRefs.current.forEach((slice) => {
      if (!slice) return;
      slice.style.backgroundImage = `url('${incomingImage}')`;
    });

    if (transitionLayer) {
      timeline.set(transitionLayer, { autoAlpha: 1 }, 0);
    }

    timeline.set(
      outgoingSliceRefs.current,
      {
        autoAlpha: 1,
        yPercent: 0,
        xPercent: 0,
        rotate: 0,
      },
      0,
    );

    timeline.set(
      incomingSliceRefs.current,
      {
        autoAlpha: 1,
        yPercent: (index: number) => (index % 2 === 0 ? 115 : -115),
        xPercent: (index: number) => (index % 2 === 0 ? -8 : 8),
        rotate: (index: number) => (index % 2 === 0 ? -4 : 4),
      },
      0,
    );

    if (outgoingSlide) {
      timeline.to(
        outgoingSlide,
        {
          autoAlpha: 0,
          scale: 1.06,
          duration: 0.58,
          ease: "power2.inOut",
        },
        0.22,
      );
    }

    if (outgoingContent) {
      timeline.to(
        outgoingContent.children,
        {
          autoAlpha: 0,
          y: -16,
          stagger: 0.05,
          duration: 0.25,
          ease: "power2.in",
        },
        0,
      );
    }

    timeline.to(
      outgoingSliceRefs.current,
      {
        yPercent: (index: number) => (index % 2 === 0 ? -130 : 130),
        xPercent: (index: number) => (index % 2 === 0 ? -14 : 14),
        rotate: (index: number) => (index % 2 === 0 ? -7 : 7),
        autoAlpha: 0,
        stagger: {
          each: 0.04,
          from: "center",
        },
        duration: 0.58,
        ease: "power3.in",
      },
      0.02,
    );

    if (incomingSlide) {
      timeline.fromTo(
        incomingSlide,
        {
          autoAlpha: 1,
          scale: 1.03,
        },
        {
          scale: 1,
          duration: 0.95,
        },
        0.2,
      );
    }

    timeline.to(
      incomingSliceRefs.current,
      {
        yPercent: 0,
        xPercent: 0,
        rotate: 0,
        stagger: {
          each: 0.04,
          from: "center",
        },
        duration: 0.68,
        ease: "power4.out",
      },
      0.24,
    );

    if (transitionLayer) {
      timeline.to(
        transitionLayer,
        {
          autoAlpha: 0,
          duration: 0.24,
        },
        1.02,
      );
    }

    if (incomingContent) {
      timeline.fromTo(
        incomingContent.children,
        {
          autoAlpha: 0,
          y: 26,
        },
        {
          autoAlpha: 1,
          y: 0,
          stagger: 0.1,
          duration: 0.55,
          ease: "power3.out",
        },
        1.08,
      );
    }

    timeline.add(() => {
      isTransitioningRef.current = false;
      setIsTransitioning(false);
    });

    previousIndexRef.current = activeIndex;

    return () => {
      isTransitioningRef.current = false;
      setIsTransitioning(false);
      timeline.kill();
    };
  }, [activeIndex, parsedSlides]);

  useEffect(() => {
    if (isPaused || isTransitioning || parsedSlides.length <= 1) return;

    const interval = window.setInterval(() => {
      if (isTransitioningRef.current) return;
      setActiveIndex((current) => (current + 1) % parsedSlides.length);
    }, 5000);

    return () => {
      window.clearInterval(interval);
    };
  }, [isPaused, isTransitioning, parsedSlides.length]);

  const goToNextSlide = () => {
    if (isTransitioningRef.current) return;
    setActiveIndex((current) => (current + 1) % parsedSlides.length);
  };

  const goToPreviousSlide = () => {
    if (isTransitioningRef.current) return;
    setActiveIndex((current) => (current - 1 + parsedSlides.length) % parsedSlides.length);
  };

  return (
    <section
      className="relative overflow-hidden bg-slate-900 text-white"
      onMouseEnter={() => setIsPaused(true)}
      onMouseLeave={() => setIsPaused(false)}
    >
      <div className="relative min-h-[75vh] md:min-h-[85vh]">
        {parsedSlides.map((hero: any, index: number) => {
          const isActive = index === activeIndex;

          return (
            <div
              key={hero?.id ?? index}
              ref={(element) => {
                slideRefs.current[index] = element;
              }}
              className={`absolute inset-0 ${isActive ? "pointer-events-auto" : "pointer-events-none"}`}
            >
              <div
                className="relative flex min-h-[75vh] items-center justify-center text-white md:min-h-[85vh]"
              >
                <img
                  src={hero?.value_media_1 ?? ""}
                  alt={hero?.title ? `${hero.title} background` : "Hero background"}
                  className="absolute inset-0 h-full w-full object-cover"
                  loading={index === 0 ? "eager" : "lazy"}
                  decoding="async"
                />
                <div className="absolute inset-0">
                  <div className="absolute inset-0 bg-black/45" />
                </div>

                <div
                  ref={(element) => {
                    contentRefs.current[index] = element;
                  }}
                  className="relative mx-auto flex w-full max-w-8xl flex-col items-center gap-4 px-6 text-center"
                >
                  <h1 className="text-2xl font-semibold sm:text-3xl md:text-2xl">{hero.title}</h1>
                  <p className="text-2xl font-bold text-[#9FCD00] sm:text-3xl md:text-3xl">{hero.subtitle}</p>
                  <p className="max-w-2xl text-base text-white/80 sm:text-base md:text-xl">{hero.description}</p>
                  <a
                    href={hero?.value_text_3 ?? "#"}
                    className="mt-2 rounded-md bg-[#9FCD00] px-5 py-2 text-base font-semibold uppercase tracking-wide text-slate-900 transition-colors hover:bg-[#b5e100]"
                  >
                    {hero?.value_text_2 ?? "Read More"}
                  </a>
                </div>
              </div>
            </div>
          );
        })}

        <div ref={transitionLayerRef} className="pointer-events-none absolute inset-0 z-10">
          {Array.from({ length: SLICE_COUNT }).map((_, index) => (
            <div
              key={`outgoing-slice-${index}`}
              ref={(element) => {
                outgoingSliceRefs.current[index] = element;
              }}
              className="absolute inset-0 bg-cover bg-center bg-no-repeat will-change-transform"
              style={{
                clipPath: `polygon(${(index * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 100%, ${(index * 100) / SLICE_COUNT}% 100%)`,
                WebkitClipPath: `polygon(${(index * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 100%, ${(index * 100) / SLICE_COUNT}% 100%)`,
              }}
            />
          ))}
          {Array.from({ length: SLICE_COUNT }).map((_, index) => (
            <div
              key={`incoming-slice-${index}`}
              ref={(element) => {
                incomingSliceRefs.current[index] = element;
              }}
              className="absolute inset-0 bg-cover bg-center bg-no-repeat will-change-transform"
              style={{
                clipPath: `polygon(${(index * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 100%, ${(index * 100) / SLICE_COUNT}% 100%)`,
                WebkitClipPath: `polygon(${(index * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 0%, ${((index + 1) * 100) / SLICE_COUNT}% 100%, ${(index * 100) / SLICE_COUNT}% 100%)`,
              }}
            />
          ))}
          <div className="absolute inset-0 bg-black/45" />
        </div>

        <button
          type="button"
          onClick={goToPreviousSlide}
          className="absolute top-1/2 left-4 w-10 h-10 z-20 -translate-y-1/2 rounded-full bg-black/35 p-2 text-white transition hover:bg-black/55"
          aria-label="Previous slide"
        >
          <span className="text-2xl leading-none">{isRtl ? "\u203A" : "\u2039"}</span>
        </button>

        <button
          type="button"
          onClick={goToNextSlide}
          className="absolute top-1/2 right-4 w-10 h-10 z-20 -translate-y-1/2 rounded-full bg-black/35 p-2 text-white transition hover:bg-black/55"
          aria-label="Next slide"
        >
          <span className="text-2xl leading-none">{isRtl ? "\u2039" : "\u203A"}</span>
        </button>

        <div className="absolute bottom-6 left-1/2 z-20 flex -translate-x-1/2 items-center gap-2">
          {parsedSlides.map((_: any, index: number) => (
            <button
              key={index}
              type="button"
              onClick={() => {
                if (isTransitioningRef.current || index === activeIndex) return;
                setActiveIndex(index);
              }}
              aria-label={`Go to slide ${index + 1}`}
              className={`h-2.5 rounded-full transition-all duration-300 ${
                index === activeIndex ? "w-7 bg-[#9FCD00]" : "w-2.5 bg-white/55 hover:bg-white/80"
              }`}
            />
          ))}
        </div>
      </div>
    </section>
  );
}
