import { __esDecorate, __runInitializers } from "tslib";
import { LitElement, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { calendarStyles } from './DatePicker.styles.js';
import { generateCalendarMonth, addMonths, getMonthNames, isSameDay, formatDate, addDays, } from './DatePickerUtils.js';
import '../../../md/icons/ui-icon.js';
import '../../../md/button/ui-button.js';
import '../../../md/icon-button/ui-icon-button.js';
/**
 * A calendar grid component for date selection.
 * Supports single date selection and date range selection with full keyboard navigation.
 *
 * ## Features
 * - Single date and date range selection
 * - Keyboard navigation support (arrow keys, home, end, page up/down)
 * - Configurable date restrictions (min/max dates, disabled dates)
 * - Localization support for date formatting and month/day names
 * - Optional action buttons for pending selections
 * - Accessible design with proper ARIA attributes
 *
 * ## Events
 * - `date-select`: Fired when a single date is selected/confirmed
 * - `date-range-select`: Fired when a date range is completed (immediate mode)
 * - `date-range-confirm`: Fired when a date range is confirmed (pending mode)
 * - `date-cancel`: Fired when a pending selection is cancelled
 *
 * ## Usage
 *
 * ```html
 * <ui-date-picker-calendar></ui-date-picker-calendar>
 * ```
 *
 * ### Single date selection
 * ```html
 * <ui-date-picker-calendar
 *   .selectedDate=${new Date()}
 *   @date-select=${this.handleDateSelect}
 * ></ui-date-picker-calendar>
 * ```
 *
 * ### Date range selection
 * ```html
 * <ui-date-picker-calendar
 *   rangeSelection
 *   .rangeStart=${new Date()}
 *   .rangeEnd=${null}
 *   @date-range-select=${this.handleRangeSelect}
 * ></ui-date-picker-calendar>
 * ```
 *
 * ### With action buttons and restrictions
 * ```html
 * <ui-date-picker-calendar
 *   rangeSelection
 *   showActions
 *   .minDate=${new Date()}
 *   .maxDate=${new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)}
 *   @date-range-confirm=${this.handleRangeConfirm}
 *   @date-cancel=${this.handleCancel}
 * ></ui-date-picker-calendar>
 * ```
 */
let UiDatePickerCalendar = (() => {
    let _classDecorators = [customElement('ui-date-picker-calendar')];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = LitElement;
    let _year_decorators;
    let _year_initializers = [];
    let _year_extraInitializers = [];
    let _month_decorators;
    let _month_initializers = [];
    let _month_extraInitializers = [];
    let _selectedDate_decorators;
    let _selectedDate_initializers = [];
    let _selectedDate_extraInitializers = [];
    let _rangeStart_decorators;
    let _rangeStart_initializers = [];
    let _rangeStart_extraInitializers = [];
    let _rangeEnd_decorators;
    let _rangeEnd_initializers = [];
    let _rangeEnd_extraInitializers = [];
    let _rangeSelection_decorators;
    let _rangeSelection_initializers = [];
    let _rangeSelection_extraInitializers = [];
    let _minDate_decorators;
    let _minDate_initializers = [];
    let _minDate_extraInitializers = [];
    let _maxDate_decorators;
    let _maxDate_initializers = [];
    let _maxDate_extraInitializers = [];
    let _disabledDates_decorators;
    let _disabledDates_initializers = [];
    let _disabledDates_extraInitializers = [];
    let _locale_decorators;
    let _locale_initializers = [];
    let _locale_extraInitializers = [];
    let _showNavigation_decorators;
    let _showNavigation_initializers = [];
    let _showNavigation_extraInitializers = [];
    let _showActions_decorators;
    let _showActions_initializers = [];
    let _showActions_extraInitializers = [];
    let _okButtonText_decorators;
    let _okButtonText_initializers = [];
    let _okButtonText_extraInitializers = [];
    let _cancelButtonText_decorators;
    let _cancelButtonText_initializers = [];
    let _cancelButtonText_extraInitializers = [];
    let _calendarData_decorators;
    let _calendarData_initializers = [];
    let _calendarData_extraInitializers = [];
    let _monthNames_decorators;
    let _monthNames_initializers = [];
    let _monthNames_extraInitializers = [];
    let _showMonthDropdown_decorators;
    let _showMonthDropdown_initializers = [];
    let _showMonthDropdown_extraInitializers = [];
    let _showYearDropdown_decorators;
    let _showYearDropdown_initializers = [];
    let _showYearDropdown_extraInitializers = [];
    let _pendingDate_decorators;
    let _pendingDate_initializers = [];
    let _pendingDate_extraInitializers = [];
    let _pendingRangeStart_decorators;
    let _pendingRangeStart_initializers = [];
    let _pendingRangeStart_extraInitializers = [];
    let _pendingRangeEnd_decorators;
    let _pendingRangeEnd_initializers = [];
    let _pendingRangeEnd_extraInitializers = [];
    let _focusedDate_decorators;
    let _focusedDate_initializers = [];
    let _focusedDate_extraInitializers = [];
    var UiDatePickerCalendar = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _year_decorators = [property({ type: Number })];
            _month_decorators = [property({ type: Number })];
            _selectedDate_decorators = [property({ type: Object })];
            _rangeStart_decorators = [property({ type: Object })];
            _rangeEnd_decorators = [property({ type: Object })];
            _rangeSelection_decorators = [property({ type: Boolean })];
            _minDate_decorators = [property({ type: Object })];
            _maxDate_decorators = [property({ type: Object })];
            _disabledDates_decorators = [property({ type: Array })];
            _locale_decorators = [property({ type: String })];
            _showNavigation_decorators = [property({ type: Boolean })];
            _showActions_decorators = [property({ type: Boolean })];
            _okButtonText_decorators = [property({ type: String })];
            _cancelButtonText_decorators = [property({ type: String })];
            _calendarData_decorators = [state()];
            _monthNames_decorators = [state()];
            _showMonthDropdown_decorators = [state()];
            _showYearDropdown_decorators = [state()];
            _pendingDate_decorators = [state()];
            _pendingRangeStart_decorators = [state()];
            _pendingRangeEnd_decorators = [state()];
            _focusedDate_decorators = [state()];
            __esDecorate(this, null, _year_decorators, { kind: "accessor", name: "year", static: false, private: false, access: { has: obj => "year" in obj, get: obj => obj.year, set: (obj, value) => { obj.year = value; } }, metadata: _metadata }, _year_initializers, _year_extraInitializers);
            __esDecorate(this, null, _month_decorators, { kind: "accessor", name: "month", static: false, private: false, access: { has: obj => "month" in obj, get: obj => obj.month, set: (obj, value) => { obj.month = value; } }, metadata: _metadata }, _month_initializers, _month_extraInitializers);
            __esDecorate(this, null, _selectedDate_decorators, { kind: "accessor", name: "selectedDate", static: false, private: false, access: { has: obj => "selectedDate" in obj, get: obj => obj.selectedDate, set: (obj, value) => { obj.selectedDate = value; } }, metadata: _metadata }, _selectedDate_initializers, _selectedDate_extraInitializers);
            __esDecorate(this, null, _rangeStart_decorators, { kind: "accessor", name: "rangeStart", static: false, private: false, access: { has: obj => "rangeStart" in obj, get: obj => obj.rangeStart, set: (obj, value) => { obj.rangeStart = value; } }, metadata: _metadata }, _rangeStart_initializers, _rangeStart_extraInitializers);
            __esDecorate(this, null, _rangeEnd_decorators, { kind: "accessor", name: "rangeEnd", static: false, private: false, access: { has: obj => "rangeEnd" in obj, get: obj => obj.rangeEnd, set: (obj, value) => { obj.rangeEnd = value; } }, metadata: _metadata }, _rangeEnd_initializers, _rangeEnd_extraInitializers);
            __esDecorate(this, null, _rangeSelection_decorators, { kind: "accessor", name: "rangeSelection", static: false, private: false, access: { has: obj => "rangeSelection" in obj, get: obj => obj.rangeSelection, set: (obj, value) => { obj.rangeSelection = value; } }, metadata: _metadata }, _rangeSelection_initializers, _rangeSelection_extraInitializers);
            __esDecorate(this, null, _minDate_decorators, { kind: "accessor", name: "minDate", static: false, private: false, access: { has: obj => "minDate" in obj, get: obj => obj.minDate, set: (obj, value) => { obj.minDate = value; } }, metadata: _metadata }, _minDate_initializers, _minDate_extraInitializers);
            __esDecorate(this, null, _maxDate_decorators, { kind: "accessor", name: "maxDate", static: false, private: false, access: { has: obj => "maxDate" in obj, get: obj => obj.maxDate, set: (obj, value) => { obj.maxDate = value; } }, metadata: _metadata }, _maxDate_initializers, _maxDate_extraInitializers);
            __esDecorate(this, null, _disabledDates_decorators, { kind: "accessor", name: "disabledDates", static: false, private: false, access: { has: obj => "disabledDates" in obj, get: obj => obj.disabledDates, set: (obj, value) => { obj.disabledDates = value; } }, metadata: _metadata }, _disabledDates_initializers, _disabledDates_extraInitializers);
            __esDecorate(this, null, _locale_decorators, { kind: "accessor", name: "locale", static: false, private: false, access: { has: obj => "locale" in obj, get: obj => obj.locale, set: (obj, value) => { obj.locale = value; } }, metadata: _metadata }, _locale_initializers, _locale_extraInitializers);
            __esDecorate(this, null, _showNavigation_decorators, { kind: "accessor", name: "showNavigation", static: false, private: false, access: { has: obj => "showNavigation" in obj, get: obj => obj.showNavigation, set: (obj, value) => { obj.showNavigation = value; } }, metadata: _metadata }, _showNavigation_initializers, _showNavigation_extraInitializers);
            __esDecorate(this, null, _showActions_decorators, { kind: "accessor", name: "showActions", static: false, private: false, access: { has: obj => "showActions" in obj, get: obj => obj.showActions, set: (obj, value) => { obj.showActions = value; } }, metadata: _metadata }, _showActions_initializers, _showActions_extraInitializers);
            __esDecorate(this, null, _okButtonText_decorators, { kind: "accessor", name: "okButtonText", static: false, private: false, access: { has: obj => "okButtonText" in obj, get: obj => obj.okButtonText, set: (obj, value) => { obj.okButtonText = value; } }, metadata: _metadata }, _okButtonText_initializers, _okButtonText_extraInitializers);
            __esDecorate(this, null, _cancelButtonText_decorators, { kind: "accessor", name: "cancelButtonText", static: false, private: false, access: { has: obj => "cancelButtonText" in obj, get: obj => obj.cancelButtonText, set: (obj, value) => { obj.cancelButtonText = value; } }, metadata: _metadata }, _cancelButtonText_initializers, _cancelButtonText_extraInitializers);
            __esDecorate(this, null, _calendarData_decorators, { kind: "accessor", name: "calendarData", static: false, private: false, access: { has: obj => "calendarData" in obj, get: obj => obj.calendarData, set: (obj, value) => { obj.calendarData = value; } }, metadata: _metadata }, _calendarData_initializers, _calendarData_extraInitializers);
            __esDecorate(this, null, _monthNames_decorators, { kind: "accessor", name: "monthNames", static: false, private: false, access: { has: obj => "monthNames" in obj, get: obj => obj.monthNames, set: (obj, value) => { obj.monthNames = value; } }, metadata: _metadata }, _monthNames_initializers, _monthNames_extraInitializers);
            __esDecorate(this, null, _showMonthDropdown_decorators, { kind: "accessor", name: "showMonthDropdown", static: false, private: false, access: { has: obj => "showMonthDropdown" in obj, get: obj => obj.showMonthDropdown, set: (obj, value) => { obj.showMonthDropdown = value; } }, metadata: _metadata }, _showMonthDropdown_initializers, _showMonthDropdown_extraInitializers);
            __esDecorate(this, null, _showYearDropdown_decorators, { kind: "accessor", name: "showYearDropdown", static: false, private: false, access: { has: obj => "showYearDropdown" in obj, get: obj => obj.showYearDropdown, set: (obj, value) => { obj.showYearDropdown = value; } }, metadata: _metadata }, _showYearDropdown_initializers, _showYearDropdown_extraInitializers);
            __esDecorate(this, null, _pendingDate_decorators, { kind: "accessor", name: "pendingDate", static: false, private: false, access: { has: obj => "pendingDate" in obj, get: obj => obj.pendingDate, set: (obj, value) => { obj.pendingDate = value; } }, metadata: _metadata }, _pendingDate_initializers, _pendingDate_extraInitializers);
            __esDecorate(this, null, _pendingRangeStart_decorators, { kind: "accessor", name: "pendingRangeStart", static: false, private: false, access: { has: obj => "pendingRangeStart" in obj, get: obj => obj.pendingRangeStart, set: (obj, value) => { obj.pendingRangeStart = value; } }, metadata: _metadata }, _pendingRangeStart_initializers, _pendingRangeStart_extraInitializers);
            __esDecorate(this, null, _pendingRangeEnd_decorators, { kind: "accessor", name: "pendingRangeEnd", static: false, private: false, access: { has: obj => "pendingRangeEnd" in obj, get: obj => obj.pendingRangeEnd, set: (obj, value) => { obj.pendingRangeEnd = value; } }, metadata: _metadata }, _pendingRangeEnd_initializers, _pendingRangeEnd_extraInitializers);
            __esDecorate(this, null, _focusedDate_decorators, { kind: "accessor", name: "focusedDate", static: false, private: false, access: { has: obj => "focusedDate" in obj, get: obj => obj.focusedDate, set: (obj, value) => { obj.focusedDate = value; } }, metadata: _metadata }, _focusedDate_initializers, _focusedDate_extraInitializers);
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            UiDatePickerCalendar = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        static styles = calendarStyles;
        #year_accessor_storage = __runInitializers(this, _year_initializers, new Date().getFullYear()
        /**
         * The currently displayed month (0-indexed, where 0 = January)
         */
        );
        /**
         * The currently displayed year
         */
        get year() { return this.#year_accessor_storage; }
        set year(value) { this.#year_accessor_storage = value; }
        #month_accessor_storage = (__runInitializers(this, _year_extraInitializers), __runInitializers(this, _month_initializers, new Date().getMonth()
        /**
         * The currently selected date for single selection mode.
         * Set to null for no selection.
         */
        ));
        /**
         * The currently displayed month (0-indexed, where 0 = January)
         */
        get month() { return this.#month_accessor_storage; }
        set month(value) { this.#month_accessor_storage = value; }
        #selectedDate_accessor_storage = (__runInitializers(this, _month_extraInitializers), __runInitializers(this, _selectedDate_initializers, null
        /**
         * The start date of the selected range for range selection mode.
         * Used in combination with rangeEnd to define a date range.
         */
        ));
        /**
         * The currently selected date for single selection mode.
         * Set to null for no selection.
         */
        get selectedDate() { return this.#selectedDate_accessor_storage; }
        set selectedDate(value) { this.#selectedDate_accessor_storage = value; }
        #rangeStart_accessor_storage = (__runInitializers(this, _selectedDate_extraInitializers), __runInitializers(this, _rangeStart_initializers, null
        /**
         * The end date of the selected range for range selection mode.
         * Used in combination with rangeStart to define a date range.
         */
        ));
        /**
         * The start date of the selected range for range selection mode.
         * Used in combination with rangeEnd to define a date range.
         */
        get rangeStart() { return this.#rangeStart_accessor_storage; }
        set rangeStart(value) { this.#rangeStart_accessor_storage = value; }
        #rangeEnd_accessor_storage = (__runInitializers(this, _rangeStart_extraInitializers), __runInitializers(this, _rangeEnd_initializers, null
        /**
         * Enable range selection mode. When true, users can select date ranges
         * instead of single dates. Affects event dispatching and UI behavior.
         */
        ));
        /**
         * The end date of the selected range for range selection mode.
         * Used in combination with rangeStart to define a date range.
         */
        get rangeEnd() { return this.#rangeEnd_accessor_storage; }
        set rangeEnd(value) { this.#rangeEnd_accessor_storage = value; }
        #rangeSelection_accessor_storage = (__runInitializers(this, _rangeEnd_extraInitializers), __runInitializers(this, _rangeSelection_initializers, false
        /**
         * Minimum selectable date. Dates before this will be disabled.
         * Set to undefined for no minimum restriction.
         */
        ));
        /**
         * Enable range selection mode. When true, users can select date ranges
         * instead of single dates. Affects event dispatching and UI behavior.
         */
        get rangeSelection() { return this.#rangeSelection_accessor_storage; }
        set rangeSelection(value) { this.#rangeSelection_accessor_storage = value; }
        #minDate_accessor_storage = (__runInitializers(this, _rangeSelection_extraInitializers), __runInitializers(this, _minDate_initializers, undefined
        /**
         * Maximum selectable date. Dates after this will be disabled.
         * Set to undefined for no maximum restriction.
         */
        ));
        /**
         * Minimum selectable date. Dates before this will be disabled.
         * Set to undefined for no minimum restriction.
         */
        get minDate() { return this.#minDate_accessor_storage; }
        set minDate(value) { this.#minDate_accessor_storage = value; }
        #maxDate_accessor_storage = (__runInitializers(this, _minDate_extraInitializers), __runInitializers(this, _maxDate_initializers, undefined
        /**
         * Array of specific dates to disable. These dates will not be selectable
         * regardless of minDate and maxDate settings.
         */
        ));
        /**
         * Maximum selectable date. Dates after this will be disabled.
         * Set to undefined for no maximum restriction.
         */
        get maxDate() { return this.#maxDate_accessor_storage; }
        set maxDate(value) { this.#maxDate_accessor_storage = value; }
        #disabledDates_accessor_storage = (__runInitializers(this, _maxDate_extraInitializers), __runInitializers(this, _disabledDates_initializers, undefined
        /**
         * Locale for date formatting and month/day names (e.g., 'en-US', 'fr-FR').
         * Defaults to browser locale if not specified.
         */
        ));
        /**
         * Array of specific dates to disable. These dates will not be selectable
         * regardless of minDate and maxDate settings.
         */
        get disabledDates() { return this.#disabledDates_accessor_storage; }
        set disabledDates(value) { this.#disabledDates_accessor_storage = value; }
        #locale_accessor_storage = (__runInitializers(this, _disabledDates_extraInitializers), __runInitializers(this, _locale_initializers, undefined
        /**
         * Whether to show navigation controls (previous/next month and year buttons).
         * When false, users can only navigate using keyboard or programmatically.
         */
        ));
        /**
         * Locale for date formatting and month/day names (e.g., 'en-US', 'fr-FR').
         * Defaults to browser locale if not specified.
         */
        get locale() { return this.#locale_accessor_storage; }
        set locale(value) { this.#locale_accessor_storage = value; }
        #showNavigation_accessor_storage = (__runInitializers(this, _locale_extraInitializers), __runInitializers(this, _showNavigation_initializers, true
        /**
         * Whether to show action buttons (OK/Cancel). When true, selections are pending
         * until confirmed with the OK button. When false, selections are immediate.
         */
        ));
        /**
         * Whether to show navigation controls (previous/next month and year buttons).
         * When false, users can only navigate using keyboard or programmatically.
         */
        get showNavigation() { return this.#showNavigation_accessor_storage; }
        set showNavigation(value) { this.#showNavigation_accessor_storage = value; }
        #showActions_accessor_storage = (__runInitializers(this, _showNavigation_extraInitializers), __runInitializers(this, _showActions_initializers, false
        /**
         * Text label for the OK/confirm button. Only visible when showActions is true.
         */
        ));
        /**
         * Whether to show action buttons (OK/Cancel). When true, selections are pending
         * until confirmed with the OK button. When false, selections are immediate.
         */
        get showActions() { return this.#showActions_accessor_storage; }
        set showActions(value) { this.#showActions_accessor_storage = value; }
        #okButtonText_accessor_storage = (__runInitializers(this, _showActions_extraInitializers), __runInitializers(this, _okButtonText_initializers, 'OK'
        /**
         * Text label for the Cancel button. Only visible when showActions is true.
         */
        ));
        /**
         * Text label for the OK/confirm button. Only visible when showActions is true.
         */
        get okButtonText() { return this.#okButtonText_accessor_storage; }
        set okButtonText(value) { this.#okButtonText_accessor_storage = value; }
        #cancelButtonText_accessor_storage = (__runInitializers(this, _okButtonText_extraInitializers), __runInitializers(this, _cancelButtonText_initializers, 'Cancel'));
        /**
         * Text label for the Cancel button. Only visible when showActions is true.
         */
        get cancelButtonText() { return this.#cancelButtonText_accessor_storage; }
        set cancelButtonText(value) { this.#cancelButtonText_accessor_storage = value; }
        #calendarData_accessor_storage = (__runInitializers(this, _cancelButtonText_extraInitializers), __runInitializers(this, _calendarData_initializers, undefined));
        get calendarData() { return this.#calendarData_accessor_storage; }
        set calendarData(value) { this.#calendarData_accessor_storage = value; }
        #monthNames_accessor_storage = (__runInitializers(this, _calendarData_extraInitializers), __runInitializers(this, _monthNames_initializers, []));
        get monthNames() { return this.#monthNames_accessor_storage; }
        set monthNames(value) { this.#monthNames_accessor_storage = value; }
        #showMonthDropdown_accessor_storage = (__runInitializers(this, _monthNames_extraInitializers), __runInitializers(this, _showMonthDropdown_initializers, false));
        get showMonthDropdown() { return this.#showMonthDropdown_accessor_storage; }
        set showMonthDropdown(value) { this.#showMonthDropdown_accessor_storage = value; }
        #showYearDropdown_accessor_storage = (__runInitializers(this, _showMonthDropdown_extraInitializers), __runInitializers(this, _showYearDropdown_initializers, false));
        get showYearDropdown() { return this.#showYearDropdown_accessor_storage; }
        set showYearDropdown(value) { this.#showYearDropdown_accessor_storage = value; }
        #pendingDate_accessor_storage = (__runInitializers(this, _showYearDropdown_extraInitializers), __runInitializers(this, _pendingDate_initializers, null));
        get pendingDate() { return this.#pendingDate_accessor_storage; }
        set pendingDate(value) { this.#pendingDate_accessor_storage = value; }
        #pendingRangeStart_accessor_storage = (__runInitializers(this, _pendingDate_extraInitializers), __runInitializers(this, _pendingRangeStart_initializers, null));
        get pendingRangeStart() { return this.#pendingRangeStart_accessor_storage; }
        set pendingRangeStart(value) { this.#pendingRangeStart_accessor_storage = value; }
        #pendingRangeEnd_accessor_storage = (__runInitializers(this, _pendingRangeStart_extraInitializers), __runInitializers(this, _pendingRangeEnd_initializers, null));
        get pendingRangeEnd() { return this.#pendingRangeEnd_accessor_storage; }
        set pendingRangeEnd(value) { this.#pendingRangeEnd_accessor_storage = value; }
        #focusedDate_accessor_storage = (__runInitializers(this, _pendingRangeEnd_extraInitializers), __runInitializers(this, _focusedDate_initializers, null));
        get focusedDate() { return this.#focusedDate_accessor_storage; }
        set focusedDate(value) { this.#focusedDate_accessor_storage = value; }
        connectedCallback() {
            super.connectedCallback();
            this.updateCalendar();
            this.updateMonthNames();
            this.initializeFocusedDate();
        }
        firstUpdated() {
            // Set initial focus to the calendar container
            this.updateFocus();
        }
        disconnectedCallback() {
            super.disconnectedCallback();
        }
        willUpdate(changedProperties) {
            if (changedProperties.has('year') ||
                changedProperties.has('month') ||
                changedProperties.has('selectedDate') ||
                changedProperties.has('rangeStart') ||
                changedProperties.has('rangeEnd') ||
                changedProperties.has('disabledDates') ||
                changedProperties.has('locale')) {
                this.updateCalendar();
            }
            if (changedProperties.has('locale')) {
                this.updateMonthNames();
            }
            // Update focused date when month/year changes via navigation
            if (changedProperties.has('year') || changedProperties.has('month')) {
                this.updateFocusedDateForMonthChange();
            }
        }
        updated(changedProperties) {
            if (changedProperties.has('showYearDropdown') && this.showYearDropdown) {
                // Scroll selected year into view
                this.scrollSelectedYearIntoView();
            }
            if (changedProperties.has('focusedDate')) {
                this.updateFocus();
            }
        }
        updateFocus() {
            if (!this.focusedDate)
                return;
            // Find the button for the focused date and set focus
            const dateString = this.focusedDate.toISOString().split('T')[0];
            const focusedButton = this.shadowRoot?.querySelector(`[data-date="${dateString}"]`);
            if (focusedButton && !focusedButton.hasAttribute('disabled')) {
                // Use requestAnimationFrame to ensure DOM is updated
                requestAnimationFrame(() => {
                    focusedButton.focus();
                });
            }
        }
        scrollSelectedYearIntoView() {
            // Wait for next frame to ensure DOM is updated
            requestAnimationFrame(() => {
                const selectedYearButton = this.shadowRoot?.querySelector('.year-option.selected');
                if (selectedYearButton) {
                    selectedYearButton.scrollIntoView({
                        behavior: 'auto',
                        block: 'center',
                    });
                }
            });
        }
        updateFocusedDateForMonthChange() {
            if (!this.focusedDate) {
                this.initializeFocusedDate();
                return;
            }
            // Keep the same day of month if possible
            const targetDay = this.focusedDate.getDate();
            const newDate = new Date(this.year, this.month, targetDay);
            // Check if the target date exists in the new month and is not disabled
            if (newDate.getMonth() === this.month && !this.isDateDisabled(newDate)) {
                this.focusedDate = newDate;
            }
            else {
                // Find the closest available date
                this.focusedDate = this.findFirstAvailableDate();
            }
        }
        updateCalendar() {
            const selectedRange = this.rangeStart || this.rangeEnd ? { start: this.rangeStart, end: this.rangeEnd } : null;
            this.calendarData = generateCalendarMonth(this.year, this.month, this.selectedDate, selectedRange, this.disabledDates, this.locale);
        }
        updateMonthNames() {
            this.monthNames = getMonthNames(this.locale);
        }
        navigateMonth(delta) {
            const newDate = addMonths(new Date(this.year, this.month), delta);
            this.year = newDate.getFullYear();
            this.month = newDate.getMonth();
        }
        handlePrevMonth() {
            this.navigateMonth(-1);
        }
        handleNextMonth() {
            this.navigateMonth(1);
        }
        handlePrevYear() {
            this.year = this.year - 1;
        }
        handleNextYear() {
            this.year = this.year + 1;
        }
        handleMonthClick() {
            this.showMonthDropdown = !this.showMonthDropdown;
            this.showYearDropdown = false;
        }
        handleYearClick() {
            this.showYearDropdown = !this.showYearDropdown;
            this.showMonthDropdown = false;
        }
        handleMonthSelect(selectedMonth) {
            this.month = selectedMonth;
            this.showMonthDropdown = false;
        }
        handleYearSelect(selectedYear) {
            this.year = selectedYear;
            this.showYearDropdown = false;
        }
        closeDropdowns() {
            this.showMonthDropdown = false;
            this.showYearDropdown = false;
        }
        navigateDate(delta) {
            if (!this.focusedDate)
                return;
            const newDate = addDays(this.focusedDate, delta);
            // Check if new date is in current month or if we should navigate to next/previous month
            if (newDate.getMonth() !== this.month || newDate.getFullYear() !== this.year) {
                // Navigate to next/previous month
                if (delta > 0) {
                    this.navigateMonth(1);
                }
                else {
                    this.navigateMonth(-1);
                }
                // Set focused date to the target date in the new month
                this.focusedDate = newDate;
                return;
            }
            // Check if new date is disabled
            if (this.isDateDisabled(newDate)) {
                // Try to find next available date
                const availableDate = this.findNextAvailableDate(newDate, delta > 0);
                if (availableDate) {
                    this.focusedDate = availableDate;
                }
            }
            else {
                this.focusedDate = newDate;
            }
        }
        findNextAvailableDate(startDate, forward) {
            const direction = forward ? 1 : -1;
            for (let i = 1; i <= 31; i++) {
                const date = addDays(startDate, i * direction);
                if (date.getMonth() !== this.month)
                    break; // Out of current month
                if (!this.isDateDisabled(date)) {
                    return date;
                }
            }
            return null;
        }
        focusFirstDayOfMonth() {
            const firstDay = new Date(this.year, this.month, 1);
            if (!this.isDateDisabled(firstDay)) {
                this.focusedDate = firstDay;
            }
            else {
                this.focusedDate = this.findFirstAvailableDate();
            }
        }
        focusLastDayOfMonth() {
            const lastDay = new Date(this.year, this.month + 1, 0);
            if (!this.isDateDisabled(lastDay)) {
                this.focusedDate = lastDay;
            }
            else {
                // Find last available date in month
                for (let i = lastDay.getDate(); i >= 1; i--) {
                    const date = new Date(this.year, this.month, i);
                    if (!this.isDateDisabled(date)) {
                        this.focusedDate = date;
                        break;
                    }
                }
            }
        }
        selectFocusedDate() {
            if (!this.focusedDate || this.isDateDisabled(this.focusedDate))
                return;
            if (this.rangeSelection) {
                this.handleRangeSelection(this.focusedDate);
            }
            else {
                this.handleSingleSelection(this.focusedDate);
            }
        }
        handleDayClick(day) {
            if (day.isDisabled)
                return;
            // Update focused date to clicked date
            this.focusedDate = day.date;
            if (this.rangeSelection) {
                this.handleRangeSelection(day.date);
            }
            else {
                this.handleSingleSelection(day.date);
            }
        }
        handleSingleSelection(date) {
            if (this.showActions) {
                // Use pending state when actions are enabled
                this.pendingDate = date;
            }
            else {
                // Immediate selection when no actions
                this.selectedDate = date;
                this.dispatchDateEvent(date);
            }
        }
        handleRangeSelection(date) {
            const isImmediate = !this.showActions;
            const { start, end } = this.getCurrentRange();
            // If we have a complete range, start a new one
            if (start && end) {
                this.setRangeValues(date, null, isImmediate);
                return;
            }
            // If we have a start but no end, complete the range
            if (start && !end) {
                const sortedRange = start <= date ? { start, end: date } : { start: date, end: start };
                this.setRangeValues(sortedRange.start, sortedRange.end, isImmediate);
                if (isImmediate) {
                    this.dispatchRangeEvent(sortedRange);
                }
                return;
            }
            // Start new range
            this.setRangeValues(date, null, isImmediate);
        }
        /**
         * Helper to get the current range state (either immediate or pending)
         */
        getCurrentRange() {
            const isImmediate = !this.showActions;
            return {
                start: isImmediate ? this.rangeStart : this.pendingRangeStart,
                end: isImmediate ? this.rangeEnd : this.pendingRangeEnd,
            };
        }
        /**
         * Helper to check if we have a complete range in the current mode
         */
        hasCompleteRange() {
            const { start, end } = this.getCurrentRange();
            return !!(start && end);
        }
        setRangeValues(start, end, isImmediate) {
            if (isImmediate) {
                this.rangeStart = start;
                this.rangeEnd = end;
            }
            else {
                this.pendingRangeStart = start;
                this.pendingRangeEnd = end;
            }
        }
        /**
         * Helper to dispatch date selection events
         */
        dispatchDateEvent(date) {
            const event = {
                date,
                formattedDate: formatDate(date, this.locale),
            };
            this.dispatchEvent(new CustomEvent('date-select', {
                detail: event,
                bubbles: true,
                composed: true,
            }));
        }
        /**
         * Helper to dispatch range selection events
         */
        dispatchRangeEvent(range) {
            const event = {
                range,
                formattedRange: {
                    start: formatDate(range.start, this.locale),
                    end: formatDate(range.end, this.locale),
                },
            };
            this.dispatchEvent(new CustomEvent('date-range-select', {
                detail: event,
                bubbles: true,
                composed: true,
            }));
        }
        /**
         * Helper to dispatch range confirmation events
         */
        dispatchRangeConfirmEvent(range) {
            const event = {
                range,
                formattedRange: {
                    start: range?.start ? formatDate(range.start, this.locale) : null,
                    end: range?.end ? formatDate(range.end, this.locale) : null,
                },
            };
            this.dispatchEvent(new CustomEvent('date-range-confirm', {
                detail: event,
                bubbles: true,
                composed: true,
            }));
        }
        /**
         * Helper to dispatch cancel events
         */
        dispatchCancelEvent(reason = 'user_cancelled') {
            const event = { reason };
            this.dispatchEvent(new CustomEvent('date-cancel', {
                detail: event,
                bubbles: true,
                composed: true,
            }));
        }
        isDateDisabled(date) {
            if (this.minDate && date < this.minDate)
                return true;
            if (this.maxDate && date > this.maxDate)
                return true;
            if (this.disabledDates?.some((disabledDate) => isSameDay(date, disabledDate)))
                return true;
            return false;
        }
        handleConfirm() {
            if (this.rangeSelection) {
                if (this.pendingRangeStart || this.pendingRangeEnd) {
                    this.rangeStart = this.pendingRangeStart;
                    this.rangeEnd = this.pendingRangeEnd;
                    const range = this.rangeStart || this.rangeEnd ? { start: this.rangeStart, end: this.rangeEnd } : null;
                    // Reset pending state after confirmation
                    this.pendingRangeStart = null;
                    this.pendingRangeEnd = null;
                    this.dispatchRangeConfirmEvent(range);
                }
            }
            else {
                if (this.pendingDate) {
                    this.selectedDate = this.pendingDate;
                    // Reset pending state after confirmation
                    this.pendingDate = null;
                    this.dispatchDateEvent(this.selectedDate);
                }
            }
        }
        handleCancel() {
            // Reset pending state
            this.pendingDate = null;
            this.pendingRangeStart = null;
            this.pendingRangeEnd = null;
            this.dispatchCancelEvent();
        }
        /**
         * Helper to render navigation buttons
         */
        renderNavButton(direction, onClick, ariaLabel, icon) {
            if (!this.showNavigation || this.showMonthDropdown || this.showYearDropdown) {
                return nothing;
            }
            return html `<ui-icon-button
      class="nav-button"
      size="xs"
      @click=${onClick}
      aria-label=${ariaLabel}
      title=${ariaLabel}
    >
      <ui-icon icon=${icon}></ui-icon>
    </ui-icon-button>`;
        }
        renderNavigation() {
            const monthName = this.monthNames[this.month] || '';
            return html `
      <div class="header">
        <div class="month-year">
          <div class="month-selector">
            ${this.renderNavButton('prev', this.handlePrevMonth, 'Previous month', 'chevronLeft')}
            <ui-button
              class="month-button"
              color="text"
              size="xs"
              @click=${this.handleMonthClick}
              aria-label="Select month"
              aria-expanded=${this.showMonthDropdown}
              trailingIcon
            >
              ${monthName}
              <ui-icon icon="arrowDropDown" slot="icon"></ui-icon>
            </ui-button>
            ${this.renderNavButton('next', this.handleNextMonth, 'Next month', 'chevronRight')}
          </div>
          <div class="year-selector">
            ${this.renderNavButton('prev', this.handlePrevYear, 'Previous year', 'chevronLeft')}
            <ui-button
              class="year-button"
              color="text"
              size="xs"
              @click=${this.handleYearClick}
              aria-label="Select year"
              aria-expanded=${this.showYearDropdown}
              trailingIcon
            >
              ${this.year}
              <ui-icon icon="arrowDropDown" slot="icon"></ui-icon>
            </ui-button>
            ${this.renderNavButton('next', this.handleNextYear, 'Next year', 'chevronRight')}
          </div>
        </div>
      </div>
    `;
        }
        renderWeekdays() {
            if (!this.calendarData)
                return html ``;
            return html `
      <div class="weekdays" role="row">
        ${this.calendarData.weekdays.map((weekday) => html `<div class="weekday" role="columnheader">${weekday}</div>`)}
      </div>
    `;
        }
        /**
         * Helper to determine day selection state for rendering
         */
        getDaySelectionState(day) {
            if (this.showActions) {
                // Use pending state
                const isPendingSelected = this.pendingDate && isSameDay(day.date, this.pendingDate);
                const isPendingRangeStart = this.pendingRangeStart && isSameDay(day.date, this.pendingRangeStart);
                const isPendingRangeEnd = this.pendingRangeEnd && isSameDay(day.date, this.pendingRangeEnd);
                const isPendingInRange = this.pendingRangeStart &&
                    this.pendingRangeEnd &&
                    day.date >= this.pendingRangeStart &&
                    day.date <= this.pendingRangeEnd &&
                    !isPendingRangeStart &&
                    !isPendingRangeEnd;
                return {
                    isSelected: !!isPendingSelected,
                    isRangeStart: !!isPendingRangeStart,
                    isRangeEnd: !!isPendingRangeEnd,
                    isInRange: !!isPendingInRange,
                };
            }
            else {
                // Use immediate state
                return {
                    isSelected: day.isSelected,
                    isRangeStart: day.isRangeStart,
                    isRangeEnd: day.isRangeEnd,
                    isInRange: day.isInRange,
                };
            }
        }
        /**
         * Helper to determine button color for a day
         */
        getDayButtonColor(day, selectionState) {
            if (selectionState.isRangeStart || selectionState.isRangeEnd || selectionState.isSelected) {
                return 'filled';
            }
            if (selectionState.isInRange) {
                return 'text';
            }
            if (day.isToday) {
                return 'outlined';
            }
            return 'text';
        }
        renderDay(day) {
            const selectionState = this.getDaySelectionState(day);
            const color = this.getDayButtonColor(day, selectionState);
            const classes = {
                'day-cell': true,
                'other-month': !day.isCurrentMonth,
                'today': day.isToday,
                'in-range': selectionState.isInRange,
                'range-start': selectionState.isRangeStart,
                'range-end': selectionState.isRangeEnd,
                'has-complete-range': this.hasCompleteRange(),
            };
            const isFocused = this.focusedDate && isSameDay(day.date, this.focusedDate);
            return html `
      <div class=${classMap(classes)} role="gridcell">
        <ui-button
          class="day-button"
          color=${color}
          size="s"
          data-date=${day.date.toISOString().split('T')[0]}
          tabindex=${isFocused && !(day.isDisabled || this.isDateDisabled(day.date)) ? '0' : '-1'}
          aria-label=${formatDate(day.date, this.locale)}
          aria-selected=${selectionState.isSelected || selectionState.isRangeStart || selectionState.isRangeEnd}
          @click=${() => this.handleDayClick(day)}
          ?disabled=${day.isDisabled || this.isDateDisabled(day.date)}
        >
          ${day.date.getDate()}
        </ui-button>
      </div>
    `;
        }
        renderDays() {
            if (!this.calendarData)
                return html ``;
            return html `<div class="days">${this.calendarData.days.map((day) => this.renderDay(day))}</div>`;
        }
        renderActions() {
            if (!this.showActions)
                return nothing;
            const hasSelection = this.rangeSelection ? this.pendingRangeStart : this.pendingDate;
            return html `
      <div class="actions">
        <ui-button size="s" color="text" @click=${this.handleCancel}>${this.cancelButtonText}</ui-button>
        <ui-button size="s" color="text" @click=${this.handleConfirm} ?disabled=${!hasSelection}>
          ${this.okButtonText}
        </ui-button>
      </div>
    `;
        }
        /**
         * Helper to render dropdown option buttons
         */
        renderDropdownOption(value, label, isSelected, onClick, className = '') {
            return html `
      <ui-button
        class="dropdown-option ${className} ${isSelected ? 'selected' : ''}"
        color=${isSelected ? 'filled' : 'text'}
        size="s"
        @click=${onClick}
        aria-label=${label}
      >
        ${label}
      </ui-button>
    `;
        }
        renderMonthDropdown() {
            return html `
      <div class="dropdown-view">
        <div class="month-list">
          ${this.monthNames.map((monthName, index) => this.renderDropdownOption(index, monthName, index === this.month, () => this.handleMonthSelect(index)))}
        </div>
      </div>
    `;
        }
        renderYearDropdown() {
            const currentYear = this.year;
            const startYear = currentYear - 50;
            const endYear = currentYear + 50;
            const years = [];
            for (let year = startYear; year <= endYear; year++) {
                years.push(year);
            }
            return html `
      <div class="dropdown-view">
        <div class="year-grid">
          ${years.map((year) => this.renderDropdownOption(year, year.toString(), year === this.year, () => this.handleYearSelect(year), 'year-option'))}
        </div>
      </div>
    `;
        }
        findFirstAvailableDate() {
            const firstDayOfMonth = new Date(this.year, this.month, 1);
            for (let i = 0; i < 31; i++) {
                const date = addDays(firstDayOfMonth, i);
                if (date.getMonth() !== this.month)
                    break; // Next month
                if (!this.isDateDisabled(date)) {
                    return date;
                }
            }
            return firstDayOfMonth; // Fallback
        }
        handleKeyDown(event) {
            // Prevent default behavior for navigation keys
            const navigationKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown', ' '];
            if (navigationKeys.includes(event.key)) {
                event.preventDefault();
            }
            switch (event.key) {
                case 'ArrowLeft':
                    this.navigateDate(-1);
                    break;
                case 'ArrowRight':
                    this.navigateDate(1);
                    break;
                case 'ArrowUp':
                    this.navigateDate(-7);
                    break;
                case 'ArrowDown':
                    this.navigateDate(7);
                    break;
                case 'Enter':
                case ' ':
                    this.selectFocusedDate();
                    break;
                case 'Home':
                    this.focusFirstDayOfMonth();
                    break;
                case 'End':
                    this.focusLastDayOfMonth();
                    break;
                case 'PageUp':
                    if (event.shiftKey) {
                        this.handlePrevYear();
                    }
                    else {
                        this.navigateMonth(-1);
                    }
                    break;
                case 'PageDown':
                    if (event.shiftKey) {
                        this.handleNextYear();
                    }
                    else {
                        this.navigateMonth(1);
                    }
                    break;
                case 'Escape':
                    this.closeDropdowns();
                    break;
            }
        }
        /**
         * Helper to check if a date is in the current month and not disabled
         */
        isDateAvailable(date) {
            return date.getMonth() === this.month && date.getFullYear() === this.year && !this.isDateDisabled(date);
        }
        initializeFocusedDate() {
            // Priority: selectedDate, rangeStart, today, first available date
            const candidates = [this.selectedDate, this.rangeStart, new Date()].filter(Boolean);
            for (const candidate of candidates) {
                if (this.isDateAvailable(candidate)) {
                    this.focusedDate = candidate;
                    return;
                }
            }
            // Fallback to first available date in current month
            this.focusedDate = this.findFirstAvailableDate();
        }
        render() {
            // Show dropdown views instead of calendar when dropdowns are open
            if (this.showMonthDropdown) {
                return html `
        <div class="calendar" role="grid" aria-label="Month selection for ${this.year}">
          ${this.renderNavigation()} ${this.renderMonthDropdown()}
        </div>
      `;
            }
            if (this.showYearDropdown) {
                return html `
        <div class="calendar" role="grid" aria-label="Year selection">
          ${this.renderNavigation()} ${this.renderYearDropdown()}
        </div>
      `;
            }
            // Default calendar view
            return html `
      <div
        class="calendar"
        role="grid"
        aria-label="Calendar for ${this.monthNames[this.month]} ${this.year}"
        aria-roledescription="Calendar grid"
        tabindex="0"
        @keydown=${this.handleKeyDown}
      >
        ${this.renderNavigation()} ${this.renderWeekdays()} ${this.renderDays()} ${this.renderActions()}
      </div>
    `;
        }
        constructor() {
            super(...arguments);
            __runInitializers(this, _focusedDate_extraInitializers);
        }
        static {
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return UiDatePickerCalendar = _classThis;
})();
export { UiDatePickerCalendar };
//# sourceMappingURL=DatePickerCalendar.js.map