import React, { type PropsWithChildren, useState } from "react";
import Button from "./ui/Button";
import { useSwipeable } from "react-swipeable";
import { motion } from "motion/react";
import clsx from "clsx";

interface SliderItemProps {
  text: string;
}

function flattenChildren(children: React.ReactNode): React.ReactElement[] {
  const result: React.ReactElement[] = [];

  React.Children.forEach(children, (child) => {
    if (React.isValidElement(child)) {
      if (child.type === React.Fragment) {
        result.push(
          ...flattenChildren(
            (child.props as { children?: React.ReactNode }).children
          )
        );
      } else {
        result.push(child);
      }
    }
  });

  return result;
}

function NewUnitSlider({ children }: PropsWithChildren) {
  const [currentSlide, setCurrentSlide] = useState(0);

  const flattenedChildren = flattenChildren(children);
  const slides = flattenedChildren.map((element, index) => {
    if (
      React.isValidElement<PropsWithChildren<SliderItemProps>>(element) &&
      element.props.text
    ) {
      return {
        index,
        element,
        text: element.props.text,
        child: element.props.children,
      };
    }
    return {
      index,
      text: `Slide ${index + 1}`,
      element,
    };
  });

  const handlers = useSwipeable({
    onSwipedLeft: () => {
      const slideText = slides[currentSlide]?.text;
      if (slideText !== "Interior") {
        setCurrentSlide(Math.min(currentSlide + 1, slides.length - 1));
      }
    },
    onSwipedRight: () => setCurrentSlide(Math.max(currentSlide - 1, 0)),
    preventScrollOnSwipe: true,
    touchEventOptions: {
      passive: false,
    },
    trackMouse: true,
  });

  return (
    <div
      className="relative size-full overflow-hidden 2xl:rounded-[1.111vw] rounded-xl border border-[#E2E2DC]"
      {...handlers}
    >
      <motion.div
        animate={{
          x: `calc(-${currentSlide} * 100%)`,
        }}
        transition={{
          duration: 0.5,
          ease: "easeInOut",
        }}
        className="flex relative top-0 size-full"
      >
        {slides.map((slide) => slide.element)}
      </motion.div>
      <div className="absolute flex 2xl:gap-[0.278vw] gap-1 items-center 2xl:bottom-[1.667vw] md:max-2xl:bottom-6 left-1/2 -translate-x-1/2 max-md:hidden">
        {slides.map((slide, index) => (
          <Button
            key={slide.text}
            variant={currentSlide === index ? "cta" : "primary"}
            onClick={() => setCurrentSlide(index)}
            className="max-md:hidden"
          >
            {slide.text}
          </Button>
        ))}
      </div>
      <div className="flex absolute bottom-4 left-1/2 gap-1 -translate-x-1/2 md:hidden">
        {slides.map((_, index) => (
          <div
            key={index}
            className={clsx(
              "size-2 rounded-full transition-colors duration-300",
              currentSlide === index ? "bg-[#00BED7]" : "bg-[#E2E2DC]"
            )}
          />
        ))}
      </div>
    </div>
  );
}

export default NewUnitSlider;
