import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import * as TabsPrimitive from "@radix-ui/react-tabs";
import { cva } from "class-variance-authority";
import { cn } from "../../lib/utils.js";
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "../DropdownMenu/dropdown-menu.js";
import { useScrollByPage, buildFadeMask, ARROW_BUTTON_WIDTH, OverflowScrollArrow, OverflowMenuTriggerButton } from "../../patterns/horizontal-overflow/horizontal-overflow.js";
import { ICON_SIZE } from "../../patterns/element-anatomy/item-anatomy.js";
import { useScrollEdges } from "../../hooks/use-overflow-items.js";
const TabsContext = React.createContext({ size: "md" });
const TabsValueContext = React.createContext({});
const Tabs = React.forwardRef(({ value, onValueChange, defaultValue, children, ...props }, ref) => {
  const [internalValue, setInternalValue] = React.useState(defaultValue);
  const isControlled = value !== void 0;
  const currentValue = isControlled ? value : internalValue;
  const handleValueChange = React.useCallback(
    (next) => {
      if (!isControlled) setInternalValue(next);
      onValueChange == null ? void 0 : onValueChange(next);
    },
    [isControlled, onValueChange]
  );
  const valueContext = React.useMemo(
    () => ({ value: currentValue, onValueChange: handleValueChange }),
    [currentValue, handleValueChange]
  );
  return /* @__PURE__ */ jsx(TabsValueContext.Provider, { value: valueContext, children: /* @__PURE__ */ jsx(
    TabsPrimitive.Root,
    {
      ref,
      value: currentValue,
      onValueChange: handleValueChange,
      ...props,
      children
    }
  ) });
});
Tabs.displayName = "Tabs";
const TABS_LIST_BASE = [
  "inline-flex items-stretch",
  "gap-[var(--layout-space-loose)]",
  "border-b border-divider"
].join(" ");
const TabsList = React.forwardRef(({ className, size = "sm", overflow = "none", children, ...props }, ref) => {
  const tabsSizeContext = React.useMemo(() => ({ size }), [size]);
  if (overflow === "scroll") {
    return /* @__PURE__ */ jsx(TabsContext.Provider, { value: tabsSizeContext, children: /* @__PURE__ */ jsx(ScrollTabsList, { ref, className, ...props, children }) });
  }
  if (overflow === "menu") {
    return /* @__PURE__ */ jsx(TabsContext.Provider, { value: tabsSizeContext, children: /* @__PURE__ */ jsx(MenuTabsList, { ref, className, ...props, children }) });
  }
  return /* @__PURE__ */ jsx(TabsContext.Provider, { value: tabsSizeContext, children: /* @__PURE__ */ jsx(
    TabsPrimitive.List,
    {
      ref,
      className: cn(TABS_LIST_BASE, "w-full", className),
      ...props,
      children
    }
  ) });
});
TabsList.displayName = "TabsList";
const ScrollTabsList = React.forwardRef(({ className, children, ...props }, ref) => {
  const { scrollRef, atStart, atEnd, canScroll } = useScrollEdges();
  const scrollByPage = useScrollByPage(scrollRef);
  const maskImage = buildFadeMask({
    canScroll,
    atStart,
    atEnd,
    reserveArrowWidth: ARROW_BUTTON_WIDTH
  });
  return (
    // 2026-05-19 fix(scroll-overflow underline clip + y auto-promote):
    //   outer 撤 `border-b` → owner 升到 `TabsList` (TABS_LIST_BASE 含 border-b border-divider)
    //   把 trigger `after:bottom-[-1px]` 2px underline 的下半部 1px 收進 list border-box,
    //   再加 `overflow-y-hidden` 明示阻 browser y auto-promote(CSS overflow-3 spec:
    //   overflow-x:auto + overflow-y:visible 必 compute auto)。
    //   不加 `pb-px`(outer border 撤後 list border 已接 -1px 部分,加 pb 多 1px 多餘空白)。
    //   對齊 Primer UnderlineNav `overflow-x:auto; overflow-y:hidden` canonical 同步動
    //   horizontal-overflow.spec.md(「Hook re-export」+「典型 scroll / menu 模式組裝」段)owner 升 list 內部。
    /* @__PURE__ */ jsxs("div", { className: "relative", children: [
      /* @__PURE__ */ jsx(
        "div",
        {
          ref: scrollRef,
          className: "overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
          style: { maskImage, WebkitMaskImage: maskImage },
          children: /* @__PURE__ */ jsx(
            TabsPrimitive.List,
            {
              ref,
              className: cn(TABS_LIST_BASE, "min-w-full", className),
              ...props,
              children
            }
          )
        }
      ),
      !atStart && canScroll && /* @__PURE__ */ jsx(OverflowScrollArrow, { direction: "left", onClick: () => scrollByPage("left") }),
      !atEnd && canScroll && /* @__PURE__ */ jsx(OverflowScrollArrow, { direction: "right", onClick: () => scrollByPage("right") })
    ] })
  );
});
ScrollTabsList.displayName = "ScrollTabsList";
const MenuTabsList = React.forwardRef(({ className, children, ...props }, ref) => {
  const { scrollRef, atStart, atEnd, canScroll } = useScrollEdges();
  const { onValueChange, value: activeValue } = React.useContext(TabsValueContext);
  const itemRefs = React.useRef(/* @__PURE__ */ new Map());
  const scrollRafIdRef = React.useRef(0);
  React.useEffect(() => () => {
    if (scrollRafIdRef.current) cancelAnimationFrame(scrollRafIdRef.current);
  }, []);
  const registerItem = React.useCallback(
    (index) => (el) => {
      if (el) itemRefs.current.set(index, el);
      else itemRefs.current.delete(index);
    },
    []
  );
  const items = React.useMemo(
    () => React.Children.toArray(children).filter(React.isValidElement),
    [children]
  );
  const enhancedChildren = items.map(
    (child, i) => React.cloneElement(
      child,
      { ref: registerItem(i) }
    )
  );
  const maskImage = buildFadeMask({ canScroll, atStart, atEnd, reserveArrowWidth: 0 });
  const handleMenuSelect = React.useCallback(
    (triggerValue, index) => {
      onValueChange == null ? void 0 : onValueChange(triggerValue);
      if (scrollRafIdRef.current) cancelAnimationFrame(scrollRafIdRef.current);
      scrollRafIdRef.current = requestAnimationFrame(() => {
        var _a;
        scrollRafIdRef.current = 0;
        (_a = itemRefs.current.get(index)) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", inline: "center", block: "nearest" });
      });
    },
    [onValueChange]
  );
  return (
    // 2026-05-19 fix(scroll-overflow underline clip + y auto-promote,parallel to ScrollTabsList):
    //   outer 改 items-stretch(menu button 容器跟 TabsList 含 border 共底線)+ 撤 border。
    //   list 套 TABS_LIST_BASE,inner scroll 加 overflow-y-hidden。menu button 容器自帶
    //   border-b border-divider 跟 TabsList border 同 y 對齊(items-stretch 保證)。
    /* @__PURE__ */ jsxs("div", { className: "flex items-stretch", children: [
      /* @__PURE__ */ jsx(
        "div",
        {
          ref: scrollRef,
          className: "flex-1 min-w-0 overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
          style: { maskImage, WebkitMaskImage: maskImage },
          children: /* @__PURE__ */ jsx(
            TabsPrimitive.List,
            {
              ref,
              className: cn(TABS_LIST_BASE, "min-w-full", className),
              ...props,
              children: enhancedChildren
            }
          )
        }
      ),
      canScroll && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 pl-[var(--layout-space-loose)] flex items-center border-b border-divider", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
        /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
          OverflowMenuTriggerButton,
          {
            "aria-label": `頁籤選單(共 ${items.length} 個)`
          }
        ) }),
        /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", children: items.map((trigger, index) => {
          const triggerProps = trigger.props;
          const triggerValue = triggerProps.value;
          if (typeof triggerValue !== "string") return null;
          return /* @__PURE__ */ jsx(
            DropdownMenuItem,
            {
              disabled: triggerProps.disabled,
              selected: activeValue === triggerValue,
              onSelect: () => handleMenuSelect(triggerValue, index),
              children: triggerProps.children
            },
            triggerValue
          );
        }) })
      ] }) })
    ] })
  );
});
MenuTabsList.displayName = "MenuTabsList";
const tabsTriggerVariants = cva(
  [
    "relative inline-flex items-center justify-center",
    "gap-2",
    "whitespace-nowrap",
    "font-medium text-fg-secondary",
    "transition-colors duration-150",
    "cursor-pointer select-none",
    "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
    // Trigger 無水平 padding — 寬度 = 內容寬度。triggers 間的分隔靠 TabsList 的 gap-[layout-space-loose]
    // selected underline：::after 絕對定位在 bottom:-1px，2px primary-hover
    // left-0/right-0 因為 trigger 已無 padding，底線等於內容寬度
    // 底線蓋住 TabsList 的 1px gray border，視覺單一線條
    "after:absolute after:left-0 after:right-0 after:bottom-[-1px] after:h-0.5",
    "after:bg-transparent after:transition-colors after:duration-150",
    // hover（未選）：文字轉深
    "hover:text-foreground",
    // selected
    "data-[state=active]:text-foreground data-[state=active]:font-medium",
    "data-[state=active]:after:bg-primary-hover",
    // disabled：cursor-not-allowed + 不吃 hover 色
    // 不用 pointer-events-none，否則 cursor 不會改變；button[disabled] 本身就擋 click
    "disabled:cursor-not-allowed disabled:text-fg-disabled",
    "disabled:hover:text-fg-disabled"
  ],
  {
    variants: {
      size: {
        // leading-compact：trigger 是單行文字容器，使用 1.3 行高避免 text-body/body-lg 預設 1.5 造成垂直偏移
        sm: "h-[var(--tab-height-sm)] text-body leading-compact",
        md: "h-[var(--tab-height-md)] text-body leading-compact",
        lg: "h-[var(--tab-height-lg)] text-body-lg leading-compact"
      }
    },
    defaultVariants: {
      // size = 'sm' per header-canonical.spec.md W6:overlay / chrome / dense toolbar
      // 都用 sm;獨立 page hero 用 lg。md 為 future tier(無 recommended use case)。
      // 2026-05-17 從 'md' 改 'sm'(M31 codex 比稿後)— production consumer = 0,
      // 影響面限 stories baseline(已過 visual diff gate)。
      size: "sm"
    }
  }
);
const TabsTrigger = React.forwardRef(({ className, startIcon: StartIcon, badge, endIcon: EndIcon, inlineAction, children, ...props }, ref) => {
  const { size } = React.useContext(TabsContext);
  const iconSize = ICON_SIZE[size];
  const hasSuffix = badge != null || EndIcon !== void 0 || inlineAction != null;
  return /* @__PURE__ */ jsxs(
    TabsPrimitive.Trigger,
    {
      ref,
      className: cn(tabsTriggerVariants({ size }), className),
      ...props,
      children: [
        StartIcon && /* @__PURE__ */ jsx(StartIcon, { size: iconSize, "aria-hidden": true }),
        children != null && /* @__PURE__ */ jsx("span", { children }),
        hasSuffix && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
          badge,
          EndIcon && /* @__PURE__ */ jsx(EndIcon, { size: iconSize, "aria-hidden": true }),
          inlineAction != null && // 2026-05-21 split-click invariant:inlineAction 點擊不冒泡到 TabsPrimitive.Trigger。
          // Radix Tabs 在 3 個 channel 觸發 tab 切換,全部 stopPropagation:
          //   - onMouseDown(primary, Radix Tabs source code main switch trigger)
          //   - onFocus(activationMode='automatic' default,focus 落內部按鈕也算「focused」)
          //   - onKeyDown Enter/Space(鍵盤啟動)
          // 加 onPointerDown / onClick 防禦其他 framework 慣例。
          // 對齊 GitHub「Code ▾」/ Linear "Triage..." split-tab 共識。
          /* @__PURE__ */ jsx(
            "span",
            {
              onPointerDown: (e) => e.stopPropagation(),
              onMouseDown: (e) => e.stopPropagation(),
              onClick: (e) => e.stopPropagation(),
              onFocus: (e) => e.stopPropagation(),
              onKeyDown: (e) => {
                if (e.key === "Enter" || e.key === " ") e.stopPropagation();
              },
              children: inlineAction
            }
          )
        ] })
      ]
    }
  );
});
TabsTrigger.displayName = "TabsTrigger";
const TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
  TabsPrimitive.Content,
  {
    ref,
    className: cn(
      // 與 TabsList 的間距 canonical(2026-06-12 user 拍板):--layout-space-tight(md 12px,
      // density 連動)。依 layoutSpace.spec「親疏 3 級」:Tabs↔Content 同 bundle(第一級,
      // 元件 spec own),值取規則 3「直接功能依賴 = tight」精神(heading → labeled content 同類)。
      // 收斂原 DS-wide 四種土法(無間距 / mt-4 / p-4 / pt-4 — M17 假 SSOT)。
      // full-height 佈局(AppShell pane)用 className="mt-0" 覆寫(tailwind-merge)。
      "mt-[var(--layout-space-tight)]",
      "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
      className
    ),
    ...props
  }
));
TabsContent.displayName = "TabsContent";
const tabsMeta = {
  component: "Tabs",
  family: null,
  // non-family composite / overlay / layout
  variants: {},
  // 注:`fieldHeight` 為 meta 通用 height key;Tabs **不複用 field-height**,值為 `--tab-height-*`(md density,對齊 spec.md size table + uiSize.css)
  sizes: {
    sm: { fieldHeight: 32, iconSize: 16, typography: "body" },
    md: { fieldHeight: 40, iconSize: 16, typography: "body" },
    lg: { fieldHeight: 48, iconSize: 20, typography: "body-lg" }
  },
  states: ["default", "hover", "active", "focus-visible", "disabled"],
  tokens: {
    bg: ["bg-primary-hover", "bg-transparent"],
    fg: ["text-fg-disabled", "text-fg-secondary", "text-foreground"],
    ring: ["ring-ring"]
  },
  defaultSize: "sm"
};
export {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
  tabsMeta,
  tabsTriggerVariants
};
//# sourceMappingURL=tabs.js.map
