"use client";

import React, { useEffect, useRef } from "react";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { cn } from "../lib/utils";

gsap.registerPlugin(ScrollTrigger);

export interface CubeItem {
  title: string;
  image: string;
  href?: string;
  target?: "_blank" | "_self" | "_parent" | "_top";
}

interface ScrollCube3DProps {
  items: CubeItem[];
  showTitles?: boolean;
  cubeSize?: number;
  scrollHeight?: number;
  theme?: "dark" | "light";
  className?: string;
  onItemClick?: (item: CubeItem, index: number) => void;
}

const ScrollCube3D: React.FC<ScrollCube3DProps> = ({
  items = [],
  showTitles = true,
  cubeSize = 380,
  scrollHeight = 1600,
  theme = "dark",
  className,
  onItemClick,
}) => {
  const sectionRef = useRef<HTMLDivElement>(null);
  const cubeRef = useRef<HTMLDivElement>(null);
  const timelineRef = useRef<gsap.core.Timeline | null>(null);

  const themeClasses = {
    dark: "bg-black text-white",
    light: "bg-white text-black",
  };

  const cardClasses = {
    dark: "bg-card border-border shadow-[0_15px_30px_rgba(0,0,0,0.5),0_0_0_1px_rgba(255,255,255,0.05)] border-border/20",
    light: "bg-card border-border shadow-[0_15px_30px_rgba(0,0,0,0.1),0_0_0_1px_rgba(0,0,0,0.05)] border-border/20",
  };

  useEffect(() => {
    if (!cubeRef.current || !sectionRef.current || items.length === 0) return;

    const cube = cubeRef.current;
    const section = sectionRef.current;

    // Clear previous content
    cube.innerHTML = "";

    // Create cube faces
    const faces = ["front-cube", "right-cube", "back-cube", "left-cube"];
    const transforms = [
      `translateZ(${cubeSize / 2}px)`,
      `rotateY(90deg) translateZ(${cubeSize / 2}px)`,
      `rotateY(180deg) translateZ(${cubeSize / 2}px)`,
      `rotateY(-90deg) translateZ(${cubeSize / 2}px)`,
    ];

    // Ensure we have 4 items by cycling through provided items
    const cubeItems = Array.from({ length: 4 }, (_, index) => items[index % items.length]);

    cubeItems.forEach((item, index) => {
      const faceDiv = document.createElement("div");
      faceDiv.className = cn(
        faces[index],
        "h-full w-full absolute flex flex-col justify-end items-center [backface-visibility:hidden] rounded-xl overflow-hidden transition-all duration-300 ease-in-out cursor-pointer",
        cardClasses[theme]
      );
      faceDiv.style.transform = transforms[index];

      const img = document.createElement("img");
      img.src = item.image;
      img.alt = item.title;
      img.className = "w-full h-full object-cover absolute top-0 left-0 [transform:translateZ(0)] grayscale-[50%] transition-all duration-300 ease-in-out hover:grayscale-0 hover:scale-105";

      faceDiv.appendChild(img);

      if (showTitles) {
        const title = document.createElement("h2");
        title.className = cn(
          "relative z-10 text-xl font-semibold p-4 pb-6",
          theme === "dark" ? "text-white" : "text-black"
        );
        title.textContent = item.title;
        faceDiv.appendChild(title);
      }

      // Handle clicks
      faceDiv.addEventListener("click", () => {
        if (item.href) {
          window.open(item.href, item.target || "_self");
        }
        if (onItemClick) {
          onItemClick(item, index);
        }
      });

      cube.appendChild(faceDiv);
    });

    // Create GSAP timeline with ScrollTrigger
    if (timelineRef.current) {
      timelineRef.current.kill();
    }

    // Set the section height to accommodate the scroll animation
    const totalHeight = scrollHeight + window.innerHeight;
    section.style.height = `${totalHeight}px`;

    timelineRef.current = gsap.timeline({
      scrollTrigger: {
        trigger: section,
        start: "top top",
        end: `+=${scrollHeight}`,
        scrub: 1.5,
        pin: ".cube-sticky-container",
        anticipatePin: 1,
      },
    });

    timelineRef.current
      .to(cube, {
        rotationY: -90,
        duration: 1,
        ease: "power2.inOut",
      })
      .to(cube, {
        rotationY: -180,
        duration: 1,
        ease: "power2.inOut",
      })
      .to(cube, {
        rotationY: -270,
        duration: 1,
        ease: "power2.inOut",
      })
      .to(cube, {
        rotationY: -360,
        duration: 1,
      });

    timelineRef.current.set(cube, { rotationY: 0 });

    return () => {
      if (timelineRef.current) {
        timelineRef.current.kill();
      }
      ScrollTrigger.getAll().forEach((trigger) => {
        if (trigger.trigger === section) {
          trigger.kill();
        }
      });
    };
  }, [items, cubeSize, scrollHeight, showTitles, theme, onItemClick]);

  if (items.length === 0) {
    return (
      <div className={cn("w-full h-screen flex items-center justify-center", themeClasses[theme])}>
        <p className="text-muted-foreground">No items provided for the cube carousel</p>
      </div>
    );
  }

  const totalSectionHeight = scrollHeight + window.innerHeight;

  return (
    <div
      ref={sectionRef}
      className={cn(
        "relative w-full overflow-hidden",
        themeClasses[theme],
        className
      )}
      style={{
        height: `${totalSectionHeight}px`
      }}
    >
      {/* Sticky container for the cube */}
      <div className="cube-sticky-container sticky top-0 w-full h-screen flex justify-center items-center">
        <div
          className="flex justify-center items-center"
          style={{
            height: `${cubeSize}px`,
            width: `${cubeSize}px`,
            perspective: "1200px",
          }}
        >
          <div
            ref={cubeRef}
            className="relative"
            style={{
              width: `${cubeSize}px`,
              height: `${cubeSize}px`,
              transformStyle: "preserve-3d",
            }}
          />
        </div>
      </div>
    </div>
  );
};

export default ScrollCube3D;