// packages/components/src/date-time/date/index.tsx
import { isSameDay, subMonths, addMonths, isEqual, addDays, subDays, subWeeks, addWeeks, isSameMonth } from "date-fns";
import { __, _n, sprintf, isRTL } from "@wordpress/i18n";
import { arrowLeft, arrowRight } from "@wordpress/icons";
import { dateI18n, date as formatDate, getSettings } from "@wordpress/date";
import { useState, useRef, useEffect } from "@wordpress/element";
import { useLilius } from "./use-lilius/index.js";
import { Wrapper, Navigator, ViewPreviousMonthButton, ViewNextMonthButton, NavigatorHeading, Calendar, DayOfWeek, DayButton } from "./styles.js";
import { inputToDate, setInConfiguredTimezone, startOfDayInConfiguredTimezone } from "../utils.js";
import { TIMEZONELESS_FORMAT } from "../constants.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
function DatePicker({
  currentDate,
  onChange,
  events = [],
  isInvalidDate,
  onMonthPreviewed,
  startOfWeek: weekStartsOn = 0
}) {
  const date = inputToDate(currentDate !== null && currentDate !== void 0 ? currentDate : /* @__PURE__ */ new Date());
  const {
    calendar,
    viewing,
    setSelected,
    setViewing,
    isSelected,
    viewPreviousMonth,
    viewNextMonth
  } = useLilius({
    selected: [startOfDayInConfiguredTimezone(date)],
    viewing: startOfDayInConfiguredTimezone(date),
    weekStartsOn
  });
  const [focusable, setFocusable] = useState(startOfDayInConfiguredTimezone(date));
  const [isFocusWithinCalendar, setIsFocusWithinCalendar] = useState(false);
  const [prevCurrentDate, setPrevCurrentDate] = useState(currentDate);
  if (currentDate !== prevCurrentDate) {
    setPrevCurrentDate(currentDate);
    setSelected([startOfDayInConfiguredTimezone(date)]);
    setViewing(startOfDayInConfiguredTimezone(date));
    setFocusable(startOfDayInConfiguredTimezone(date));
  }
  return /* @__PURE__ */ _jsxs(Wrapper, {
    className: "components-datetime__date",
    role: "application",
    "aria-label": __("Calendar"),
    children: [/* @__PURE__ */ _jsxs(Navigator, {
      children: [/* @__PURE__ */ _jsx(ViewPreviousMonthButton, {
        icon: isRTL() ? arrowRight : arrowLeft,
        variant: "tertiary",
        "aria-label": __("View previous month"),
        onClick: () => {
          viewPreviousMonth();
          setFocusable(subMonths(focusable, 1));
          const prevMonth = subMonths(viewing, 1);
          onMonthPreviewed?.(dateI18n(TIMEZONELESS_FORMAT, prevMonth, -prevMonth.getTimezoneOffset()));
        },
        size: "compact"
      }), /* @__PURE__ */ _jsxs(NavigatorHeading, {
        level: 3,
        children: [/* @__PURE__ */ _jsx("strong", {
          children: dateI18n("F", viewing, -viewing.getTimezoneOffset())
        }), " ", dateI18n("Y", viewing, -viewing.getTimezoneOffset())]
      }), /* @__PURE__ */ _jsx(ViewNextMonthButton, {
        icon: isRTL() ? arrowLeft : arrowRight,
        variant: "tertiary",
        "aria-label": __("View next month"),
        onClick: () => {
          viewNextMonth();
          setFocusable(addMonths(focusable, 1));
          const nextMonth = addMonths(viewing, 1);
          onMonthPreviewed?.(dateI18n(TIMEZONELESS_FORMAT, nextMonth, -nextMonth.getTimezoneOffset()));
        },
        size: "compact"
      })]
    }), /* @__PURE__ */ _jsxs(Calendar, {
      onFocus: () => setIsFocusWithinCalendar(true),
      onBlur: () => setIsFocusWithinCalendar(false),
      children: [calendar[0][0].map((day) => /* @__PURE__ */ _jsx(DayOfWeek, {
        children: dateI18n("D", day, -day.getTimezoneOffset())
      }, day.toString())), calendar[0].map((week) => week.map((day, index) => {
        if (!isSameMonth(day, viewing)) {
          return null;
        }
        return /* @__PURE__ */ _jsx(Day, {
          day,
          column: index + 1,
          isSelected: isSelected(day),
          isFocusable: isEqual(day, focusable),
          isFocusAllowed: isFocusWithinCalendar,
          isToday: isSameDay(day, startOfDayInConfiguredTimezone(/* @__PURE__ */ new Date())),
          isInvalid: isInvalidDate ? isInvalidDate(day) : false,
          numEvents: events.filter((event) => isSameDay(event.date, day)).length,
          onClick: () => {
            setSelected([day]);
            setFocusable(day);
            const newDate = setInConfiguredTimezone(date, {
              year: day.getFullYear(),
              month: day.getMonth(),
              date: day.getDate()
            });
            onChange?.(formatDate(TIMEZONELESS_FORMAT, newDate));
          },
          onKeyDown: (event) => {
            let nextFocusable;
            if (event.key === "ArrowLeft") {
              nextFocusable = addDays(day, isRTL() ? 1 : -1);
            }
            if (event.key === "ArrowRight") {
              nextFocusable = addDays(day, isRTL() ? -1 : 1);
            }
            if (event.key === "ArrowUp") {
              nextFocusable = subWeeks(day, 1);
            }
            if (event.key === "ArrowDown") {
              nextFocusable = addWeeks(day, 1);
            }
            if (event.key === "PageUp") {
              nextFocusable = subMonths(day, 1);
            }
            if (event.key === "PageDown") {
              nextFocusable = addMonths(day, 1);
            }
            if (event.key === "Home") {
              const dayOfWeek = day.getDay();
              const daysToSubtract = (dayOfWeek - weekStartsOn + 7) % 7;
              nextFocusable = subDays(day, daysToSubtract);
            }
            if (event.key === "End") {
              const dayOfWeek = day.getDay();
              const daysToAdd = (weekStartsOn + 6 - dayOfWeek) % 7;
              nextFocusable = addDays(day, daysToAdd);
            }
            if (nextFocusable) {
              event.preventDefault();
              setFocusable(nextFocusable);
              if (!isSameMonth(nextFocusable, viewing)) {
                setViewing(nextFocusable);
                onMonthPreviewed?.(dateI18n(TIMEZONELESS_FORMAT, nextFocusable, -nextFocusable.getTimezoneOffset()));
              }
            }
          }
        }, day.toString());
      }))]
    })]
  });
}
function Day({
  day,
  column,
  isSelected,
  isFocusable,
  isFocusAllowed,
  isToday,
  isInvalid,
  numEvents,
  onClick,
  onKeyDown
}) {
  const ref = useRef();
  useEffect(() => {
    if (ref.current && isFocusable && isFocusAllowed) {
      ref.current.focus();
    }
  }, [isFocusable]);
  return /* @__PURE__ */ _jsx(DayButton, {
    __next40pxDefaultSize: true,
    ref,
    className: "components-datetime__date__day",
    disabled: isInvalid,
    tabIndex: isFocusable ? 0 : -1,
    "aria-label": getDayLabel(day, isSelected, isToday, numEvents),
    column,
    isSelected,
    isToday,
    hasEvents: numEvents > 0,
    onClick,
    onKeyDown,
    children: dateI18n("j", day, -day.getTimezoneOffset())
  });
}
function getDayLabel(date, isSelected, isToday, numEvents) {
  const {
    formats
  } = getSettings();
  const localizedDate = dateI18n(formats.date, date, -date.getTimezoneOffset());
  const parts = [localizedDate];
  if (isSelected) {
    parts.push(__("Selected"));
  }
  if (isToday) {
    parts.push(__("Today"));
  }
  if (numEvents > 0) {
    parts.push(sprintf(
      // translators: %d: Number of events on the calendar date.
      _n("There is %d event", "There are %d events", numEvents),
      numEvents
    ));
  }
  return parts.join(". ");
}
var date_default = DatePicker;
export {
  DatePicker,
  date_default as default
};
//# sourceMappingURL=index.js.map
