import React, {
  useState,
  useCallback,
  useMemo,
  useEffect,
  useRef,
} from "react";
import {
  motion,
  AnimatePresence,
  useMotionValue,
  useTransform,
} from "framer-motion";
import Image from "next/image";

import ExploreImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Explore.png";
import FabricsCollectionImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Fabrics Collection.png";
import ProductImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Product.png";
import SearchImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Search.png";
import SignInEmailImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Sign In - Email.png";
import SignInPasswordImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Sign In - Password.png";
import SignInImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Sign In.png";
import SizeProfile1Image from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Size Profile-1.png";
import SizeProfile2Image from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Size Profile-2.png";
import SizeProfileImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Size Profile.png";
import SizingAdjustmentsImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Sizing Adjustments.png";
import SplashScreenImage from "@/../public/maintenance/projects/personalized-fashion-platfrom/images/Splash Screen.png";

enum ScreenSize {
  MOBILE = "mobile",
  TABLET = "tablet",
  WEB = "web",
}

interface ProjectImage {
  id: string;
  title: string;
  subtitle: string;
  screenSize: ScreenSize;
  href: any;
}

interface Project {
  id: number;
  name: string;
  description: string;
  images: ProjectImage[];
}

interface ProjectGroup {
  id: number;
  name: string;
  projects: Project[];
}

// Image dimensions in pixels
const IMAGE_WIDTH = 383;
const IMAGE_HEIGHT = 852;

const importAll = (r: any) => {
  let images: any = {};
  r.keys().forEach((item: any) => {
    images[item.replace("./", "")] = r(item);
  });
  return images;
};

const projectGroupsData: ProjectGroup[] = [
  {
    id: 1,
    name: "Personalized Fashion Platform",
    projects: [
      {
        id: 201,
        name: "Fashion App Screens",
        description: "Various screens from our personalized fashion platform",
        images: [
          {
            id: "201-explore",
            title: "Explore Screen",
            subtitle: "Discover new styles",
            screenSize: ScreenSize.MOBILE,
            href: ExploreImage,
          },
          {
            id: "201-fabrics",
            title: "Fabrics Collection",
            subtitle: "Browse fabric options",
            screenSize: ScreenSize.MOBILE,
            href: FabricsCollectionImage,
          },
          {
            id: "201-product",
            title: "Product Screen",
            subtitle: "View product details",
            screenSize: ScreenSize.MOBILE,
            href: ProductImage,
          },
          {
            id: "201-search",
            title: "Search Screen",
            subtitle: "Find your perfect style",
            screenSize: ScreenSize.MOBILE,
            href: SearchImage,
          },
          {
            id: "201-signin-email",
            title: "Sign In - Email",
            subtitle: "Enter your email",
            screenSize: ScreenSize.MOBILE,
            href: SignInEmailImage,
          },
          {
            id: "201-signin-password",
            title: "Sign In - Password",
            subtitle: "Enter your password",
            screenSize: ScreenSize.MOBILE,
            href: SignInPasswordImage,
          },
          {
            id: "201-signin",
            title: "Sign In",
            subtitle: "Access your account",
            screenSize: ScreenSize.MOBILE,
            href: SignInImage,
          },
          {
            id: "201-size-profile-1",
            title: "Size Profile - Step 1",
            subtitle: "Enter your measurements",
            screenSize: ScreenSize.MOBILE,
            href: SizeProfile1Image,
          },
          {
            id: "201-size-profile-2",
            title: "Size Profile - Step 2",
            subtitle: "Refine your fit",
            screenSize: ScreenSize.MOBILE,
            href: SizeProfile2Image,
          },
          {
            id: "201-size-profile",
            title: "Size Profile",
            subtitle: "View your size profile",
            screenSize: ScreenSize.MOBILE,
            href: SizeProfileImage,
          },
          {
            id: "201-sizing-adjustments",
            title: "Sizing Adjustments",
            subtitle: "Fine-tune your fit",
            screenSize: ScreenSize.MOBILE,
            href: SizingAdjustmentsImage,
          },
          {
            id: "201-splash",
            title: "Splash Screen",
            subtitle: "Welcome to the app",
            screenSize: ScreenSize.MOBILE,
            href: SplashScreenImage,
          },
        ],
      },
    ],
  },
];

const GroupedWheelControlledCarousel = () => {
  const itemGroups = useMemo(
    () =>
      projectGroupsData.map((group) => ({
        id: group.id,
        name: group.name,
        items: group.projects.flatMap((project) =>
          project.images.map((image) => ({
            id: image.id,
            item: image.href,
            title: image.title,
            subtitle: image.subtitle,
            projectName: project.name,
            projectDescription: project.description,
            screenSize: image.screenSize,
          })),
        ),
      })),
    [],
  );

  const flattenedItems = useMemo(
    () =>
      itemGroups.flatMap((group) =>
        group.items.map((item, idx) => ({
          ...item,
          groupId: group.id,
          groupName: group.name,
          id: `${group.id}-${idx}`,
        })),
      ),
    [itemGroups],
  );

  const totalItems = flattenedItems.length;
  const [visibleItemCount, setVisibleItemCount] = useState(7);
  const [containerWidth, setContainerWidth] = useState(600);
  const [containerHeight, setContainerHeight] = useState(200);

  const [offset, setOffset] = useState(0);
  const dragX = useMotionValue(0);
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handleWheel = (event: WheelEvent) => {
      event.preventDefault();
      const delta = event.deltaX * 0.005; // Reduced multiplier for smoother scrolling
      setOffset((prevOffset) => {
        const newOffset = prevOffset + delta;
        return newOffset - Math.floor(newOffset / totalItems) * totalItems;
      });
    };

    const container = containerRef.current;
    if (container) {
      container.addEventListener("wheel", handleWheel, { passive: false });
    }

    return () => {
      if (container) {
        container.removeEventListener("wheel", handleWheel);
      }
    };
  }, [totalItems]);

  const handleDrag = useCallback(
    (event: any, info: any) => {
      const dragDelta = info.delta.x * 0.005; // Adjust this multiplier as needed
      setOffset((prevOffset) => {
        const newOffset = prevOffset - dragDelta;
        return newOffset - Math.floor(newOffset / totalItems) * totalItems;
      });
    },
    [totalItems],
  );

  const visibleItems = useMemo(() => {
    const items = [];
    const halfVisible = Math.floor(visibleItemCount / 2);

    for (let i = -halfVisible; i <= halfVisible; i++) {
      const itemIndex = Math.floor(offset + i);
      const wrappedIndex = ((itemIndex % totalItems) + totalItems) % totalItems;
      const item = flattenedItems[wrappedIndex];

      const position = (i - (offset % 1)) / halfVisible;

      // Calculate opacity based on position
      const opacity = Math.cos((position * Math.PI) / 2);

      // Only include items with opacity > 0
      if (opacity > 0) {
        items.push({
          ...item,
          position,
          opacity,
        });
      }
    }

    return items;
  }, [offset, flattenedItems, totalItems, visibleItemCount]);

  const activeGroups = useMemo(() => {
    const groups = new Set(visibleItems.map((item) => item.groupId));
    return groups;
  }, [visibleItems]);

  const pathD = useMemo(() => {
    const midY = containerHeight / 2;
    const controlY = containerHeight / 4;
    const rx = containerWidth / 2 + 360;
    const ry = containerHeight / 2 - 40;
    const centerX = containerWidth / 2;
    const centerY = containerHeight / 2;
    const startAngle = 150 * (Math.PI / 180);
    const endAngle = 30 * (Math.PI / 180);

    const startX = centerX + rx * Math.cos(startAngle);
    const startY = centerY + ry * Math.sin(startAngle);
    const endX = centerX + rx * Math.cos(endAngle);
    const endY = centerY + ry * Math.sin(endAngle);

    return `M${startX},${startY} A${rx},${ry} 0 0 0 ${endX},${endY}`;
  }, [containerWidth, containerHeight]);

  return (
    <div className="mx-auto h-full w-full">
      <div className="pointer-events-none absolute inset-0"></div>
      <motion.div
        ref={containerRef}
        className="relative mb-4 flex items-center justify-center overflow-visible rounded-lg bg-gray-100"
        style={{
          width: `${100}%`,
          height: `${(containerWidth / 5) * (IMAGE_HEIGHT / IMAGE_WIDTH)}px`,
        }}
        drag="x"
        dragConstraints={{ left: 0, right: 0 }}
        dragElastic={0.05}
        onDrag={handleDrag}
      >
        <svg
          width={"100%"}
          height={containerHeight}
          className="absolute left-0 top-0"
        >
          <path d={pathD} fill="none" stroke="lightgray" />
        </svg>
        <div
          style={{
            width: `${containerWidth}px`,
            height: `${(containerWidth / 5) * (IMAGE_HEIGHT / IMAGE_WIDTH)}px`,
          }}
        >
          <AnimatePresence initial={false}>
            {visibleItems.map((itemObj) => {
              const normalizedPosition = (itemObj.position + 1) / 2; // Convert position to range 0-1
              const distanceFromCenter = Math.abs(normalizedPosition - 0.5);
              const opacity = Math.max(0, 1 - distanceFromCenter * 0.5); // Faster fade-out
              const scale = 0.8 + (1 - distanceFromCenter) * 0.5; // Scale down towards edges

              return (
                <motion.div
                  key={itemObj.id}
                  className="absolute -translate-x-1/2 -translate-y-1/2 transform opacity-0"
                  style={{
                    offsetPath: `path("${pathD}")`,
                    offsetDistance: `${normalizedPosition * 100}%`,
                    opacity: opacity,
                    zIndex: Math.round((1 - distanceFromCenter) * 100),
                    pointerEvents: opacity > 0.1 ? "auto" : "none", // Disable interactions for nearly invisible items
                  }}
                  initial={{ opacity: 0, scale: 0.8 }}
                  animate={{ opacity: opacity, scale: scale }}
                  exit={{ opacity: 0, scale: 0.8 }}
                  transition={{
                    duration: 0.1,
                    opacity: {
                      duration: 0.07,
                    },
                  }}
                >
                  <Image
                    src={itemObj.item}
                    alt={`${itemObj.projectName} - ${itemObj.title}`}
                    width={containerWidth / 5}
                    height={(containerWidth / 5) * (IMAGE_HEIGHT / IMAGE_WIDTH)}
                    className="rounded-lg object-cover"
                  />
                </motion.div>
              );
            })}
          </AnimatePresence>
        </div>
      </motion.div>
      <div className="flex justify-center space-x-2">
        {itemGroups.map((group) => (
          <div
            key={group.id}
            className={`h-3 w-3 rounded-full ${
              activeGroups.has(group.id) ? "bg-blue-500" : "bg-gray-300"
            }`}
            title={group.name}
          />
        ))}
      </div>
      <div className="mt-2 text-center">
        Active Groups:{" "}
        {Array.from(activeGroups)
          .map((groupId) => {
            const group = itemGroups.find((g) => g.id === groupId);
            return group ? group.name : "";
          })
          .join(", ")}
      </div>
    </div>
  );
};

export default GroupedWheelControlledCarousel;


Use framer motion.