"use client";

import React, { useRef } from "react";
import Image from "next/image";
import gsap from "gsap";
import { useIsomorphicLayoutEffect } from "@/hooks/use-isomorphic-layout-effect";
import { cn } from "@/lib/utils";

interface ImageRevealParallaxProps {
  src: string;
  alt: string;
  direction?: "left" | "right" | "top" | "bottom";
  speed?: number;
  className?: string;
  imageClassName?: string;
  width?: number;
  height?: number;
  quality?: number;
  blurDataURL?: string;
}

export const ImageRevealParallax: React.FC<ImageRevealParallaxProps> = ({
  src,
  alt,
  direction = "left",
  speed = 1,
  className = "",
  imageClassName = "",
  width,
  height,
  quality = 90,
  blurDataURL,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const imageRef = useRef<HTMLDivElement>(null);
  const maskRef = useRef<HTMLDivElement>(null);

  useIsomorphicLayoutEffect(() => {
    if (!containerRef.current || !maskRef.current) return;

    const ctx = gsap.context(() => {
      // Set initial mask position based on direction
      const initialMask = getInitialMask(direction);
      gsap.set(maskRef.current, initialMask);

      // Animate mask reveal
      const revealAnimation = gsap.to(maskRef.current, {
        ...getRevealAnimation(direction),
        ease: "power2.inOut",
        scrollTrigger: {
          trigger: containerRef.current,
          start: "top 80%",
          end: "bottom 20%",
          scrub: true,
        },
      });

      // Parallax effect on image
      const parallaxAnimation = gsap.to(imageRef.current, {
        yPercent: -20 * speed,
        ease: "none",
        scrollTrigger: {
          trigger: containerRef.current,
          start: "top bottom",
          end: "bottom top",
          scrub: 1,
        },
      });

      return () => {
        revealAnimation.kill();
        parallaxAnimation.kill();
      };
    });

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

  const getInitialMask = (dir: string) => {
    switch (dir) {
      case "left":
        return { clipPath: "inset(0% 100% 0% 0%)" };
      case "right":
        return { clipPath: "inset(0% 0% 0% 100%)" };
      case "top":
        return { clipPath: "inset(100% 0% 0% 0%)" };
      case "bottom":
        return { clipPath: "inset(0% 0% 100% 0%)" };
      default:
        return { clipPath: "inset(0% 100% 0% 0%)" };
    }
  };

  const getRevealAnimation = (dir: string) => {
    switch (dir) {
      case "left":
      case "right":
        return { clipPath: "inset(0% 0% 0% 0%)", duration: 1 };
      case "top":
      case "bottom":
        return { clipPath: "inset(0% 0% 0% 0%)", duration: 1 };
      default:
        return { clipPath: "inset(0% 0% 0% 0%)", duration: 1 };
    }
  };

  return (
    <div
      ref={containerRef}
      className={cn(
        "image-reveal-parallax",
        "relative overflow-hidden",
        className
      )}
    >
      <div
        ref={imageRef}
        className="image-reveal-content will-change-transform"
      >
        <Image
          src={src}
          alt={alt}
          width={width}
          height={height}
          quality={quality}
          blurDataURL={blurDataURL}
          className={cn("w-full h-full object-cover", imageClassName)}
          sizes="(max-width: 768px) 100vw, (max-width: 1200px) 80vw, 70vw"
        />
      </div>

      {/* Mask for reveal effect */}
      <div
        ref={maskRef}
        className="absolute inset-0 bg-white pointer-events-none"
        style={{
          clipPath: "inset(0% 100% 0% 0%)",
        }}
      />
    </div>
  );
};
