import { jsxs, jsx } from "react/jsx-runtime";
import * as React from "react";
import { ChevronLeft, ChevronRight, Plus } from "lucide-react";
import { startOfMonth, endOfMonth, startOfWeek, endOfWeek, eachDayOfInterval, isSameMonth, isSameDay, format, subMonths, addMonths } from "date-fns";
import { cn } from "../../lib/utils.js";
import { CAT_ACCENT, CAT_EVENT } from "../../tokens/categorical-color.js";
import { Button } from "../Button/button.js";
import { SegmentedControl, SegmentedControlItem } from "../SegmentedControl/segmented-control.js";
const EVENT_COLOR_CLASSES = CAT_EVENT;
const EVENT_ALLDAY_ACCENT = CAT_ACCENT;
function coerceDate(value) {
  return value instanceof Date ? value : new Date(value);
}
function eventsOnDate(events, date) {
  return events.filter((e) => {
    const start = coerceDate(e.start);
    const end = coerceDate(e.end);
    const d = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
    const s = new Date(start.getFullYear(), start.getMonth(), start.getDate()).getTime();
    const eEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate()).getTime();
    return d >= s && d <= eEnd;
  });
}
const MAX_TILES_PER_CELL = 3;
const Calendar = React.forwardRef(function Calendar2({
  view: viewProp,
  defaultView = "month",
  onViewChange,
  referenceDate: referenceDateProp,
  defaultReferenceDate,
  onReferenceDateChange,
  events = [],
  onEventClick,
  onDateClick,
  onCreateEvent,
  weekStartsOn = 0,
  renderEventTile,
  size = "md",
  className,
  locale = "en-US",
  prevAriaLabel = "上個月",
  // i18n-allow: DS default; consumer override via prevAriaLabel prop
  nextAriaLabel = "下個月",
  // i18n-allow: DS default; consumer override via nextAriaLabel prop
  navAriaLabel = "行事曆月份導覽",
  // i18n-allow: DS default; consumer override via navAriaLabel prop
  viewToggleAriaLabel = "檢視切換",
  // i18n-allow: DS default; consumer override via viewToggleAriaLabel prop
  todayLabel = "今天",
  // i18n-allow: DS default; consumer override via todayLabel prop
  ...props
}, ref) {
  const [internalRef, setInternalRef] = React.useState(
    defaultReferenceDate ?? /* @__PURE__ */ new Date()
  );
  const refDate = referenceDateProp ?? internalRef;
  const setRefDate = React.useCallback(
    (next) => {
      if (referenceDateProp === void 0) setInternalRef(next);
      onReferenceDateChange == null ? void 0 : onReferenceDateChange(next);
    },
    [referenceDateProp, onReferenceDateChange]
  );
  const [internalView, setInternalView] = React.useState(defaultView);
  const currentView = viewProp ?? internalView;
  const setView = React.useCallback(
    (next) => {
      if (viewProp === void 0) setInternalView(next);
      onViewChange == null ? void 0 : onViewChange(next);
    },
    [viewProp, onViewChange]
  );
  const days = React.useMemo(() => {
    const monthStart = startOfMonth(refDate);
    const monthEnd = endOfMonth(refDate);
    const gridStart = startOfWeek(monthStart, { weekStartsOn });
    const gridEnd = endOfWeek(monthEnd, { weekStartsOn });
    return eachDayOfInterval({ start: gridStart, end: gridEnd });
  }, [refDate, weekStartsOn]);
  const monthTitle = new Intl.DateTimeFormat(locale, {
    year: "numeric",
    month: "long"
  }).format(refDate);
  const today = /* @__PURE__ */ new Date();
  const weekdayNames = React.useMemo(() => {
    return days.slice(0, 7).map(
      (d) => new Intl.DateTimeFormat(locale, { weekday: "short" }).format(d)
    );
  }, [days, locale]);
  const handleToday = () => setRefDate(/* @__PURE__ */ new Date());
  const handlePrev = () => setRefDate(subMonths(refDate, 1));
  const handleNext = () => setRefDate(addMonths(refDate, 1));
  return /* @__PURE__ */ jsxs(
    "div",
    {
      ref,
      className: cn(
        "flex flex-col w-full h-full bg-surface rounded-md border border-divider overflow-hidden",
        className
      ),
      "data-view": currentView,
      "data-size": size,
      ...props,
      children: [
        /* @__PURE__ */ jsxs(
          "div",
          {
            className: cn(
              "flex items-center gap-2 shrink-0 border-b border-divider",
              "px-[var(--layout-space-loose)] py-[var(--layout-space-tight)]"
            ),
            children: [
              /* @__PURE__ */ jsxs("nav", { className: "flex items-center gap-2", "aria-label": navAriaLabel, children: [
                /* @__PURE__ */ jsx(
                  Button,
                  {
                    variant: "text",
                    size: "sm",
                    iconOnly: true,
                    startIcon: ChevronLeft,
                    "aria-label": prevAriaLabel,
                    onClick: handlePrev
                  }
                ),
                /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleToday, children: todayLabel }),
                /* @__PURE__ */ jsx(
                  Button,
                  {
                    variant: "text",
                    size: "sm",
                    iconOnly: true,
                    startIcon: ChevronRight,
                    "aria-label": nextAriaLabel,
                    onClick: handleNext
                  }
                )
              ] }),
              /* @__PURE__ */ jsx("h2", { className: "text-body-lg font-medium text-foreground flex-1 min-w-0 truncate ml-2", children: monthTitle }),
              /* @__PURE__ */ jsxs(
                SegmentedControl,
                {
                  size: "sm",
                  value: currentView,
                  onValueChange: (v) => setView(v),
                  "aria-label": viewToggleAriaLabel,
                  children: [
                    /* @__PURE__ */ jsx(SegmentedControlItem, { value: "day", disabled: true, children: "日" }),
                    /* @__PURE__ */ jsx(SegmentedControlItem, { value: "week", disabled: true, children: "週" }),
                    /* @__PURE__ */ jsx(SegmentedControlItem, { value: "month", children: "月" })
                  ]
                }
              ),
              onCreateEvent && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", startIcon: Plus, onClick: onCreateEvent, children: "新事件" })
            ]
          }
        ),
        /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 border-b border-divider bg-muted", children: weekdayNames.map((name, i) => /* @__PURE__ */ jsx(
          "div",
          {
            className: "px-2 py-1.5 text-caption text-fg-muted font-normal text-center",
            children: name
          },
          i
        )) }),
        /* @__PURE__ */ jsx(
          "div",
          {
            className: "grid grid-cols-7 flex-1 min-h-0",
            role: "grid",
            "aria-label": `月行事曆,${monthTitle}`,
            children: Array.from({ length: Math.ceil(days.length / 7) }, (_, rowIdx) => /* @__PURE__ */ jsx("div", { role: "row", style: { display: "contents" }, children: days.slice(rowIdx * 7, rowIdx * 7 + 7).map((date) => {
              const inMonth = isSameMonth(date, refDate);
              const isToday = isSameDay(date, today);
              const dayEvents = eventsOnDate(events, date).slice().sort((a, b) => Number(b.allDay ?? false) - Number(a.allDay ?? false));
              const visibleEvents = dayEvents.slice(0, MAX_TILES_PER_CELL);
              const overflowCount = dayEvents.length - visibleEvents.length;
              return (
                // 2026-06-11 a11y(user 拍板 2c 修 code):cell 從 <button role="gridcell"> 改非互動容器 —
                // W3C button 語義禁止互動後代,cell 內含 role="button" 事件 tile = nested-interactive 違規。
                // 對齊 Google Calendar:gridcell = 容器,日期數字按鈕 = 日期級 keyboard 入口,tile 各自為 button。
                // div onClick 保留滑鼠「點 cell 空白處等同點日期」便利(keyboard 走日期數字按鈕,功能等價)。
                /* @__PURE__ */ jsxs(
                  "div",
                  {
                    role: "gridcell",
                    onClick: () => onDateClick == null ? void 0 : onDateClick(date),
                    className: cn(
                      "flex flex-col gap-1 min-h-28 p-1.5 text-left",
                      "border-r border-b border-divider last:border-r-0",
                      "[&:nth-child(7n)]:border-r-0",
                      "hover:bg-neutral-hover transition-colors",
                      !inMonth && "bg-muted"
                    ),
                    children: [
                      /* @__PURE__ */ jsx("div", { className: "flex items-start justify-end", children: /* @__PURE__ */ jsx(
                        "button",
                        {
                          type: "button",
                          "aria-label": `${format(date, "yyyy-MM-dd")},${dayEvents.length} 個事件`,
                          onClick: (e) => {
                            e.stopPropagation();
                            onDateClick == null ? void 0 : onDateClick(date);
                          },
                          className: cn(
                            "inline-flex items-center justify-center min-w-6 h-6 rounded-full text-body font-medium",
                            "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
                            isToday && "px-2 bg-info text-on-emphasis",
                            !isToday && !inMonth && "text-fg-disabled"
                          ),
                          children: format(date, "d")
                        }
                      ) }),
                      /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 min-h-0", children: [
                        visibleEvents.map((event) => {
                          const ec = event.color ?? "blue";
                          const colorClass = event.allDay ? cn(EVENT_COLOR_CLASSES[ec], EVENT_ALLDAY_ACCENT[ec], "font-medium") : EVENT_COLOR_CLASSES[ec];
                          if (renderEventTile) {
                            return /* @__PURE__ */ jsx(
                              "div",
                              {
                                onClick: (e) => {
                                  e.stopPropagation();
                                  onEventClick == null ? void 0 : onEventClick(event);
                                },
                                children: renderEventTile(event)
                              },
                              event.id
                            );
                          }
                          return /* @__PURE__ */ jsx(
                            "div",
                            {
                              role: "button",
                              tabIndex: 0,
                              onClick: (e) => {
                                e.stopPropagation();
                                onEventClick == null ? void 0 : onEventClick(event);
                              },
                              onKeyDown: (e) => {
                                if (e.key === "Enter" || e.key === " ") {
                                  e.preventDefault();
                                  onEventClick == null ? void 0 : onEventClick(event);
                                }
                              },
                              "aria-label": `事件:${event.title}`,
                              className: cn(
                                "rounded-md px-1.5 py-0.5 text-caption truncate cursor-pointer transition-colors",
                                // 2026-05-31 #22:事件 tile 是 focusable(tabIndex=0 role=button)但原無 focus ring
                                // → WCAG 2.4.7 不合規。補 focus-visible ring 對齊日期格按鈕。
                                "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
                                colorClass
                              ),
                              children: event.title
                            },
                            event.id
                          );
                        }),
                        overflowCount > 0 && /* @__PURE__ */ jsxs("div", { className: "text-caption text-fg-muted px-1.5", children: [
                          "+",
                          overflowCount,
                          " more"
                        ] })
                      ] })
                    ]
                  },
                  date.toISOString()
                )
              );
            }) }, rowIdx))
          }
        )
      ]
    }
  );
});
Calendar.displayName = "Calendar";
const calendarMeta = {
  component: "Calendar",
  family: null,
  // non-family composite / overlay / layout
  variants: {},
  sizes: {},
  states: ["default", "hover", "active", "focus-visible", "disabled"],
  tokens: {
    bg: ["bg-muted", "bg-neutral-hover", "bg-info", "bg-surface"],
    fg: ["text-fg-disabled", "text-fg-muted", "text-foreground"],
    ring: ["ring-ring"]
  }
};
export {
  Calendar,
  calendarMeta
};
//# sourceMappingURL=calendar.js.map
