/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { isArray, createVisuallyHiddenElement, closestElement } from '@tylertech/forge-core';
import { POPOVER_CONSTANTS } from '../../popover/popover-constants';
import { CALENDAR_CONSTANTS } from '../calendar-constants';
import { getDateId } from '../calendar-dom-utils';
import { CALENDAR_DROPDOWN_CONSTANTS } from './calendar-dropdown-constants';
export class CalendarDropdown {
    get isOpen() {
        return this.dropdownElement?.open ?? false;
    }
    get popupClasses() {
        return this._popupClasses;
    }
    set popupClasses(value) {
        this._popupClasses = !!value ? (isArray(value) ? [...value] : [value]) : [];
    }
    get locale() {
        return this.calendar?.locale;
    }
    set locale(value) {
        if (this.calendar) {
            this.calendar.locale = value;
        }
    }
    constructor(targetElement, id) {
        this._popupClasses = [];
        this.targetElement = targetElement;
        this.id = id;
    }
    async close({ force = false } = {}) {
        if (!this.dropdownElement) {
            return;
        }
        if (force) {
            this.dropdownElement.open = false;
        }
        else {
            await this.dropdownElement.hideAsync();
        }
        this.dropdownElement.remove();
        this.dropdownElement = undefined;
        this.calendar = undefined;
    }
    destroy() {
        this.close({ force: true });
    }
    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);
        // Add a listener for when the active descendent is updated
        this.calendar.addEventListener(CALENDAR_CONSTANTS.events.FOCUS_CHANGE, (evt) => {
            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;
            }
            this.activeChangeCallback?.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;
            }
        });
        // Append to root node
        const hostDocument = this.targetElement.ownerDocument ?? document;
        const hostElement = closestElement(POPOVER_CONSTANTS.selectors.HOST, this.targetElement) ?? hostDocument.body;
        hostElement.appendChild(this.dropdownElement);
        this.dropdownElement.open = true;
    }
    propagateKeyboardEvent(evt) {
        this.calendar?.handleKey(evt);
    }
    _createCalendar(config) {
        const calendarElement = document.createElement(CALENDAR_CONSTANTS.elementName);
        Object.assign(calendarElement, config);
        return calendarElement;
    }
    _createDropdown() {
        const popupElement = document.createElement('forge-popover');
        popupElement.anchorElement = this.targetElement;
        popupElement.placement = 'bottom-start';
        popupElement.persistent = true;
        popupElement.classList.add(CALENDAR_DROPDOWN_CONSTANTS.classes.POPUP);
        popupElement.id = this.id;
        popupElement.classList.add(...this._popupClasses);
        popupElement.addEventListener(POPOVER_CONSTANTS.events.TOGGLE, () => this.closeCallback?.());
        return popupElement;
    }
}
