import { jsx } from "react/jsx-runtime";
import * as React from "react";
import useEmblaCarousel from "embla-carousel-react";
import { ChevronRight, ChevronLeft } from "lucide-react";
import { cn } from "../../lib/utils.js";
import { Button } from "../Button/button.js";
const CarouselContext = React.createContext(null);
function useCarousel() {
  const ctx = React.useContext(CarouselContext);
  if (!ctx) throw new Error("useCarousel 必須在 <Carousel> 內使用");
  return ctx;
}
const Carousel = React.forwardRef(
  ({
    orientation = "horizontal",
    opts,
    setApi,
    plugins,
    className,
    children,
    ...props
  }, ref) => {
    const [carouselRef, api] = useEmblaCarousel(
      { ...opts, axis: orientation === "horizontal" ? "x" : "y" },
      plugins
    );
    const [canScrollPrev, setCanScrollPrev] = React.useState(false);
    const [canScrollNext, setCanScrollNext] = React.useState(false);
    const [selectedIndex, setSelectedIndex] = React.useState(0);
    const [scrollSnaps, setScrollSnaps] = React.useState([]);
    const onSelect = React.useCallback((a) => {
      if (!a) return;
      setCanScrollPrev(a.canScrollPrev());
      setCanScrollNext(a.canScrollNext());
      setSelectedIndex(a.selectedScrollSnap());
    }, []);
    const scrollPrev = React.useCallback(() => api == null ? void 0 : api.scrollPrev(), [api]);
    const scrollNext = React.useCallback(() => api == null ? void 0 : api.scrollNext(), [api]);
    const scrollTo = React.useCallback((i) => api == null ? void 0 : api.scrollTo(i), [api]);
    React.useEffect(() => {
      if (!api || !setApi) return;
      setApi(api);
    }, [api, setApi]);
    React.useEffect(() => {
      if (!api) return;
      setScrollSnaps(api.scrollSnapList());
      onSelect(api);
      api.on("reInit", onSelect);
      api.on("select", onSelect);
      return () => {
        api == null ? void 0 : api.off("select", onSelect);
        api == null ? void 0 : api.off("reInit", onSelect);
      };
    }, [api, onSelect]);
    const handleKeyDown = (e) => {
      const prevKey = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
      const nextKey = orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
      if (e.key === prevKey) {
        e.preventDefault();
        scrollPrev();
      } else if (e.key === nextKey) {
        e.preventDefault();
        scrollNext();
      }
    };
    const contextValue = React.useMemo(
      () => ({
        carouselRef,
        api,
        opts,
        orientation,
        scrollPrev,
        scrollNext,
        scrollTo,
        canScrollPrev,
        canScrollNext,
        selectedIndex,
        scrollSnaps
      }),
      [
        carouselRef,
        api,
        opts,
        orientation,
        scrollPrev,
        scrollNext,
        scrollTo,
        canScrollPrev,
        canScrollNext,
        selectedIndex,
        scrollSnaps
      ]
    );
    return /* @__PURE__ */ jsx(CarouselContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
      "div",
      {
        ref,
        onKeyDownCapture: handleKeyDown,
        className: cn("group/carousel relative", className),
        role: "region",
        "aria-roledescription": "carousel",
        "aria-label": "輪播",
        ...props,
        children
      }
    ) });
  }
);
Carousel.displayName = "Carousel";
const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
  const { carouselRef, orientation } = useCarousel();
  return /* @__PURE__ */ jsx("div", { ref: carouselRef, className: "overflow-hidden", children: /* @__PURE__ */ jsx(
    "div",
    {
      ref,
      className: cn(
        "flex",
        orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
        className
      ),
      ...props
    }
  ) });
});
CarouselContent.displayName = "CarouselContent";
const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
  const { orientation } = useCarousel();
  return /* @__PURE__ */ jsx(
    "div",
    {
      ref,
      role: "group",
      "aria-roledescription": "slide",
      className: cn(
        "min-w-0 shrink-0 grow-0 basis-full",
        orientation === "horizontal" ? "pl-4" : "pt-4",
        className
      ),
      ...props
    }
  );
});
CarouselItem.displayName = "CarouselItem";
const arrowWrapperClass = cn(
  "absolute z-10",
  "transition-opacity duration-200",
  "opacity-0 group-hover/carousel:opacity-100",
  "focus-within:opacity-100",
  "[&:has(button:disabled)]:opacity-0 [&:has(button:disabled)]:pointer-events-none"
);
const CarouselPrevious = React.forwardRef(
  ({
    className,
    "aria-label": ariaLabel = "上一張"
    /* i18n-allow: DS default; consumer override via aria-label prop */
  }, ref) => {
    const { orientation, scrollPrev, canScrollPrev } = useCarousel();
    return /* @__PURE__ */ jsx(
      "div",
      {
        className: cn(
          arrowWrapperClass,
          orientation === "horizontal" ? "left-3 top-1/2 -translate-y-1/2" : "top-3 left-1/2 -translate-x-1/2 rotate-90",
          className
        ),
        children: /* @__PURE__ */ jsx(
          Button,
          {
            ref,
            variant: "tertiary",
            size: "md",
            iconOnly: true,
            startIcon: ChevronLeft,
            "aria-label": ariaLabel,
            disabled: !canScrollPrev,
            onClick: scrollPrev,
            className: "rounded-full"
          }
        )
      }
    );
  }
);
CarouselPrevious.displayName = "CarouselPrevious";
const CarouselNext = React.forwardRef(
  ({
    className,
    "aria-label": ariaLabel = "下一張"
    /* i18n-allow: DS default; consumer override via aria-label prop */
  }, ref) => {
    const { orientation, scrollNext, canScrollNext } = useCarousel();
    return /* @__PURE__ */ jsx(
      "div",
      {
        className: cn(
          arrowWrapperClass,
          orientation === "horizontal" ? "right-3 top-1/2 -translate-y-1/2" : "bottom-3 left-1/2 -translate-x-1/2 rotate-90",
          className
        ),
        children: /* @__PURE__ */ jsx(
          Button,
          {
            ref,
            variant: "tertiary",
            size: "md",
            iconOnly: true,
            startIcon: ChevronRight,
            "aria-label": ariaLabel,
            disabled: !canScrollNext,
            onClick: scrollNext,
            className: "rounded-full"
          }
        )
      }
    );
  }
);
CarouselNext.displayName = "CarouselNext";
const CarouselDots = React.forwardRef(({ className, ...props }, ref) => {
  const { scrollSnaps, selectedIndex, scrollTo } = useCarousel();
  if (scrollSnaps.length <= 1) return null;
  return /* @__PURE__ */ jsx(
    "div",
    {
      ref,
      className: cn(
        "absolute bottom-3 left-1/2 -translate-x-1/2 z-10",
        "flex items-center gap-1.5",
        className
      ),
      role: "group",
      "aria-label": "輪播指示器",
      ...props,
      children: scrollSnaps.map((_, i) => /* @__PURE__ */ jsx(
        "button",
        {
          type: "button",
          "aria-current": i === selectedIndex ? "true" : void 0,
          "aria-label": `跳至第 ${i + 1} 張`,
          onClick: () => scrollTo(i),
          className: cn(
            "h-1.5 rounded-full transition-all",
            // 2026-06-11 a11y(R2;Phase B codex 修重疊):hit-area 垂直擴至 24px、水平 ±3px(dot 6px+gap 6px → 中心距 12px,±3 恰相切零重疊;再寬必互搶點擊)
            // — 視覺 dot 維持 6×6 不變,僅點擊目標擴大(anatomy story 原宣稱的 hit-area 機制補真)
            'relative before:absolute before:-inset-y-[9px] before:-inset-x-[3px] before:content-[""]',
            // Dots 疊在 media(image/video)之上,不是 token color 底——用 --on-emphasis 保持語義
            // 跟其他「於飽和色底上的淺色前景」一致
            "bg-on-emphasis/60 hover:bg-on-emphasis/80",
            "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
            i === selectedIndex ? "w-6 bg-on-emphasis" : "w-1.5"
          )
        },
        i
      ))
    }
  );
});
CarouselDots.displayName = "CarouselDots";
const carouselMeta = {
  component: "Carousel",
  family: null,
  // non-family composite / overlay / layout
  variants: {},
  sizes: {},
  states: ["default", "hover", "active", "focus-visible", "disabled"],
  tokens: {
    bg: [],
    fg: [],
    ring: ["ring-ring"]
  }
};
export {
  Carousel,
  CarouselContent,
  CarouselDots,
  CarouselItem,
  CarouselNext,
  CarouselPrevious,
  carouselMeta
};
//# sourceMappingURL=carousel.js.map
