"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const dateFns = require("date-fns");
const locale = require("date-fns/locale");
const React = require("react");
const ReactDatePicker = require("react-datepicker");
const fa = require("react-icons/fa");
const im = require("react-icons/im");
const useBindingState = require("../../form/hooks/useBindingState.cjs");
const classNames = require("../../utils/classNames.cjs");
require("../../utils/globals.cjs");
const objects = require("../../utils/objects.cjs");
const typescript = require("../../utils/typescript.cjs");
require("zod");
const useDidUpdateEffect = require("../../hooks/useDidUpdateEffect.cjs");
const radixDialog = require("../../workarounds/radixDialog.cjs");
const button_component = require("../button/button.component.cjs");
const config_context = require("../config/config.context.cjs");
const input_component = require("../input/input.component.cjs");
const label_component = require("../label/label.component.cjs");
const select_component = require("../select/select.component.cjs");
const validationErrors_component = require("../validationErrors/validationErrors.component.cjs");
const dateTimeInput_utils = require("./dateTimeInput.utils.cjs");
require("react-datepicker/dist/react-datepicker.css");
require("./dateTimeInput.theme.css.cjs");
function _interopNamespaceDefault(e) {
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
  if (e) {
    for (const k in e) {
      if (k !== "default") {
        const d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: () => e[k]
        });
      }
    }
  }
  n.default = e;
  return Object.freeze(n);
}
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
const defaultDateFormat = "dd/MM/yyyy";
const defaultTimeFormat = "HH:mm";
const defaultDateAndTimeFormat = `${defaultDateFormat} ${defaultTimeFormat}`;
const defaultLocale = locale.enGB;
const DropdownHeader = ({ changeMonth, changeYear, date, min, max, locale: locale2 = defaultLocale }) => {
  const monthOptions = React__namespace.useMemo(() => {
    return dateTimeInput_utils.getMonths(date.getFullYear(), locale2, min, max).map(({ index, name, disabled }) => ({
      id: index,
      content: name,
      disabled
    }));
  }, [date, locale2, min, max]);
  const yearOptions = React__namespace.useMemo(() => {
    return dateTimeInput_utils.getYears(min, max).map((y) => ({ id: y, content: y.toString() }));
  }, [min, max]);
  return jsxRuntime.jsxs("div", { className: "arm-date-time-input-header dropdown", children: [jsxRuntime.jsx(select_component.Select, { className: "arm-date-time-dropdown-select", options: monthOptions, onSelectOption: changeMonth, currentValue: date.getMonth(), clearable: false, displaySize: "small" }), jsxRuntime.jsx(select_component.Select, { className: "arm-date-time-dropdown-select", options: yearOptions, onSelectOption: changeYear, currentValue: date.getFullYear(), clearable: false, displaySize: "small" })] });
};
const LeftAlignHeader = (props) => {
  return jsxRuntime.jsxs("div", { className: "arm-date-time-input-header left-align", children: [jsxRuntime.jsx("span", { className: "arm-left-align-date", children: dateTimeInput_utils.formatDate(props.monthDate, "MMMM yyyy") }), jsxRuntime.jsxs("div", { className: "arm-left-align-date-navigation", children: [jsxRuntime.jsx(button_component.Button, { type: "button", className: "arm-date-time-input-header-button left-align-button", displayStyle: "blank", onClick: props.decreaseMonth, disabled: props.prevMonthButtonDisabled, children: jsxRuntime.jsx(fa.FaChevronLeft, { className: "arm-date-time-input-header-icon" }) }), jsxRuntime.jsx(button_component.Button, { type: "button", className: "arm-date-time-input-header-button left-align-button", displayStyle: "blank", onClick: props.increaseMonth, disabled: props.nextMonthButtonDisabled, children: jsxRuntime.jsx(fa.FaChevronRight, { className: "arm-date-time-input-header-icon" }) })] })] });
};
const CenteredHeader = (props) => {
  return jsxRuntime.jsxs("div", { className: "arm-date-time-input-header centered", children: [jsxRuntime.jsx(button_component.Button, { type: "button", className: "arm-date-time-input-header-button", displayStyle: "blank", onClick: props.decreaseMonth, disabled: props.prevMonthButtonDisabled, children: jsxRuntime.jsx(fa.FaChevronLeft, { className: "arm-date-time-input-header-icon" }) }), jsxRuntime.jsx("span", { children: dateTimeInput_utils.formatDate(props.monthDate, "MMMM yyyy") }), jsxRuntime.jsx(button_component.Button, { type: "button", className: "arm-date-time-input-header-button", displayStyle: "blank", onClick: props.increaseMonth, disabled: props.nextMonthButtonDisabled, children: jsxRuntime.jsx(fa.FaChevronRight, { className: "arm-date-time-input-header-icon" }) })] });
};
const SingleDateTimeInput = React__namespace.forwardRef(({ config, selectsRange, className, bind, value, onChange, validationErrorMessages, monthSelectVariant, mode, native, format, locale: locale2, statusClassName, autoValidate, showCalendarOnLeftOverlayClick, onBlur, ...inputProps }, ref) => {
  const datePickerRef = React__namespace.useRef(null);
  const [date, setDate, bindDateConfig] = useBindingState.useBindingState(bind, {
    validationErrorMessages,
    value,
    onChange,
    autoValidate
  });
  const globals = config_context.useArmstrongConfig({
    autoValidate: bindDateConfig.autoValidate
  });
  const renderCustomHeader = React__namespace.useCallback((customHeaderProps) => {
    return jsxRuntime.jsxs("div", { className: "customer-header-container", children: [monthSelectVariant === "dropdown" && jsxRuntime.jsx(DropdownHeader, { ...customHeaderProps, min: (config == null ? void 0 : config.minDate) ?? void 0, max: (config == null ? void 0 : config.maxDate) ?? void 0 }), monthSelectVariant === "left-align" && jsxRuntime.jsx(LeftAlignHeader, { ...customHeaderProps }), (!monthSelectVariant || monthSelectVariant === "centered") && jsxRuntime.jsx(CenteredHeader, { ...customHeaderProps })] });
  }, [monthSelectVariant, config]);
  const compiledFormat = React__namespace.useMemo(() => {
    if (format) {
      return format;
    }
    switch (mode) {
      case "date":
        return defaultDateFormat;
      case "time":
        return defaultTimeFormat;
      default:
        typescript.assertNever(mode);
        return "";
    }
  }, [mode, format]);
  const compiledConfig = React__namespace.useMemo(() => {
    return {
      // initial two props can be overridden with config
      monthsShown: 1,
      dateFormat: compiledFormat,
      ...config,
      renderCustomHeader,
      renderDayContents: (day) => jsxRuntime.jsx("div", { className: "arm-date-time-input-day-contents", children: day }),
      showTimeSelect: mode === "time",
      showTimeSelectOnly: mode === "time"
    };
  }, [mode, config, renderCustomHeader, compiledFormat]);
  const dateVal = React__namespace.useMemo(() => date ? dateFns.parse(date, compiledFormat, /* @__PURE__ */ new Date(), { locale: locale2 }) : void 0, [date, compiledFormat, locale2]);
  useDidUpdateEffect.useDidUpdateEffect(() => {
    if (globals.autoValidate) {
      bindDateConfig.validate();
    }
    bindDateConfig.setTouched(true);
  }, [dateVal]);
  const leftOverlay = React__namespace.useMemo(() => {
    if (inputProps.leftOverlay === false)
      return void 0;
    if (inputProps.leftOverlay)
      return inputProps.leftOverlay;
    if (mode === "time")
      return jsxRuntime.jsx(im.ImClock, {});
    return jsxRuntime.jsx(fa.FaRegCalendar, {});
  }, [inputProps.leftOverlay, mode]);
  const onBlurEvent = React__namespace.useCallback((event) => {
    radixDialog.onBlurWorkaround(event);
    return onBlur == null ? void 0 : onBlur(event);
  }, [onBlur]);
  return jsxRuntime.jsx(ReactDatePicker, { ...objects.stripNullOrUndefined(compiledConfig), ref: datePickerRef, className, locale: locale2, dateFormat: compiledFormat, disabled: inputProps.disabled, required: inputProps.required, onBlur: onBlurEvent, customInput: jsxRuntime.jsx(input_component.Input, { ref, ...inputProps, leftOverlay: showCalendarOnLeftOverlayClick && leftOverlay ? jsxRuntime.jsx("button", { type: "button", className: "arm-date-time-overlay-button", disabled: inputProps.disabled, onClick: () => {
    var _a;
    return (_a = datePickerRef.current) == null ? void 0 : _a.setOpen(true);
  }, children: leftOverlay }) : leftOverlay, className: classNames.concat(inputProps.inputClassName, "arm-date-time-input"), validationErrorMessages: bindDateConfig.validationErrorMessages }), selectsRange: false, selected: dateVal, onChange: (newValue) => setDate == null ? void 0 : setDate(dateTimeInput_utils.formatDate(newValue, compiledFormat)) });
});
SingleDateTimeInput.displayName = "SingleDateTimeInput";
SingleDateTimeInput.defaultProps = {
  locale: defaultLocale,
  showCalendarOnLeftOverlayClick: true
};
const RangeDateTimeInput = React__namespace.forwardRef(({ config, selectsRange, startBind, endBind, startValue, endValue, className, onChange, validationErrorMessages, native, format, locale: locale2, autoValidate, showCalendarOnLeftOverlayClick, ...inputProps }, ref) => {
  const datePickerRef = React__namespace.useRef(null);
  const [startDate, setStartDate, bindStartDateConfig] = useBindingState.useBindingState(startBind, {
    validationErrorMessages,
    value: startValue,
    autoValidate
  });
  const [endDate, setEndDate, bindEndDateConfig] = useBindingState.useBindingState(endBind, {
    // only pass in validationErrorMessages once for date range as errors will be combined!
    validationErrorMessages: [],
    value: endValue,
    autoValidate
  });
  const globals = config_context.useArmstrongConfig({
    autoValidate: bindEndDateConfig.autoValidate ?? bindStartDateConfig.autoValidate
  });
  const compiledConfig = React__namespace.useMemo(() => {
    return {
      // initial values can be overridden with config
      monthsShown: 2,
      ...config,
      renderDayContents: (day) => jsxRuntime.jsx("div", { className: "arm-date-time-input-day-contents", children: day })
    };
  }, [config]);
  const startDateVal = startDate ? dateFns.parse(startDate, format, /* @__PURE__ */ new Date(), { locale: locale2 }) : void 0;
  const endDateVal = endDate ? dateFns.parse(endDate, format, /* @__PURE__ */ new Date(), { locale: locale2 }) : void 0;
  useDidUpdateEffect.useDidUpdateEffect(() => {
    if (globals.autoValidate) {
      bindEndDateConfig.validate();
      bindStartDateConfig.validate();
    }
    bindStartDateConfig.setTouched(true);
    bindEndDateConfig.setTouched(true);
  }, [endDate]);
  useDidUpdateEffect.useDidUpdateEffect(() => {
    if (globals.autoValidate && bindStartDateConfig.isTouched && bindEndDateConfig.isTouched) {
      bindEndDateConfig.validate();
      bindStartDateConfig.validate();
    }
  }, [startDate]);
  return jsxRuntime.jsx(ReactDatePicker, { ...objects.stripNullOrUndefined(compiledConfig), ref: datePickerRef, locale: locale2, className: classNames.concat("arm-date-time-input", className), dateFormat: format, disabled: inputProps.disabled, customInput: jsxRuntime.jsx(input_component.Input, { type: "text", ref, ...inputProps, leftOverlay: showCalendarOnLeftOverlayClick && inputProps.leftOverlay ? jsxRuntime.jsx("button", { type: "button", className: "arm-date-time-overlay-button", disabled: inputProps.disabled, onClick: () => {
    var _a;
    return (_a = datePickerRef.current) == null ? void 0 : _a.setOpen(true);
  }, children: inputProps.leftOverlay }) : inputProps.leftOverlay, validationErrorMessages: [
    ...bindStartDateConfig.validationErrorMessages,
    ...bindEndDateConfig.validationErrorMessages
  ] }), selectsRange: true, startDate: startDateVal, endDate: endDateVal, onChange: (newValue) => {
    let hasChanged = false;
    if (newValue == null ? void 0 : newValue[0]) {
      setStartDate == null ? void 0 : setStartDate(dateTimeInput_utils.formatDate(newValue == null ? void 0 : newValue[0], format));
      hasChanged = true;
    }
    if (newValue == null ? void 0 : newValue[1]) {
      setEndDate == null ? void 0 : setEndDate(dateTimeInput_utils.formatDate(newValue == null ? void 0 : newValue[1], format));
      hasChanged = true;
    }
    if (hasChanged) {
      onChange == null ? void 0 : onChange(newValue == null ? void 0 : newValue.map((nv) => dateTimeInput_utils.formatDate(nv, format)));
    }
  } });
});
RangeDateTimeInput.displayName = "RangeDateTimeInput";
RangeDateTimeInput.defaultProps = {
  leftOverlay: jsxRuntime.jsx(fa.FaRegCalendar, {}),
  format: defaultDateFormat,
  locale: defaultLocale,
  showCalendarOnLeftOverlayClick: true
};
const NativeDateTimeInput = React__namespace.forwardRef(({ mode, selectsRange, native, ...props }, ref) => {
  return jsxRuntime.jsx(input_component.Input, { ref, type: mode === "date-time" ? "datetime-local" : mode, ...props });
});
NativeDateTimeInput.displayName = "NativeDateTimeInput";
const SingleDateAndTimeInput = React__namespace.forwardRef(({ className, bind, mode, validationErrorMessages, disableOnPending, hideIconOnStatus, displaySize, statusPosition, requiredIndicator, scrollValidationErrorsIntoView, validationMode, errorIcon, validationErrorsClassName, value, onChange, dateInputConfig, timeInputConfig, format, locale: locale2, disabled, required, dateInputProps = {}, timeInputProps = {}, timeInputDisplayFormat, dateInputDisplayFormat, timeInputRef, selectsRange, native, monthSelectVariant, error, label, labelId, labelClassName, autoValidate, ...nativeProps }, ref) => {
  const [dateTime, setDateTime, bindConfig] = useBindingState.useBindingState(bind, {
    validationErrorMessages,
    value,
    onChange,
    validationMode,
    autoValidate
  });
  const globals = config_context.useArmstrongConfig({
    validationMode: bindConfig.validationMode,
    disableControlOnPending: disableOnPending,
    hideInputErrorIconOnStatus: hideIconOnStatus,
    inputDisplaySize: displaySize,
    inputStatusPosition: statusPosition,
    requiredIndicator,
    validationErrorIcon: bindConfig.validationErrorIcon,
    scrollValidationErrorsIntoView,
    autoValidate: bindConfig.autoValidate
  });
  const incomingDateValue = React__namespace.useMemo(() => {
    if (!dateTime)
      return void 0;
    const asDate = dateFns.parse(dateTime, format, /* @__PURE__ */ new Date(), { locale: locale2 });
    return dateTimeInput_utils.formatDate(asDate, dateInputDisplayFormat);
  }, [dateTime, format, locale2, dateInputDisplayFormat]);
  const incomingTimeValue = React__namespace.useMemo(() => {
    if (!dateTime)
      return void 0;
    const asDate = dateFns.parse(dateTime, format, /* @__PURE__ */ new Date(), { locale: locale2 });
    return dateTimeInput_utils.formatDate(asDate, timeInputDisplayFormat);
  }, [dateTime, format, locale2, timeInputDisplayFormat]);
  const [dateValue, setDateValue] = React__namespace.useState(incomingDateValue);
  const [timeValue, setTimeValue] = React__namespace.useState(incomingTimeValue);
  React__namespace.useEffect(() => setDateValue(incomingDateValue), [incomingDateValue]);
  React__namespace.useEffect(() => setTimeValue(incomingTimeValue), [incomingTimeValue]);
  React__namespace.useEffect(() => {
    if (dateValue && timeValue) {
      const dateAsDate = dateFns.parse(dateValue, dateInputDisplayFormat, /* @__PURE__ */ new Date(), { locale: locale2 });
      const timeAsDate = dateFns.parse(timeValue, timeInputDisplayFormat, /* @__PURE__ */ new Date(), { locale: locale2 });
      const combinedDate = new Date(dateAsDate.getFullYear(), dateAsDate.getMonth(), dateAsDate.getDate(), timeAsDate.getHours(), timeAsDate.getMinutes(), timeAsDate.getSeconds(), timeAsDate.getMilliseconds());
      setDateTime == null ? void 0 : setDateTime(dateTimeInput_utils.formatDate(combinedDate, format));
    }
  }, [dateInputDisplayFormat, dateValue, format, locale2, timeInputDisplayFormat, timeValue]);
  useDidUpdateEffect.useDidUpdateEffect(() => {
    if (globals.autoValidate) {
      bindConfig.validate();
    }
    bindConfig.setTouched(true);
  }, [dateTime]);
  return jsxRuntime.jsxs("div", { className: classNames.concat("arm-date-and-time-input-container", className), ...nativeProps, children: [label && jsxRuntime.jsx(label_component.Label, { className: classNames.concat("arm-input-base-label arm-date-and-time-input-label", labelClassName), required, requiredIndicator: globals.requiredIndicator, htmlFor: labelId, displaySize: globals.inputDisplaySize, children: label }), jsxRuntime.jsxs("div", { className: "arm-date-and-time-inputs", children: [jsxRuntime.jsx("div", { className: "arm-date-and-time-input arm-date-input", children: jsxRuntime.jsx(SingleDateTimeInput, { mode: "date", ref, locale: locale2, format: dateInputDisplayFormat, config: dateInputConfig, value: dateValue, onChange: setDateValue, displaySize: globals.inputDisplaySize, validationMode: bindConfig.validationMode, disabled, statusPosition: globals.inputStatusPosition, disableOnPending: globals.disableControlOnPending, hideIconOnStatus: globals.hideInputErrorIconOnStatus, required, requiredIndicator: globals.requiredIndicator, monthSelectVariant, error: error || !!(validationErrorMessages == null ? void 0 : validationErrorMessages.length), ...dateInputProps }) }), jsxRuntime.jsx("div", { className: "arm-date-and-time-input arm-time-input", children: jsxRuntime.jsx(SingleDateTimeInput, { mode: "time", locale: locale2, format: timeInputDisplayFormat, config: timeInputConfig, ref: timeInputRef, value: timeValue, onChange: setTimeValue, displaySize: globals.inputDisplaySize, validationMode: bindConfig.validationMode, disabled, statusPosition: globals.inputStatusPosition, disableOnPending: globals.disableControlOnPending, hideIconOnStatus: globals.hideInputErrorIconOnStatus, required, requiredIndicator: globals.requiredIndicator, error: error || !!(validationErrorMessages == null ? void 0 : validationErrorMessages.length), ...timeInputProps }) })] }), !!(validationErrorMessages == null ? void 0 : validationErrorMessages.length) && bindConfig.shouldShowValidationErrorMessage && jsxRuntime.jsx(validationErrors_component.ValidationErrors, { className: validationErrorsClassName, validationMode: globals.validationMode, validationErrors: validationErrorMessages, scrollIntoView: globals.scrollValidationErrorsIntoView })] });
});
SingleDateAndTimeInput.displayName = "SingleDateAndTimeInput";
SingleDateAndTimeInput.defaultProps = {
  format: defaultDateAndTimeFormat,
  locale: defaultLocale,
  timeInputDisplayFormat: defaultTimeFormat,
  dateInputDisplayFormat: defaultDateFormat
};
const DateTimeInput = React__namespace.forwardRef(
  (props, ref) => {
    if (props.selectsRange) {
      return jsxRuntime.jsx(RangeDateTimeInput, { ref, ...props });
    }
    if (props.native) {
      return jsxRuntime.jsx(NativeDateTimeInput, { ref, ...props });
    }
    if (props.mode === "date-time") {
      return jsxRuntime.jsx(SingleDateAndTimeInput, { ref, ...props });
    }
    return jsxRuntime.jsx(SingleDateTimeInput, { ref, ...props });
  }
  // type assertion to ensure generic works with RefForwarded component
  // DO NOT CHANGE TYPE WITHOUT CHANGING THIS, FIND TYPE BY INSPECTING React.forwardRef
);
DateTimeInput.displayName = "DateTimeInput";
DateTimeInput.defaultProps = {
  selectsRange: false,
  mode: "date",
  native: false
};
exports.DateTimeInput = DateTimeInput;
exports.RangeDateTimeInput = RangeDateTimeInput;
exports.SingleDateAndTimeInput = SingleDateAndTimeInput;
exports.SingleDateTimeInput = SingleDateTimeInput;
//# sourceMappingURL=dateTimeInput.component.cjs.map
