/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { addClass, isArray, createVisuallyHiddenElement } from '@tylertech/forge-core';
import { PopupAnimationType, POPUP_CONSTANTS } from '../../popup';
import { CALENDAR_CONSTANTS } from '../calendar-constants';
import { getDateId } from '../calendar-dom-utils';
import { CALENDAR_DROPDOWN_CONSTANTS } from './calendar-dropdown-constants';
export class CalendarDropdown {
    constructor(targetElement, id) {
        this._popupClasses = [];
        this.targetElement = targetElement;
        this.id = id;
    }
    get isOpen() {
        var _a, _b;
        return (_b = (_a = this.dropdownElement) === null || _a === void 0 ? void 0 : _a.open) !== null && _b !== void 0 ? _b : false;
    }
    get popupClasses() {
        return this._popupClasses;
    }
    set popupClasses(value) {
        this._popupClasses = !!value ? isArray(value) ? [...value] : [value] : [];
    }
    get locale() {
        var _a;
        return (_a = this.calendar) === null || _a === void 0 ? void 0 : _a.locale;
    }
    set locale(value) {
        if (this.calendar) {
            this.calendar.locale = value;
        }
    }
    close() {
        if (!this.dropdownElement) {
            return;
        }
        this.dropdownElement.open = false;
        this.dropdownElement = undefined;
        this.calendar = undefined;
    }
    destroy() {
        this.close();
    }
    open(config) {
        // Create calendar element
        this.calendar = this._createCalendar(config);
        this._announcerElement = createVisuallyHiddenElement();
        this._announcerElement.id = `${this.id}-activedescendant`;
        // Create dropdown element
        this.dropdownElement = this._createDropdown();
        this.dropdownElement.appendChild(this.calendar);
        this.dropdownElement.appendChild(this._announcerElement);
        this.dropdownElement.static = true;
        // Add a listener for when the active descendent is updated
        this.calendar.addEventListener(CALENDAR_CONSTANTS.events.FOCUS_CHANGE, (evt) => {
            var _a;
            let id = `${this.id}-activedescendent-`;
            switch (evt.detail.type) {
                case 'date':
                    id += getDateId(evt.detail.value);
                    break;
                case 'month':
                    id += `month-${evt.detail.value.toString()}`;
                    break;
                case 'year':
                    id += `year-${evt.detail.value.toString()}`;
                    break;
            }
            (_a = this.activeChangeCallback) === null || _a === void 0 ? void 0 : _a.call(this, id);
            if (this._announcerElement) {
                this._announcerElement.id = id;
                this._announcerElement.setAttribute('aria-selected', evt.detail.selected.toString());
                this._announcerElement.textContent = evt.detail.text;
            }
        });
        // Open the popup
        this.dropdownElement.open = true;
        // Attempt to re-layout the calendar to account for updates in rendering during scale
        // transition within popup (fixes ripple alignment... etc.)
        window.requestAnimationFrame(() => {
            setTimeout(() => {
                if (this.dropdownElement && this.dropdownElement.open && this.calendar && this.calendar.isConnected) {
                    this.calendar.layout();
                }
            }, POPUP_CONSTANTS.numbers.ANIMATION_DURATION);
        });
    }
    propagateKeyboardEvent(evt) {
        var _a;
        (_a = this.calendar) === null || _a === void 0 ? void 0 : _a.handleKey(evt);
    }
    _createCalendar(config) {
        const calendarElement = document.createElement(CALENDAR_CONSTANTS.elementName);
        Object.assign(calendarElement, config);
        return calendarElement;
    }
    _createDropdown() {
        const popupElement = document.createElement(POPUP_CONSTANTS.elementName);
        popupElement.targetElement = this.targetElement;
        popupElement.placement = 'bottom-start';
        popupElement.animationType = PopupAnimationType.Menu;
        popupElement.classList.add(CALENDAR_DROPDOWN_CONSTANTS.classes.POPUP);
        popupElement.id = this.id;
        addClass(this._popupClasses, popupElement);
        popupElement.addEventListener(POPUP_CONSTANTS.events.CLOSE, () => {
            if (this.closeCallback) {
                this.closeCallback();
            }
        });
        return popupElement;
    }
}
