import { jsx, jsxs, Fragment } from "react/jsx-runtime";
import React__default, { forwardRef, useState, useRef, Children, useEffect, useCallback } from "react";
import { cn } from "../utils/cn.js";
import { Button } from "../button/button.js";
import { C as ChevronLeft, a as ChevronRight } from "../../chevron-right-CKVJjscR.js";
const gapSizes = {
  xs: "gap-1",
  sm: "gap-2",
  md: "gap-4",
  lg: "gap-6",
  xl: "gap-8"
};
const gapPixels = {
  xs: 4,
  sm: 8,
  md: 16,
  lg: 24,
  xl: 32
};
const CarouselSlide = forwardRef(
  ({ children, className }, ref) => {
    return /* @__PURE__ */ jsx(
      "div",
      {
        ref,
        className: cn("min-w-0 h-full w-full", className),
        role: "tabpanel",
        children
      }
    );
  }
);
CarouselSlide.displayName = "CarouselSlide";
const Carousel = forwardRef(
  ({
    children,
    slideIndex,
    onSlideChange,
    showArrows = true,
    showDots = true,
    loop = true,
    autoplay = false,
    duration = 3e3,
    transitionDuration = 400,
    height = "auto",
    slidesToShow = 1,
    slideGap = "md",
    className
  }, ref) => {
    const [currentSlide, setCurrentSlide] = useState(slideIndex ?? 0);
    const [isDragging, setIsDragging] = useState(false);
    const [startX, setStartX] = useState(0);
    const [translateX, setTranslateX] = useState(0);
    const [isPaused, setIsPaused] = useState(false);
    const containerRef = useRef(null);
    const slidesRef = useRef(null);
    const touchStartRef = useRef(0);
    const slides = Children.toArray(children).filter(
      (child) => React__default.isValidElement(child) && child.type === CarouselSlide
    );
    const slidesCount = slides.length;
    const maxSlide = Math.max(0, slidesCount - slidesToShow);
    const pageCount = Math.ceil(slidesCount / slidesToShow);
    const isControlled = slideIndex !== void 0;
    const activeSlide = isControlled ? slideIndex : currentSlide;
    const slideWidth = 100 / slidesToShow;
    useEffect(() => {
      if (isControlled && slideIndex !== void 0) {
        setCurrentSlide(slideIndex);
      }
    }, [slideIndex, isControlled]);
    const handleSlideChange = useCallback(
      (index) => {
        let newIndex = index;
        if (loop) {
          if (index < 0) {
            newIndex = activeSlide <= 0 ? maxSlide : Math.max(0, index);
          } else if (index > maxSlide) {
            newIndex = activeSlide >= maxSlide ? 0 : Math.min(maxSlide, index);
          }
        } else {
          newIndex = Math.max(0, Math.min(maxSlide, index));
        }
        if (!isControlled) {
          setCurrentSlide(newIndex);
        }
        onSlideChange?.(newIndex);
      },
      [isControlled, loop, maxSlide, onSlideChange, activeSlide]
    );
    const goToSlide = useCallback(
      (index) => {
        handleSlideChange(index);
      },
      [handleSlideChange]
    );
    const goToNext = useCallback(() => {
      handleSlideChange(activeSlide + slidesToShow);
    }, [activeSlide, slidesToShow, handleSlideChange]);
    const goToPrevious = useCallback(() => {
      handleSlideChange(activeSlide - slidesToShow);
    }, [activeSlide, slidesToShow, handleSlideChange]);
    const advanceSlide = useCallback(() => {
      if (isControlled) {
        const nextSlide = activeSlide + slidesToShow;
        let finalSlide;
        if (loop) {
          if (nextSlide > maxSlide) {
            finalSlide = activeSlide >= maxSlide ? 0 : Math.min(maxSlide, nextSlide);
          } else {
            finalSlide = nextSlide;
          }
        } else {
          finalSlide = Math.min(nextSlide, maxSlide);
        }
        onSlideChange?.(finalSlide);
      } else {
        setCurrentSlide((prevSlide) => {
          const nextSlide = prevSlide + slidesToShow;
          let finalSlide;
          if (loop) {
            if (nextSlide > maxSlide) {
              finalSlide = prevSlide >= maxSlide ? 0 : Math.min(maxSlide, nextSlide);
            } else {
              finalSlide = nextSlide;
            }
          } else {
            finalSlide = Math.min(nextSlide, maxSlide);
          }
          onSlideChange?.(finalSlide);
          return finalSlide;
        });
      }
    }, [isControlled, activeSlide, slidesToShow, loop, maxSlide, onSlideChange]);
    useEffect(() => {
      if (!autoplay || isPaused || isDragging) return;
      const interval = setInterval(advanceSlide, duration);
      return () => clearInterval(interval);
    }, [autoplay, duration, isPaused, isDragging, advanceSlide]);
    useEffect(() => {
      const handleKeyDown = (e) => {
        if (e.key === "ArrowLeft") {
          goToPrevious();
        } else if (e.key === "ArrowRight") {
          goToNext();
        }
      };
      const container = containerRef.current;
      if (container) {
        container.addEventListener("keydown", handleKeyDown);
        return () => {
          container.removeEventListener("keydown", handleKeyDown);
        };
      }
    }, [goToNext, goToPrevious]);
    const handleDragStart = useCallback((clientX) => {
      setIsDragging(true);
      setStartX(clientX);
      touchStartRef.current = clientX;
    }, []);
    const handleDragMove = useCallback(
      (clientX) => {
        if (!isDragging) return;
        const diff = clientX - startX;
        const containerWidth = containerRef.current?.offsetWidth || 1;
        const maxDrag = containerWidth * 0.3;
        const constrainedDiff = Math.max(-maxDrag, Math.min(maxDrag, diff));
        setTranslateX(constrainedDiff);
      },
      [isDragging, startX]
    );
    const handleDragEnd = useCallback(() => {
      if (!isDragging) return;
      const threshold = 50;
      if (Math.abs(translateX) > threshold) {
        if (translateX > 0) {
          goToPrevious();
        } else {
          goToNext();
        }
      }
      setIsDragging(false);
      setTranslateX(0);
      setStartX(0);
    }, [isDragging, translateX, goToNext, goToPrevious]);
    const handleMouseDown = (e) => {
      e.preventDefault();
    };
    const handleTouchStart = (e) => {
      handleDragStart(e.touches[0].clientX);
    };
    const handleTouchMove = (e) => {
      handleDragMove(e.touches[0].clientX);
    };
    const handleTouchEnd = () => {
      handleDragEnd();
    };
    const getTransform = () => {
      const slideWidthPercent = 100 / slidesToShow;
      const baseTranslatePercent = -(activeSlide * slideWidthPercent);
      const gapSize = gapPixels[slideGap];
      const gapOffset = activeSlide > 0 ? -(activeSlide * gapSize) : 0;
      const containerWidth = containerRef.current?.offsetWidth || 1;
      const dragOffset = isDragging ? translateX / containerWidth * 100 : 0;
      return `translateX(calc(${baseTranslatePercent}% + ${gapOffset}px + ${dragOffset}px))`;
    };
    const showPrevious = loop || activeSlide > 0;
    const showNext = loop || activeSlide < maxSlide;
    const ControlButton = ({
      direction,
      onClick,
      label
    }) => {
      const isVisible = direction === "prev" ? showPrevious : showNext;
      if (!isVisible && !loop) return null;
      return /* @__PURE__ */ jsx(
        Button,
        {
          variant: "secondary",
          size: "md",
          icon: direction === "prev" ? /* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5" }),
          onClick,
          "aria-label": label,
          disabled: !isVisible,
          className: cn(
            "absolute top-1/2 z-10 -translate-y-1/2 rounded-full bg-white/90 shadow-md hover:bg-white hover:shadow-lg",
            {
              "left-4": direction === "prev",
              "right-4": direction === "next"
            }
          )
        }
      );
    };
    return /* @__PURE__ */ jsx(
      "div",
      {
        ref,
        className: cn("relative", className),
        role: "region",
        "aria-label": "Carousel",
        "aria-roledescription": "carousel",
        onMouseEnter: () => setIsPaused(true),
        onMouseLeave: () => setIsPaused(false),
        children: /* @__PURE__ */ jsxs(
          "div",
          {
            ref: containerRef,
            className: "relative overflow-hidden rounded-lg",
            style: {
              height: height === "auto" ? "auto" : typeof height === "number" ? `${height}px` : height
            },
            tabIndex: 0,
            children: [
              /* @__PURE__ */ jsx(
                "div",
                {
                  ref: slidesRef,
                  className: cn("flex transition-transform", gapSizes[slideGap]),
                  style: {
                    transform: getTransform(),
                    transitionDuration: isDragging ? "0ms" : `${transitionDuration}ms`,
                    height: height === "auto" ? "auto" : "100%"
                  },
                  onMouseDown: handleMouseDown,
                  onTouchStart: handleTouchStart,
                  onTouchMove: handleTouchMove,
                  onTouchEnd: handleTouchEnd,
                  children: slides.map((slide, index) => {
                    return /* @__PURE__ */ jsx(
                      "div",
                      {
                        className: "min-w-0 h-full flex-shrink-0 select-none",
                        onDragStart: (e) => e.preventDefault(),
                        style: {
                          flexBasis: `${slideWidth}%`,
                          width: `${slideWidth}%`
                        },
                        role: "tabpanel",
                        "aria-hidden": index < activeSlide || index >= activeSlide + slidesToShow,
                        children: slide.props.children
                      },
                      index
                    );
                  })
                }
              ),
              showArrows && /* @__PURE__ */ jsxs(Fragment, { children: [
                /* @__PURE__ */ jsx(
                  ControlButton,
                  {
                    direction: "prev",
                    onClick: goToPrevious,
                    label: "Previous slide"
                  }
                ),
                /* @__PURE__ */ jsx(
                  ControlButton,
                  {
                    direction: "next",
                    onClick: goToNext,
                    label: "Next slide"
                  }
                )
              ] }),
              showDots && /* @__PURE__ */ jsx(
                "div",
                {
                  className: "absolute bottom-4 left-1/2 z-10 flex -translate-x-1/2 gap-1.5",
                  role: "tablist",
                  children: Array.from({ length: pageCount }).map((_, pageIndex) => {
                    const slideIndex2 = pageIndex * slidesToShow;
                    const isActivePage = Math.floor(activeSlide / slidesToShow) === pageIndex;
                    return /* @__PURE__ */ jsx(
                      "button",
                      {
                        type: "button",
                        role: "tab",
                        "aria-selected": isActivePage,
                        "aria-label": `Go to page ${pageIndex + 1}`,
                        onClick: () => goToSlide(slideIndex2),
                        className: cn(
                          "h-2 rounded-full transition-all cursor-pointer shadow-sm",
                          "focus:outline-none",
                          {
                            "w-6 bg-white": isActivePage,
                            "w-2 bg-white/60 hover:bg-white/80": !isActivePage
                          }
                        )
                      },
                      pageIndex
                    );
                  })
                }
              )
            ]
          }
        )
      }
    );
  }
);
Carousel.displayName = "Carousel";
export {
  Carousel,
  CarouselSlide
};
