import { jsx, jsxs, Fragment } from "react/jsx-runtime";
import * as React from "react";
import { ArrowRight, Calendar, X } from "lucide-react";
import { cn } from "../../lib/utils.js";
import { EMPTY_DISPLAY, nakedCellRowModeAlign, fieldWrapperStyles, bareInputStyles, fieldDisplayTextClass } from "../Field/field-wrapper.js";
import { ICON_SIZE, ItemSuffix, ItemInlineAction } from "../../patterns/element-anatomy/item-anatomy.js";
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../Popover/popover.js";
import { DateGrid } from "../DateGrid/date-grid.js";
import { Button } from "../Button/button.js";
import { SurfaceFooter } from "../../patterns/overlay-surface/overlay-surface.js";
import { useFieldContext, useResolvedFieldSize, useResolvedFieldInvalid, useResolvedFieldDisabled, useResolvedFieldMode, useResolvedFieldVariant } from "../Field/field-context.js";
import { isoToTimeParts, timePartsToString, TimeColumns } from "../TimePicker/time-columns.js";
function formatDate(value, options = {}) {
  const date = value instanceof Date ? value : new Date(value);
  if (Number.isNaN(date.getTime())) return String(value);
  if (options.formatOptions || options.locale) {
    return new Intl.DateTimeFormat(options.locale ?? "en-US", options.formatOptions ?? { year: "numeric", month: "2-digit", day: "2-digit" }).format(date);
  }
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}/${m}/${d}`;
}
function formatDateOrDateTime(iso, showTime, showSeconds, options = {}) {
  if (!iso) return "";
  const dateText = formatDate(iso, options);
  if (!showTime) return dateText;
  const time = isoToTimeParts(iso);
  if (!time) return dateText;
  return `${dateText} ${timePartsToString(time, showSeconds)}`;
}
function isoToDate(iso) {
  if (!iso) return void 0;
  const datePart = iso.slice(0, 10);
  const [y, m, d] = datePart.split("-").map(Number);
  if (!y || !m || !d) return void 0;
  const date = new Date(y, m - 1, d);
  const time = isoToTimeParts(iso);
  if (time) {
    date.setHours(time.hours, time.minutes, time.seconds);
  }
  return date;
}
function parseDateInput(input, opts) {
  const trimmed = input.trim();
  if (trimmed === "") return { iso: null, valid: true };
  const isoDateMatch = trimmed.match(/^(\d{4})[-/.](\d{1,2})[-/.](\d{1,2})(?:[T\s](\d{1,2}):(\d{1,2})(?::(\d{1,2}))?)?$/);
  if (isoDateMatch) {
    const [, y, m, d, hh, mm, ss] = isoDateMatch;
    const date = new Date(Number(y), Number(m) - 1, Number(d), Number(hh ?? 0), Number(mm ?? 0), Number(ss ?? 0));
    if (isNaN(date.getTime()) || date.getMonth() !== Number(m) - 1) return { iso: null, valid: false };
    const datePart = dateToIso(date);
    if (hh != null && opts.allowTime) {
      const h2 = String(Number(hh)).padStart(2, "0");
      const m2 = String(Number(mm)).padStart(2, "0");
      const s2 = String(Number(ss ?? 0)).padStart(2, "0");
      return { iso: `${datePart}T${h2}:${m2}:${s2}`, valid: true };
    }
    return { iso: datePart, valid: true };
  }
  const parsed = new Date(trimmed);
  if (!isNaN(parsed.getTime())) {
    const datePart = dateToIso(parsed);
    if (opts.allowTime && (trimmed.includes(":") || trimmed.includes("T"))) {
      const h2 = String(parsed.getHours()).padStart(2, "0");
      const m2 = String(parsed.getMinutes()).padStart(2, "0");
      const s2 = String(parsed.getSeconds()).padStart(2, "0");
      return { iso: `${datePart}T${h2}:${m2}:${s2}`, valid: true };
    }
    return { iso: datePart, valid: true };
  }
  return { iso: null, valid: false };
}
function dateToIso(date) {
  if (!date) return "";
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}-${m}-${d}`;
}
function combineDateAndTime(date, time) {
  const datePart = dateToIso(date);
  const hh = String(time.hours).padStart(2, "0");
  const mi = String(time.minutes).padStart(2, "0");
  const ss = String(time.seconds).padStart(2, "0");
  return `${datePart}T${hh}:${mi}:${ss}`;
}
function nowIsoDateTime() {
  const d = /* @__PURE__ */ new Date();
  return combineDateAndTime(d, {
    hours: d.getHours(),
    minutes: d.getMinutes(),
    seconds: d.getSeconds()
  });
}
function addDays(date, n) {
  const next = new Date(date);
  next.setDate(next.getDate() + n);
  return next;
}
function TimePickerSidePanel({
  value,
  onChange,
  showSeconds = false,
  minuteStep = 1,
  secondStep = 1,
  className
}) {
  const headerText = value ? timePartsToString(value, showSeconds) : showSeconds ? "--:--:--" : "--:--";
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col h-full pt-3", className), children: [
    /* @__PURE__ */ jsx("div", { className: "h-field-xs flex items-center justify-center mb-3", children: /* @__PURE__ */ jsx("span", { className: "text-body font-medium tabular-nums", children: headerText }) }),
    /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 flex", children: /* @__PURE__ */ jsx(
      TimeColumns,
      {
        value,
        onChange,
        showSeconds,
        minuteStep,
        secondStep
      }
    ) })
  ] });
}
const TIME_PANEL_WIDTH = (showSeconds) => showSeconds ? "w-60" : "w-40";
function CalendarTimeContainer({ showTime, showSeconds, calendar, timePanel }) {
  if (!showTime) return /* @__PURE__ */ jsx(Fragment, { children: calendar });
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
    /* @__PURE__ */ jsxs("div", { className: "flex flex-row", children: [
      calendar,
      /* @__PURE__ */ jsx("div", { className: cn("shrink-0 border-l border-divider", TIME_PANEL_WIDTH(showSeconds)) })
    ] }),
    /* @__PURE__ */ jsx("div", { className: cn("absolute top-0 right-0 bottom-0", TIME_PANEL_WIDTH(showSeconds)), children: timePanel })
  ] });
}
const DatePicker = React.forwardRef(
  ({
    mode,
    variant: variantProp,
    error: errorProp = false,
    size: sizeProp,
    value,
    onChange,
    placeholder,
    className,
    disabled: disabledProp,
    clearable = false,
    formatOptions,
    locale,
    showTime = false,
    showSeconds = false,
    minuteStep = 1,
    secondStep = 1,
    needConfirm: needConfirmProp,
    showDisplayEndIcon = false,
    defaultOpen = false,
    onOpenChange,
    typeable = false,
    id: idProp,
    "aria-label": ariaLabelProp,
    "aria-labelledby": ariaLabelledByProp,
    "aria-describedby": ariaDescribedByProp,
    "aria-errormessage": ariaErrorMessageProp,
    ...props
  }, ref) => {
    const fieldCtx = useFieldContext();
    const size = useResolvedFieldSize(sizeProp);
    const error = useResolvedFieldInvalid(errorProp);
    const disabled = useResolvedFieldDisabled(disabledProp);
    const resolvedMode = useResolvedFieldMode({ mode, disabled });
    const variant = useResolvedFieldVariant(variantProp);
    const isEditable = resolvedMode === "edit";
    const iconSize = ICON_SIZE[size];
    const needConfirm = needConfirmProp ?? showTime;
    const [open, setOpenState] = React.useState(defaultOpen);
    const setOpen = React.useCallback((next) => {
      setOpenState(next);
      onOpenChange == null ? void 0 : onOpenChange(next);
    }, [onOpenChange]);
    const [draft, setDraft] = React.useState(value ?? null);
    const resolvedPlaceholder = placeholder ?? (showTime ? "YYYY/MM/DD HH:MM" : "YYYY/MM/DD");
    const accessibleName = ariaLabelProp ?? (ariaLabelledByProp ? void 0 : (fieldCtx == null ? void 0 : fieldCtx.id) ? void 0 : resolvedPlaceholder);
    const lastOpenRef = React.useRef(open);
    React.useEffect(() => {
      if (!lastOpenRef.current && open) setDraft(value ?? null);
      lastOpenRef.current = open;
    }, [open, value]);
    const displayValue = needConfirm ? draft : value ?? null;
    const displayDate = React.useMemo(() => isoToDate(displayValue), [displayValue]);
    const draftDate = React.useMemo(() => isoToDate(draft), [draft]);
    const draftTime = isoToTimeParts(draft) ?? { hours: 0, minutes: 0, seconds: 0 };
    const showClear = clearable && (needConfirm ? draft : value) && isEditable;
    const displayCommitted = formatDateOrDateTime(value, showTime, showSeconds, { formatOptions, locale });
    const displayLive = formatDateOrDateTime(displayValue, showTime, showSeconds, { formatOptions, locale });
    const [inputDraft, setInputDraft] = React.useState(displayLive);
    const [inputInvalid, setInputInvalid] = React.useState(false);
    const composingRef = React.useRef(false);
    const lastDisplayLiveRef = React.useRef(displayLive);
    React.useEffect(() => {
      if (lastDisplayLiveRef.current !== displayLive) {
        setInputDraft(displayLive);
        setInputInvalid(false);
        lastDisplayLiveRef.current = displayLive;
      }
    }, [displayLive]);
    const handleInputCommit = React.useCallback((raw) => {
      const { iso, valid } = parseDateInput(raw, { allowTime: showTime });
      if (!valid) {
        setInputInvalid(true);
        return;
      }
      setInputInvalid(false);
      if (iso === null) {
        onChange == null ? void 0 : onChange("");
        setDraft(null);
      } else {
        onChange == null ? void 0 : onChange(iso);
        setDraft(iso);
      }
    }, [onChange, showTime]);
    if (resolvedMode === "display") {
      if (!showDisplayEndIcon) {
        if (!value) return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), "text-fg-muted", className), children: EMPTY_DISPLAY });
        return /* @__PURE__ */ jsx("span", { className: cn(fieldDisplayTextClass(size), "truncate", className), children: displayCommitted });
      }
      return /* @__PURE__ */ jsxs(
        "div",
        {
          className: cn(fieldWrapperStyles({ mode: "display", variant, size }), className),
          "data-field-mode": "display",
          children: [
            /* @__PURE__ */ jsx("span", { className: cn(bareInputStyles, "flex-1 min-w-0 truncate", !value && "text-fg-muted"), children: value ? displayCommitted : EMPTY_DISPLAY }),
            /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(Calendar, { size: iconSize, className: "text-fg-muted", "aria-hidden": true }) })
          ]
        }
      );
    }
    if (!isEditable) {
      return /* @__PURE__ */ jsxs(
        "div",
        {
          className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size }), className),
          "data-field-mode": resolvedMode,
          "aria-disabled": resolvedMode === "disabled" ? true : void 0,
          ...props,
          children: [
            /* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", resolvedMode === "disabled" && "text-fg-disabled"), children: value ? displayCommitted : /* @__PURE__ */ jsx("span", { className: "text-fg-muted", children: EMPTY_DISPLAY }) }),
            (variant === "naked" ? showDisplayEndIcon : true) && /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(Calendar, { size: iconSize, className: resolvedMode === "disabled" ? "text-fg-disabled" : "text-fg-muted", "aria-hidden": true }) })
          ]
        }
      );
    }
    const triggerText = displayValue ? displayLive : /* @__PURE__ */ jsx("span", { className: "text-fg-muted", children: resolvedPlaceholder });
    const commitDraft = (next) => {
      if (needConfirm) setDraft(next);
      else onChange == null ? void 0 : onChange(next ?? "");
    };
    const handleConfirm = () => {
      onChange == null ? void 0 : onChange(draft ?? "");
      setOpen(false);
    };
    const handleNow = () => {
      const now = showTime ? nowIsoDateTime() : dateToIso(/* @__PURE__ */ new Date());
      commitDraft(now);
    };
    return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
      /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
        "div",
        {
          ref,
          id: idProp ?? (fieldCtx == null ? void 0 : fieldCtx.id),
          role: "combobox",
          tabIndex: disabled ? -1 : 0,
          "aria-disabled": disabled || void 0,
          "aria-label": accessibleName,
          "aria-labelledby": ariaLabelledByProp ?? (fieldCtx == null ? void 0 : fieldCtx.labelId),
          "aria-invalid": error || void 0,
          "aria-required": (fieldCtx == null ? void 0 : fieldCtx.required) || void 0,
          "aria-describedby": ariaDescribedByProp ?? (fieldCtx == null ? void 0 : fieldCtx.descriptionId),
          "aria-errormessage": ariaErrorMessageProp ?? (error ? fieldCtx == null ? void 0 : fieldCtx.errorId : void 0),
          "aria-haspopup": "dialog",
          "aria-expanded": open,
          "data-field-mode": "edit",
          "data-error": error ? "" : void 0,
          onKeyDown: typeable ? void 0 : (e) => {
            if (e.key === "Enter" || e.key === " ") {
              e.preventDefault();
              setOpen(true);
            }
            if (e.key === "Escape") setOpen(false);
          },
          className: cn(
            fieldWrapperStyles({ mode: "edit", variant, size }),
            "text-left cursor-pointer",
            "focus-visible:outline-none",
            error && [
              "border-error hover:border-error-hover",
              "focus-within:border-error focus-within:hover:border-error"
            ],
            className
          ),
          ...props,
          children: [
            typeable ? (
              // Issue 10 typed input(2026-05-10):real `<input>` 接 user 鍵盤打字。
              // Click 在 input 上不 propagate 給外層 popover trigger(避免每次打字都開 popover)。
              // Calendar icon `<ItemSuffix>` 點才開 popover(Material/Ant typed-date idiom)。
              /* @__PURE__ */ jsx(
                "input",
                {
                  type: "text",
                  className: cn(bareInputStyles, "truncate", !inputDraft && "placeholder:text-fg-muted"),
                  value: inputDraft,
                  placeholder: resolvedPlaceholder,
                  "aria-invalid": inputInvalid || error || void 0,
                  onChange: (e) => {
                    setInputDraft(e.target.value);
                    setInputInvalid(false);
                  },
                  onCompositionStart: () => {
                    composingRef.current = true;
                  },
                  onCompositionEnd: () => {
                    composingRef.current = false;
                  },
                  onKeyDown: (e) => {
                    if (composingRef.current) return;
                    if (e.key === "Enter") {
                      e.preventDefault();
                      handleInputCommit(inputDraft);
                    }
                    if (e.key === "Escape") {
                      setInputDraft(displayLive);
                      setInputInvalid(false);
                      e.preventDefault();
                    }
                  },
                  onBlur: () => {
                    if (!composingRef.current) handleInputCommit(inputDraft);
                  },
                  onClick: (e) => e.stopPropagation()
                }
              )
            ) : /* @__PURE__ */ jsx("span", { className: cn(bareInputStyles, "truncate", !displayValue && "text-fg-muted"), children: triggerText }),
            showClear && /* @__PURE__ */ jsx(
              ItemInlineAction,
              {
                size: size ?? "md",
                action: {
                  icon: X,
                  label: "清除日期",
                  // i18n-allow: DS default inline-action label
                  // Clear = 立刻 commit + 同步 draft(對齊 user 體感 / Ant trigger X 慣例)
                  // 不走 needConfirm「等確定」語義 — X 在 trigger 上是 standard clear affordance,
                  // 應立刻清空。dual-state 必同步:value('') + draft(null),否則 popover 開
                  // 著時 displayValue=draft 仍顯示舊值(see line 318: displayValue = needConfirm ? draft : value)。
                  onClick: (e) => {
                    e == null ? void 0 : e.stopPropagation();
                    onChange == null ? void 0 : onChange("");
                    setDraft(null);
                  }
                }
              }
            ),
            /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(Calendar, { size: iconSize, className: "text-fg-muted", "aria-hidden": true }) })
          ]
        }
      ) }),
      /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsxs("div", { role: "dialog", className: "flex flex-col flex-1 min-h-0", children: [
        /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsx(
          CalendarTimeContainer,
          {
            showTime,
            showSeconds,
            calendar: /* @__PURE__ */ jsx(
              DateGrid,
              {
                mode: "single",
                selected: displayDate,
                onSelect: (date) => {
                  if (!date) return;
                  if (showTime) {
                    commitDraft(combineDateAndTime(date, draftTime));
                  } else {
                    commitDraft(dateToIso(date));
                    if (!needConfirm) setOpen(false);
                  }
                },
                defaultMonth: displayDate ?? void 0,
                autoFocus: true
              }
            ),
            timePanel: /* @__PURE__ */ jsx(
              TimePickerSidePanel,
              {
                value: draftTime,
                onChange: (time) => {
                  const target = draftDate ?? /* @__PURE__ */ new Date();
                  commitDraft(combineDateAndTime(target, time));
                },
                showSeconds,
                minuteStep,
                secondStep
              }
            )
          }
        ) }),
        showTime && // Footer:消費 SurfaceFooter SSOT(border-t + canonical px-loose py-tight padding,
        // 不再 hand-coded p-2 / Separator / ml-auto wrapper 三層垃圾)。
        // 「此刻」加 mr-auto 把後面 button 推右(對齊 Ant `marginInlineStart: auto` on OK)。
        /* @__PURE__ */ jsxs(SurfaceFooter, { children: [
          /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleNow, className: "mr-auto", children: "此刻" }),
          needConfirm ? /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: handleConfirm, disabled: !draft, children: "確定" }) : /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: () => setOpen(false), children: "關閉" })
        ] })
      ] }) })
    ] });
  }
);
DatePicker.displayName = "DatePicker";
const DatePickerRange = React.forwardRef(
  ({
    mode,
    variant: variantProp,
    error: errorProp = false,
    size: sizeProp,
    value,
    onChange,
    placeholder,
    className,
    disabled: disabledProp,
    clearable = false,
    formatOptions,
    locale,
    showTime = false,
    showSeconds = false,
    minuteStep = 1,
    secondStep = 1,
    needConfirm: needConfirmProp,
    id: idProp,
    "aria-describedby": ariaDescribedByProp,
    "aria-errormessage": ariaErrorMessageProp,
    ...props
  }, ref) => {
    const fieldCtx = useFieldContext();
    const size = useResolvedFieldSize(sizeProp);
    const error = useResolvedFieldInvalid(errorProp);
    const disabled = useResolvedFieldDisabled(disabledProp);
    const resolvedMode = useResolvedFieldMode({ mode, disabled });
    const variant = useResolvedFieldVariant(variantProp);
    const isEditable = resolvedMode === "edit";
    const iconSize = ICON_SIZE[size];
    const needConfirm = needConfirmProp ?? showTime;
    const resolvedPlaceholder = placeholder ?? (showTime ? ["Start date time", "End date time"] : ["Start date", "End date"]);
    const [open, setOpen] = React.useState(false);
    const [draft, setDraft] = React.useState(value ?? [null, null]);
    const [activeEnd, setActiveEnd] = React.useState("start");
    const lastOpenRef = React.useRef(open);
    React.useEffect(() => {
      if (!lastOpenRef.current && open) setDraft(value ?? [null, null]);
      lastOpenRef.current = open;
    }, [open, value]);
    const startIso = (needConfirm ? draft[0] : value == null ? void 0 : value[0]) ?? null;
    const endIso = (needConfirm ? draft[1] : value == null ? void 0 : value[1]) ?? null;
    const startDate = React.useMemo(() => isoToDate(startIso), [startIso]);
    const endDate = React.useMemo(() => isoToDate(endIso), [endIso]);
    const hasValue = !!((value == null ? void 0 : value[0]) || (value == null ? void 0 : value[1]));
    const showClear = clearable && hasValue && isEditable;
    const startText = startIso ? formatDateOrDateTime(startIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[0];
    const endText = endIso ? formatDateOrDateTime(endIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[1];
    const activeIso = activeEnd === "start" ? startIso : endIso;
    const activeDate = activeEnd === "start" ? startDate : endDate;
    const activeTime = isoToTimeParts(activeIso) ?? { hours: 0, minutes: 0, seconds: 0 };
    const rangeModifiers = React.useMemo(() => {
      const mods = {};
      if (startDate) mods.rangeStart = startDate;
      if (endDate) mods.rangeEnd = endDate;
      if (startDate && endDate) {
        const middleStart = addDays(startDate, 1);
        const middleEnd = addDays(endDate, -1);
        if (middleEnd >= middleStart) {
          mods.rangeMiddle = { from: middleStart, to: middleEnd };
        }
      }
      return mods;
    }, [startDate, endDate]);
    const commitRange = (next) => {
      if (needConfirm) setDraft(next);
      else {
        onChange == null ? void 0 : onChange(next);
        setDraft(next);
      }
    };
    const setActive = (iso) => {
      const nextDraft = activeEnd === "start" ? [iso, draft[1]] : [draft[0], iso];
      commitRange(nextDraft);
    };
    const handleConfirm = () => {
      if (showTime && activeEnd === "start" && draft[0]) {
        setActiveEnd("end");
      } else {
        onChange == null ? void 0 : onChange(draft);
        setOpen(false);
      }
    };
    const handleNow = () => {
      setActive(showTime ? nowIsoDateTime() : dateToIso(/* @__PURE__ */ new Date()));
    };
    const handleClearRange = (e) => {
      e == null ? void 0 : e.stopPropagation();
      onChange == null ? void 0 : onChange([null, null]);
      setDraft([null, null]);
    };
    const openWithActive = (which) => {
      setActiveEnd(which);
      setOpen(true);
    };
    const isOutOfRangeOrder = React.useCallback((date) => {
      if (activeEnd === "end" && startDate) {
        const startMidnight = new Date(startDate.getTime());
        startMidnight.setHours(0, 0, 0, 0);
        return date.getTime() < startMidnight.getTime();
      }
      if (activeEnd === "start" && endDate) {
        const endEndOfDay = new Date(endDate.getTime());
        endEndOfDay.setHours(23, 59, 59, 999);
        return date.getTime() > endEndOfDay.getTime();
      }
      return false;
    }, [activeEnd, startDate, endDate]);
    if (resolvedMode === "display") {
      const hasAny = !!(startIso || endIso);
      if (!hasAny) return /* @__PURE__ */ jsx("span", { className: cn("text-fg-muted", className), children: EMPTY_DISPLAY });
      return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center min-w-0", nakedCellRowModeAlign, className), children: [
        /* @__PURE__ */ jsx("span", { className: cn("truncate", !startIso && "text-fg-muted"), children: startIso ? formatDateOrDateTime(startIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[0] }),
        /* @__PURE__ */ jsx(ArrowRight, { size: iconSize, className: "shrink-0 text-fg-muted mx-2", "aria-hidden": true }),
        /* @__PURE__ */ jsx("span", { className: cn("truncate", !endIso && "text-fg-muted"), children: endIso ? formatDateOrDateTime(endIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[1] })
      ] });
    }
    if (!isEditable) {
      return /* @__PURE__ */ jsxs(
        "div",
        {
          ref,
          className: cn(fieldWrapperStyles({ mode: resolvedMode, variant, size }), className),
          "data-field-mode": resolvedMode,
          "aria-disabled": resolvedMode === "disabled" ? true : void 0,
          ...props,
          children: [
            /* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", !startIso && "text-fg-muted", resolvedMode === "disabled" && "text-fg-disabled"), children: startIso ? formatDateOrDateTime(startIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[0] }),
            /* @__PURE__ */ jsx(ArrowRight, { size: iconSize, className: cn("shrink-0 mx-2", resolvedMode === "disabled" ? "text-fg-disabled" : "text-fg-muted"), "aria-hidden": true }),
            /* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", !endIso && "text-fg-muted", resolvedMode === "disabled" && "text-fg-disabled"), children: endIso ? formatDateOrDateTime(endIso, showTime, showSeconds, { formatOptions, locale }) : resolvedPlaceholder[1] }),
            /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(Calendar, { size: iconSize, className: resolvedMode === "disabled" ? "text-fg-disabled" : "text-fg-muted", "aria-hidden": true }) })
          ]
        }
      );
    }
    return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
      /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
        "div",
        {
          ref,
          id: idProp ?? (fieldCtx == null ? void 0 : fieldCtx.id),
          "aria-invalid": error || void 0,
          "aria-required": (fieldCtx == null ? void 0 : fieldCtx.required) || void 0,
          "aria-describedby": ariaDescribedByProp ?? (fieldCtx == null ? void 0 : fieldCtx.descriptionId),
          "aria-errormessage": ariaErrorMessageProp ?? (error ? fieldCtx == null ? void 0 : fieldCtx.errorId : void 0),
          "data-field-mode": "edit",
          "data-error": error ? "" : void 0,
          "data-state": open ? "open" : "closed",
          className: cn(
            fieldWrapperStyles({ mode: "edit", size }),
            "cursor-text",
            error && [
              "border-error hover:border-error-hover",
              "focus-within:border-error focus-within:hover:border-error"
            ],
            className
          ),
          ...props,
          children: [
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                onClick: () => openWithActive("start"),
                "data-active-end": open && activeEnd === "start" ? "true" : void 0,
                "aria-label": resolvedPlaceholder[0],
                "aria-haspopup": "dialog",
                "aria-expanded": open && activeEnd === "start",
                className: cn(
                  bareInputStyles,
                  "truncate text-left cursor-pointer focus-visible:outline-none",
                  "data-[active-end=true]:underline decoration-primary underline-offset-4 decoration-2",
                  !startIso && "text-fg-muted"
                ),
                children: startText
              }
            ),
            /* @__PURE__ */ jsx(ArrowRight, { size: iconSize, className: "shrink-0 text-fg-muted mx-2", "aria-hidden": true }),
            /* @__PURE__ */ jsx(
              "button",
              {
                type: "button",
                onClick: () => openWithActive("end"),
                "data-active-end": open && activeEnd === "end" ? "true" : void 0,
                "aria-label": resolvedPlaceholder[1],
                "aria-haspopup": "dialog",
                "aria-expanded": open && activeEnd === "end",
                className: cn(
                  bareInputStyles,
                  "truncate text-left cursor-pointer focus-visible:outline-none",
                  "data-[active-end=true]:underline decoration-primary underline-offset-4 decoration-2",
                  !endIso && "text-fg-muted"
                ),
                children: endText
              }
            ),
            showClear && /* @__PURE__ */ jsx(
              ItemInlineAction,
              {
                size: size ?? "md",
                action: {
                  icon: X,
                  label: "清除日期區間",
                  // i18n-allow: DS default inline-action label
                  onClick: handleClearRange
                }
              }
            ),
            /* @__PURE__ */ jsx(ItemSuffix, { className: "pointer-events-none", children: /* @__PURE__ */ jsx(Calendar, { size: iconSize, className: "text-fg-muted", "aria-hidden": true }) })
          ]
        }
      ) }),
      /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsxs("div", { role: "dialog", "aria-label": "日期區間選擇", className: "flex flex-col flex-1 min-h-0", children: [
        /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsx(
          CalendarTimeContainer,
          {
            showTime,
            showSeconds,
            calendar: /* @__PURE__ */ jsx(
              DateGrid,
              {
                mode: "single",
                selected: activeDate,
                onSelect: (date) => {
                  if (!date) return;
                  if (isOutOfRangeOrder(date)) return;
                  const preservedTime = isoToTimeParts(activeEnd === "start" ? draft[0] : draft[1]) ?? activeTime;
                  const nextIso = showTime ? combineDateAndTime(date, preservedTime) : dateToIso(date);
                  const nextDraft = activeEnd === "start" ? [nextIso, draft[1]] : [draft[0], nextIso];
                  commitRange(nextDraft);
                  if (!showTime) {
                    if (activeEnd === "start") {
                      setActiveEnd("end");
                      if (!needConfirm && nextDraft[0] && nextDraft[1]) setOpen(false);
                    } else if (!needConfirm && nextDraft[0] && nextDraft[1]) {
                      setOpen(false);
                    }
                  }
                },
                modifiers: showTime ? {} : rangeModifiers,
                modifiersClassNames: {
                  // ── Range visual canonical(2026-05-03 v8 stadium pattern)──
                  // v5 修「白色破圖」用 pseudo 蓋全 cell 矩形,但新副作用:button 圓比矩形小,
                  // 4 corner triangle 區域 grey 凸出圓外(user 2026-05-03 抓到「凸出去」)。
                  // v8 對齊 Ant `cell-range-start::before { border-radius: 9999px 0 0 9999px }`:
                  // rangeStart pseudo 加 `rounded-l-full` → pseudo 變「左半圓 + 右矩形」stadium
                  // 左半圓 EXACTLY OVERLAY button 圓的左半弧(同 center 同 radius 14)→ 無縫
                  // 右側矩形 bridge 2px to middle → 跟 middle pseudo 連續
                  // Cell 的 top-left + bottom-left corner triangle:pseudo 不蓋 + button 不蓋 →
                  // popover white 顯露(乾淨 breathing)
                  rangeStart: cn(
                    "[&>button]:!bg-primary [&>button]:!text-on-emphasis [&>button]:hover:!ring-0",
                    "before:content-[''] before:absolute before:inset-y-0",
                    "before:left-0 before:-right-[2px]",
                    "before:bg-neutral-selected before:pointer-events-none",
                    "before:rounded-l-full"
                    // ← stadium 左半圓 matches button 圓的左半弧
                  ),
                  rangeEnd: cn(
                    "[&>button]:!bg-primary [&>button]:!text-on-emphasis [&>button]:hover:!ring-0",
                    "before:content-[''] before:absolute before:inset-y-0",
                    "before:-left-[2px] before:right-0",
                    "before:bg-neutral-selected before:pointer-events-none",
                    "before:rounded-r-full"
                    // ← 鏡像
                  ),
                  rangeMiddle: cn(
                    "before:content-[''] before:absolute before:inset-y-0 before:-inset-x-[2px]",
                    "before:bg-neutral-selected before:pointer-events-none",
                    "[&>button]:!bg-transparent [&>button]:!text-foreground"
                  )
                },
                disabled: isOutOfRangeOrder,
                numberOfMonths: showTime ? 1 : 2,
                defaultMonth: activeDate ?? startDate ?? endDate ?? void 0,
                autoFocus: true
              }
            ),
            timePanel: /* @__PURE__ */ jsx(
              TimePickerSidePanel,
              {
                value: activeTime,
                onChange: (time) => {
                  const target = activeDate ?? /* @__PURE__ */ new Date();
                  setActive(combineDateAndTime(target, time));
                },
                showSeconds,
                minuteStep,
                secondStep
              }
            )
          }
        ) }),
        (showTime || needConfirm) && // Footer 消費 SurfaceFooter SSOT(border-t + canonical px-loose py-tight)。
        // showTime Range 無「此刻」(對齊 Ant `showNow={multiple ? false : showNow}`)→ 只有 確定 走 justify-end。
        // date-only Range needConfirm:左 此刻(mr-auto)+ 右 確定。
        /* @__PURE__ */ jsxs(SurfaceFooter, { children: [
          !showTime && /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: handleNow, className: "mr-auto", children: "此刻" }),
          needConfirm ? /* @__PURE__ */ jsx(
            Button,
            {
              variant: "primary",
              size: "sm",
              onClick: handleConfirm,
              disabled: showTime ? activeEnd === "start" ? !draft[0] : !draft[0] || !draft[1] : !draft[0] || !draft[1],
              children: "確定"
            }
          ) : /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", onClick: () => setOpen(false), children: "關閉" })
        ] })
      ] }) })
    ] });
  }
);
DatePickerRange.displayName = "DatePickerRange";
const DatePickerWithRange = Object.assign(DatePicker, { Range: DatePickerRange });
const datePickerMeta = {
  component: "DatePicker",
  family: 4,
  variants: {},
  sizes: {},
  states: ["default", "hover", "active", "focus-visible", "disabled"],
  tokens: {
    bg: [],
    fg: ["text-fg-disabled", "text-fg-muted"],
    ring: []
  }
};
export {
  DatePickerWithRange as DatePicker,
  DatePickerRange,
  datePickerMeta,
  formatDate
};
//# sourceMappingURL=date-picker.js.map
