import { jsxs, jsx } from "react/jsx-runtime";
import * as React from "react";
import { cva } from "class-variance-authority";
import { X } from "lucide-react";
import { cn } from "../../lib/utils.js";
import { Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/tooltip.js";
import { ItemInlineActionButton } from "../../patterns/element-anatomy/item-anatomy.js";
import { CAT_SUBTLE, CAT_SOLID, CAT_INTERACT } from "../../tokens/categorical-color.js";
let _measureCtx = null;
function getMeasureCtx() {
  if (!_measureCtx) _measureCtx = document.createElement("canvas").getContext("2d");
  return _measureCtx;
}
const tagVariants = cva(
  "inline-flex items-center rounded-md border border-transparent transition-colors cursor-text",
  {
    variants: {
      // color：categorical 色相(裝飾性分類,非語意狀態)。**消費 categorical-color SSOT**——
      // key X 一律對 `--color-X-*`(1:1,零 offset)。neutral 非色相(無 hue),用 secondary 底自處理。
      // 2026-06-04 修:原 `red` 誤接 `--color-deep-orange-*`(red=品牌紅 hue-25 ≠ deep-orange hue-38
      // ≠ 語意 --error〔= deep-orange〕);改消費 SSOT 後 red→`--color-red-*`,並補齊全 12 色相。
      color: {
        neutral: "bg-secondary text-foreground",
        ...CAT_SUBTLE
      },
      size: {
        sm: "h-5 px-1 text-caption font-medium",
        md: "h-6 px-1 text-body font-normal",
        lg: "h-6 px-1 text-body font-normal"
      }
    },
    defaultVariants: {
      color: "neutral",
      size: "md"
    }
  }
);
const SOLID_CLASSES = {
  neutral: "bg-[var(--color-neutral-9)] text-inverse-fg",
  ...CAT_SOLID
};
const SOLID_DISMISS_HOVER = {
  neutral: { hover: "var(--inverse-neutral-hover)", active: "var(--inverse-neutral-active)" },
  ...CAT_INTERACT
};
function TagDismiss({ onRemove, label, solid, color }) {
  const solidColors = solid && color ? SOLID_DISMISS_HOVER[color] : void 0;
  return /* @__PURE__ */ jsx(
    ItemInlineActionButton,
    {
      icon: X,
      size: "md",
      onClick: (e) => {
        e.stopPropagation();
        onRemove();
      },
      "aria-label": `移除 ${label}`,
      style: solidColors ? { "--dismiss-hover": solidColors.hover, "--dismiss-active": solidColors.active } : void 0,
      hoverBgClassName: solidColors ? "group-hover/action:bg-[var(--dismiss-hover)] group-active/action:bg-[var(--dismiss-active)]" : void 0,
      className: "text-current hover:text-current active:text-current"
    }
  );
}
function TagInner({ className, color, size, icon: Icon, avatar, onRemove, solid, unbounded = false, children, style, ...props }, forwardedRef) {
  const solidClass = solid ? SOLID_CLASSES[color ?? "neutral"] : void 0;
  const ownRef = React.useRef(null);
  const [isTruncated, setIsTruncated] = React.useState(false);
  React.useLayoutEffect(() => {
    const el = ownRef.current;
    if (!el) return;
    const ctx = getMeasureCtx();
    const check = () => {
      const textSpan = el.querySelector("[data-tag-text]");
      if (!textSpan || !ctx) return;
      const text = textSpan.textContent || "";
      const cs = getComputedStyle(textSpan);
      ctx.font = `${cs.fontWeight} ${cs.fontSize} ${cs.fontFamily}`;
      const textWidth = ctx.measureText(text).width;
      const padL = parseFloat(cs.paddingLeft) || 0;
      const padR = parseFloat(cs.paddingRight) || 0;
      const needed = textWidth + padL + padR;
      setIsTruncated(needed > textSpan.clientWidth + 1);
    };
    check();
    const obs = new ResizeObserver(check);
    obs.observe(el);
    return () => obs.disconnect();
  }, [children]);
  const label = typeof children === "string" ? children : "";
  const tag = /* @__PURE__ */ jsxs(
    "div",
    {
      ref: (el) => {
        ownRef.current = el;
        if (typeof forwardedRef === "function") forwardedRef(el);
        else if (forwardedRef) forwardedRef.current = el;
      },
      "data-tag-root": "",
      className: cn(tagVariants({ color, size }), solidClass, "w-fit min-w-0 overflow-hidden", className),
      style: {
        maxWidth: unbounded ? "var(--combobox-tag-area-inline-size, 100%)" : "min(var(--combobox-tag-area-inline-size, 10rem), 10rem)",
        ...style
      },
      ...props,
      children: [
        Icon && /* @__PURE__ */ jsx(Icon, { size: 16, "aria-hidden": true }),
        avatar && /* @__PURE__ */ jsx("span", { className: "shrink-0 w-4 h-4 rounded-full overflow-hidden inline-grid place-content-center [&>*]:w-full [&>*]:h-full", children: avatar }),
        /* @__PURE__ */ jsx("span", { "data-tag-text": "", className: "px-1 truncate min-w-0", children }),
        onRemove && /* @__PURE__ */ jsx(TagDismiss, { onRemove, label, solid, color: color ?? "neutral" })
      ]
    }
  );
  if (!isTruncated) return tag;
  return /* @__PURE__ */ jsxs(Tooltip, { children: [
    /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: tag }),
    /* @__PURE__ */ jsx(TooltipContent, { children })
  ] });
}
const Tag = React.forwardRef(TagInner);
Tag.displayName = "Tag";
const tagMeta = {
  component: "Tag",
  family: 3,
  // categorical 色相(裝飾性分類,非語意狀態)。**1:1 對 `--color-{hue}-*` primitive,零 offset**。
  // 不對應語意 token——語意狀態(error/info/success/warning)走 Notice / Alert 等狀態元件,
  // 不是 Tag 色相。2026-06-04 修:移除原「red 對應 --error / blue 對應 --info ...」誤導框架
  // (red = 品牌紅 hue-25,跟語意 --error〔= deep-orange〕無關)。
  variants: {
    neutral: { purpose: "通用分類、草稿、無特定語義(secondary 底)" },
    blue: { purpose: "categorical 色相(--color-blue-*)" },
    green: { purpose: "categorical 色相(--color-green-*)" },
    "deep-orange": { purpose: "categorical 色相(--color-deep-orange-*,hue 38)" },
    yellow: { purpose: "categorical 色相(--color-yellow-*,淺底深字)" },
    red: { purpose: "categorical 色相(--color-red-*,品牌紅家族 hue 25;≠ 語意 --error)" },
    orange: { purpose: "categorical 色相(--color-orange-*)" },
    amber: { purpose: "categorical 色相(--color-amber-*,淺底深字)" },
    lime: { purpose: "categorical 色相(--color-lime-*)" },
    turquoise: { purpose: "categorical 色相(--color-turquoise-*)" },
    indigo: { purpose: "categorical 色相(--color-indigo-*)" },
    purple: { purpose: "categorical 色相(--color-purple-*)" },
    magenta: { purpose: "categorical 色相(--color-magenta-*)" }
  },
  sizes: {
    // Tag 尺寸不引用 field-height token（spec.md:180/241——Tag 與 Field 尺寸獨立）。
    // height = Tag 自身高度（cva h-5/h-6/h-6 = 20/24/24，lg = md alias）。
    // iconSize 全尺寸統一 16（tag.tsx:195 硬寫 size={16}）。
    sm: { height: 20, iconSize: 16, typography: "caption" },
    md: { height: 24, iconSize: 16, typography: "body" },
    lg: { height: 24, iconSize: 16, typography: "body" }
  },
  // Tag 為純展示 indicator，無互動 state（spec.md:249-256「為何無 StateBehavior」）。
  // 唯一行為 dismiss 屬 Inline Action pattern，非 Tag 自有 state。
  states: ["default"],
  tokens: {
    bg: ["bg-neutral-active", "bg-neutral-hover", "bg-secondary", "bg-transparent"],
    fg: ["text-foreground", "text-inverse-fg"],
    ring: []
  },
  defaultVariant: "neutral",
  defaultSize: "md"
};
export {
  Tag,
  tagMeta,
  tagVariants
};
//# sourceMappingURL=tag.js.map
