/**
 * Copyright IBM Corp. 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import "../../globals/settings.js";
import { carbonElement } from "../../globals/decorators/carbon-element.js";
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.js";
import HostListener from "../../globals/decorators/host-listener.js";
import HostListenerMixin from "../../globals/mixins/host-listener.js";
import FormMixin from "../../globals/mixins/form.js";
import flatpickr from "../../node_modules/flatpickr/dist/esm/index.js";
import { getISODateString, parseISODateString } from "./iso-date.js";
import append_to_plugin_default from "./append-to-plugin.js";
import css_class_plugin_default from "./css-class-plugin.js";
import fix_events_plugin_default from "./fix-events-plugin.js";
import date_picker_default$1 from "./date-picker.scss.js";
import focus_plugin_default from "./focus-plugin.js";
import icon_plugin_default from "./icon-plugin.js";
import month_select_plugin_default from "./month-select-plugin.js";
import range_plugin_default from "./range-plugin.js";
import shadow_dom_events_plugin_default from "./shadow-dom-events-plugin.js";
import state_handshake_plugin_default from "./state-handshake-plugin.js";
import { LitElement, html } from "lit";
import { property, query } from "lit/decorators.js";
//#region src/components/date-picker/date-picker.ts
/**
* Copyright IBM Corp. 2019, 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
flatpickr.l10ns.en.weekdays.shorthand.forEach((_day, index) => {
	const currentDay = flatpickr.l10ns.en.weekdays.shorthand;
	if (currentDay[index] === "Thu" || currentDay[index] === "Th") currentDay[index] = "Th";
	else currentDay[index] = currentDay[index].charAt(0);
});
/**
* Date picker.
*
* @element cds-date-picker
* @fires cds-date-picker-changed - The custom event fired on this element when Flatpickr updates its value.
* @fires cds-date-picker-flatpickr-error
*   The name of the custom event when Flatpickr throws an error.
*/
let CDSDatePicker = class CDSDatePicker extends HostListenerMixin(FormMixin(LitElement)) {
	constructor(..._args) {
		super(..._args);
		this._dateInteractNode = null;
		this._handleChange = ({ detail }) => {
			this._value = detail.selectedDates.map((date) => getISODateString(date)).join("/");
		};
		this._handleFlatpickrError = (error) => {
			this.dispatchEvent(new CustomEvent(this.constructor.eventFlatpickrError, {
				bubbles: true,
				cancelable: false,
				composed: true,
				detail: { error }
			}));
		};
		this.calendar = null;
		this.allowInput = true;
		this.closeOnSelect = true;
		this.disabled = false;
		this.name = "";
		this.open = false;
		this.readonly = false;
	}
	/**
	* @returns The effective date picker mode, determined by the child `<cds-date-picker-input>`.
	*/
	get _mode() {
		const { selectorInputTo } = this.constructor;
		if (this.querySelector(selectorInputTo)) return "range";
		if (this.querySelector(`cds-date-picker-input[kind="single"]`)) return "single";
		return "simple";
	}
	/**
	* @returns The Flatpickr plugins to use.
	*/
	get _datePickerPlugins() {
		const { classCalendarContainer, classMonth, classWeekdays, classDays, classWeekday, classDay, classNoBorder, selectorInputFrom, selectorInputTo, _selectorFlatpickrMonthYearContainer: selectorFlatpickrMonthYearContainer, _selectorFlatpickrYearContainer: selectorFlatpickrYearContainer, _selectorFlatpickrCurrentMonth: selectorFlatpickrCurrentMonth, _selectorFlatpickrMonth: selectorFlatpickrMonth, _selectorFlatpickrWeekdays: selectorFlatpickrWeekdays, _selectorFlatpickrDays: selectorFlatpickrDays, _selectorFlatpickrWeekday: selectorFlatpickrWeekday, _selectorFlatpickrDay: selectorFlatpickrDay, _classFlatpickrCurrentMonth: classFlatpickrCurrentMonth, _classFlatpickrToday: classFlatpickrToday } = this.constructor;
		const { _floatingMenuContainerNode: floatingMenuContainerNode, _mode: mode } = this;
		const inputFrom = this.querySelector(selectorInputFrom);
		const inputTo = this.querySelector(selectorInputTo);
		const plugins = [
			append_to_plugin_default({ appendTo: floatingMenuContainerNode }),
			css_class_plugin_default({
				classCalendarContainer,
				classMonth,
				classWeekdays,
				classDays,
				classWeekday,
				classDay,
				classNoBorder,
				selectorFlatpickrMonth,
				selectorFlatpickrWeekdays,
				selectorFlatpickrDays,
				selectorFlatpickrWeekday,
				selectorFlatpickrDay,
				classFlatpickrToday
			}),
			fix_events_plugin_default({
				inputFrom,
				inputTo
			}),
			focus_plugin_default({
				inputFrom,
				inputTo
			}),
			icon_plugin_default(),
			month_select_plugin_default({
				selectorFlatpickrMonthYearContainer,
				selectorFlatpickrYearContainer,
				selectorFlatpickrCurrentMonth,
				classFlatpickrCurrentMonth
			}),
			shadow_dom_events_plugin_default(),
			state_handshake_plugin_default(this)
		];
		if (mode === "range") plugins.push(range_plugin_default({ input: inputTo }));
		return plugins;
	}
	/**
	* @returns The options to instantiate Flatpickr with.
	*/
	get _datePickerOptions() {
		const { locale = this.constructor.defaultLocale, enabledRange, _dateInteractNode: dateInteractNode, _datePickerPlugins: plugins, _handleFlatpickrError: handleFlatpickrError } = this;
		const { input: positionElement } = dateInteractNode;
		const [minDate = void 0, maxDate = void 0] = !enabledRange ? [] : enabledRange.split("/");
		return {
			allowInput: this.allowInput,
			ariaDateFormat: this.constructor.defaultAriaDateFormat,
			closeOnSelect: this.closeOnSelect,
			dateFormat: this.dateFormat ?? this.constructor.defaultDateFormat,
			disableMobile: true,
			errorHandler: handleFlatpickrError,
			locale,
			maxDate,
			minDate,
			positionElement,
			plugins
		};
	}
	_handleFormdata(event) {
		const { formData } = event;
		const { disabled, name, value } = this;
		if (!disabled) formData.append(name, value);
	}
	/**
	* Handles `slotchange` event in the `<slot>`.
	*/
	_handleSlotChange({ target }) {
		const { _dateInteractNode: oldDateInteractNode } = this;
		const dateInteractNode = target.assignedNodes().find((node) => node.nodeType === Node.ELEMENT_NODE && node.matches(this.constructor.selectorInputFrom));
		if (oldDateInteractNode !== dateInteractNode) {
			this._dateInteractNode = dateInteractNode;
			this._instantiateDatePicker();
		}
	}
	/**
	* Sets calendar options
	* @param property property to set
	* @param calendar calendar object
	*/
	_setCalendar(property, calendar) {
		const { disabled, dateFormat, open, readonly, minDate, maxDate, value } = this;
		const { selectorInputFrom, selectorInputTo } = this.constructor;
		const inputFrom = this.querySelector(selectorInputFrom);
		const inputTo = this.querySelector(selectorInputTo);
		if (property === "dateFormat") calendar.set({ dateFormat });
		if (property === "date") {
			if (!parseISODateString(minDate)) throw new Error(`Wrong date format found in \`minDate\` property: ${minDate}`);
			if (!parseISODateString(maxDate)) throw new Error(`Wrong date format found in \`maxDate\` property: ${maxDate}`);
			if (minDate && maxDate && minDate > maxDate) throw new Error(`\`maxDate\` property, shouldn't be smaller than the \`minDate\` property. You have: minDate: ${minDate}, maxDate: ${maxDate}`);
			calendar.set({
				minDate,
				maxDate
			});
		}
		if (property === "open") if (open && !readonly) calendar.open();
		else calendar.close();
		if (property === "disabled") [inputFrom, inputTo].forEach((input) => {
			if (input) {
				input.disabled = disabled;
				input.readonly = readonly;
			}
		});
		if (property === "value") {
			const dates = value.split("/").filter(Boolean).map((item) => parseISODateString(item));
			if (dates.some((item) => isNaN(Number(item)))) throw new Error(`Wrong date format found in \`value\` property: ${value}`);
			const [startDate, endDate] = dates;
			if (startDate && endDate && startDate > endDate) throw new Error(`In \`value\` property, the end date shouldn't be smaller than the start date. You have: ${value}`);
			if (calendar) {
				calendar.setDate(dates);
				[inputFrom, inputTo].forEach((input, i) => {
					if (input) input.value = !dates[i] ? "" : calendar.formatDate(new Date(dates[i]), calendar.config.dateFormat);
				});
			}
		}
		return calendar;
	}
	/**
	* Instantiates Flatpickr.
	*
	* @returns The Flatpickr instance.
	*/
	_instantiateDatePicker() {
		this._releaseDatePicker();
		const { _dateInteractNode: dateInteractNode } = this;
		if (dateInteractNode && dateInteractNode.input && this._mode !== "simple") this.calendar = flatpickr(dateInteractNode.input, this._datePickerOptions);
		const { calendar, disabled, dateFormat, open, readonly, minDate, maxDate, value } = this;
		if (calendar) {
			if (dateFormat) this._setCalendar("dateFormat", calendar);
			if (minDate || maxDate) this._setCalendar("date", calendar);
			if (open) this._setCalendar("open", calendar);
			if (disabled || readonly) this._setCalendar("disabled", calendar);
			if (value) this._setCalendar("value", calendar);
		}
		return calendar;
	}
	/**
	* Releases Flatpickr instances.
	*/
	_releaseDatePicker() {
		if (this.calendar) {
			this.calendar.destroy();
			this.calendar = null;
		}
		return this.calendar;
	}
	/**
	* The date(s) in ISO8601 format (date portion only), for range mode, '/' is used for separate start/end dates.
	*/
	get value() {
		return this._value;
	}
	set value(value) {
		const { _value: oldValue } = this;
		this._value = value;
		this.requestUpdate("value", oldValue);
	}
	connectedCallback() {
		super.connectedCallback();
		this._instantiateDatePicker();
	}
	disconnectedCallback() {
		this._releaseDatePicker();
		super.disconnectedCallback();
	}
	updated(changedProperties) {
		const { calendar } = this;
		if (calendar) {
			if (changedProperties.has("dateFormat")) this._setCalendar("dateFormat", calendar);
			if (changedProperties.has("minDate") || changedProperties.has("maxDate")) this._setCalendar("date", calendar);
			if (changedProperties.has("open")) this._setCalendar("open", calendar);
			if (changedProperties.has("disabled") || changedProperties.has("readonly")) this._setCalendar("disabled", calendar);
			if (changedProperties.has("value")) this._setCalendar("value", calendar);
		}
	}
	render() {
		const { _handleSlotChange: handleSlotChange } = this;
		return html`
      <a
        class="${"cds"}--visually-hidden"
        href="javascript:void 0"
        role="navigation"
        tabindex="-1"></a>
      <slot @slotchange="${handleSlotChange}"></slot>
      <div id="floating-menu-container"></div>
      <a
        class="${"cds"}--visually-hidden"
        href="javascript:void 0"
        role="navigation"
        tabindex="-1"></a>
    `;
	}
	static {
		this._selectorFlatpickrMonthYearContainer = ".flatpickr-current-month";
	}
	static {
		this._selectorFlatpickrYearContainer = ".numInputWrapper";
	}
	static {
		this._selectorFlatpickrCurrentMonth = ".cur-month";
	}
	static {
		this._selectorFlatpickrMonth = ".flatpickr-month";
	}
	static {
		this._selectorFlatpickrWeekdays = ".flatpickr-weekdays";
	}
	static {
		this._selectorFlatpickrDays = ".flatpickr-days";
	}
	static {
		this._selectorFlatpickrWeekday = ".flatpickr-weekday";
	}
	static {
		this._selectorFlatpickrDay = ".flatpickr-day";
	}
	static {
		this._classFlatpickrCurrentMonth = "cur-month";
	}
	static {
		this._classFlatpickrToday = "today";
	}
	/**
	* The CSS class for the calendar dropdown.
	*/
	static get classCalendarContainer() {
		return `cds--date-picker__calendar`;
	}
	/**
	* The CSS class for the month navigator.
	*/
	static get classMonth() {
		return `cds--date-picker__month`;
	}
	/**
	* The CSS class for the container of the weekdays.
	*/
	static get classWeekdays() {
		return `cds--date-picker__weekdays`;
	}
	/**
	* The CSS class for the container of the days.
	*/
	static get classDays() {
		return `cds--date-picker__days`;
	}
	/**
	* The CSS class applied to each weekdays.
	*/
	static get classWeekday() {
		return `cds--date-picker__weekday`;
	}
	/**
	* The CSS class applied to each days.
	*/
	static get classDay() {
		return `cds--date-picker__day`;
	}
	static {
		this.classNoBorder = "no-border";
	}
	static {
		this.defaultAriaDateFormat = "l, F j, Y";
	}
	static {
		this.defaultDateFormat = "m/d/Y";
	}
	static {
		this.defaultLocale = flatpickr.l10ns.default;
	}
	/**
	* A selector that will return the `<input>` to enter starting date.
	*/
	static get selectorInputFrom() {
		return `cds-date-picker-input,cds-date-picker-input[kind="from"]`;
	}
	/**
	* A selector that will return the `<input>` to enter end date.
	*/
	static get selectorInputTo() {
		return `cds-date-picker-input[kind="to"]`;
	}
	/**
	* The name of the custom event when Flatpickr throws an error.
	*/
	static get eventFlatpickrError() {
		return `cds-date-picker-flatpickr-error`;
	}
	/**
	* The name of the custom event fired on this element when Flatpickr updates its value.
	*/
	static get eventChange() {
		return `cds-date-picker-changed`;
	}
	static {
		this.styles = date_picker_default$1;
	}
};
__decorate([query("#floating-menu-container")], CDSDatePicker.prototype, "_floatingMenuContainerNode", void 0);
__decorate([HostListener("eventChange")], CDSDatePicker.prototype, "_handleChange", void 0);
__decorate([property({
	type: Boolean,
	reflect: true,
	attribute: "allow-input"
})], CDSDatePicker.prototype, "allowInput", void 0);
__decorate([property({
	type: Boolean,
	reflect: true,
	attribute: "close-on-select"
})], CDSDatePicker.prototype, "closeOnSelect", void 0);
__decorate([property({ attribute: "date-format" })], CDSDatePicker.prototype, "dateFormat", void 0);
__decorate([property({
	type: Boolean,
	reflect: true
})], CDSDatePicker.prototype, "disabled", void 0);
__decorate([property({ attribute: "enabled-range" })], CDSDatePicker.prototype, "enabledRange", void 0);
__decorate([property({ attribute: false })], CDSDatePicker.prototype, "locale", void 0);
__decorate([property({ attribute: "max-date" })], CDSDatePicker.prototype, "maxDate", void 0);
__decorate([property({ attribute: "min-date" })], CDSDatePicker.prototype, "minDate", void 0);
__decorate([property()], CDSDatePicker.prototype, "name", void 0);
__decorate([property({
	type: Boolean,
	reflect: true
})], CDSDatePicker.prototype, "open", void 0);
__decorate([property({
	type: Boolean,
	reflect: true
})], CDSDatePicker.prototype, "readonly", void 0);
__decorate([property()], CDSDatePicker.prototype, "value", null);
CDSDatePicker = __decorate([carbonElement(`cds-date-picker`)], CDSDatePicker);
var date_picker_default = CDSDatePicker;
//#endregion
export { date_picker_default as default };

//# sourceMappingURL=date-picker.js.map