/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { getShadowElement, emitEvent, getActiveElement, toggleAttribute } from '@tylertech/forge-core';
import { BaseAdapter, setAriaControls, tryCreateAriaControlsPlaceholder } from '../core';
import { TIME_PICKER_CONSTANTS } from './time-picker-constants';
import { TimeInputMask } from '../core/mask/time-input-mask';
import { TEXT_FIELD_CONSTANTS } from '../text-field';
import { ICON_BUTTON_CONSTANTS } from '../icon-button';
import { ICON_CONSTANTS } from '../icon';
import { ListDropdown } from '../list-dropdown';
export class TimePickerAdapter extends BaseAdapter {
    constructor(component) {
        super(component);
    }
    get inputElement() {
        return this._inputElement;
    }
    initialize() {
        this._inputElement = this._component.querySelector(TIME_PICKER_CONSTANTS.selectors.INPUT);
    }
    initializeMask(options) {
        this.destroyMask();
        this._inputMask = new TimeInputMask(this._inputElement, options);
    }
    destroy() {
        this._targetElement = undefined;
        this._toggleElement = undefined;
        this._inputElement = undefined;
    }
    destroyMask() {
        var _a;
        (_a = this._inputMask) === null || _a === void 0 ? void 0 : _a.destroy();
        this._inputMask = undefined;
    }
    initializeAccessibility(identifier) {
        this._inputElement.setAttribute('autocomplete', 'off');
        this._inputElement.setAttribute('autocorrect', 'off');
        this._inputElement.setAttribute('autocapitalize', 'off');
        this._inputElement.setAttribute('spellcheck', 'false');
        this._inputElement.setAttribute('role', 'combobox');
        this._inputElement.setAttribute('aria-live', 'assertive');
        this._inputElement.setAttribute('aria-atomic', 'true');
        this._inputElement.setAttribute('aria-haspopup', 'true');
        this._inputElement.setAttribute('aria-expanded', 'false');
        tryCreateAriaControlsPlaceholder();
        setAriaControls(this._inputElement);
    }
    addInputListener(type, listener, capture) {
        this._inputElement.addEventListener(type, listener, { capture });
    }
    removeInputListener(type, listener, capture) {
        if (this._inputElement) {
            this._inputElement.removeEventListener(type, listener, { capture });
        }
    }
    addToggleListener(type, listener) {
        if (this._toggleElement) {
            this._toggleElement.addEventListener(type, listener);
        }
    }
    removeToggleListener(type, listener) {
        if (this._toggleElement) {
            this._toggleElement.removeEventListener(type, listener);
        }
    }
    hasInputElement() {
        return !!this._inputElement;
    }
    tryCreateToggle() {
        const textField = this._component.querySelector(TEXT_FIELD_CONSTANTS.elementName);
        const toggleElement = this._component.querySelector(TIME_PICKER_CONSTANTS.selectors.TOGGLE);
        if (textField) {
            const existingIconButton = textField.querySelector(`${ICON_BUTTON_CONSTANTS.elementName}[slot=trailing]`);
            if (existingIconButton || toggleElement) {
                this._toggleElement = (existingIconButton || toggleElement);
                return;
            }
            const iconButtonElement = document.createElement(ICON_BUTTON_CONSTANTS.elementName);
            iconButtonElement.slot = 'trailing';
            iconButtonElement.dense = true;
            iconButtonElement.densityLevel = 3;
            iconButtonElement.style.marginRight = '4px'; // Override default trailing slot margin in text-field
            const buttonElement = document.createElement('button');
            buttonElement.type = 'button';
            buttonElement.tabIndex = -1;
            buttonElement.setAttribute('aria-label', 'Toggle time dropdown');
            const iconElement = document.createElement(ICON_CONSTANTS.elementName);
            iconElement.name = 'clock_outline';
            buttonElement.appendChild(iconElement);
            iconButtonElement.appendChild(buttonElement);
            textField.appendChild(iconButtonElement);
            this._toggleElement = iconButtonElement;
        }
        else if (toggleElement) {
            this._toggleElement = toggleElement;
        }
    }
    tryFocusInput() {
        this._inputElement.select();
    }
    tryBlurInput() {
        this._inputElement.blur();
    }
    selectInputText() {
        this._inputElement.select();
    }
    isInputDisabled() {
        return this._inputElement.disabled;
    }
    isInputFocused() {
        const activeElement = getActiveElement(this._component.ownerDocument);
        return activeElement === this._inputElement;
    }
    setInputValue(value, emitEvents) {
        if (this._inputElement.value === value) {
            return;
        }
        this._inputElement.value = value;
        if (this._inputMask) {
            this._inputMask.update();
        }
        if (emitEvents) {
            this._emitInputEvent('change');
            this._emitInputEvent('input');
        }
    }
    getInputValue() {
        return this._inputMask ? this._inputMask.maskedValue : this._inputElement.value;
    }
    setDisabled(isDisabled) {
        this._inputElement.disabled = isDisabled;
        this._inputElement.setAttribute('aria-disabled', isDisabled.toString());
        this.setToggleDisabled(isDisabled);
    }
    attachDropdown(config) {
        this._listDropdown = new ListDropdown(this._inputElement, config);
        this._listDropdown.open();
        this._inputElement.setAttribute('aria-controls', `list-dropdown-popup-${config.id}`);
    }
    detachDropdown() {
        if (this._listDropdown) {
            this._listDropdown.close();
            this._listDropdown.destroy();
            this._listDropdown = undefined;
        }
        setAriaControls(this._inputElement);
    }
    propagateKey(key) {
        var _a;
        (_a = this._listDropdown) === null || _a === void 0 ? void 0 : _a.handleKey(key);
    }
    setActiveDescendant(id) {
        toggleAttribute(this._inputElement, !!id, 'aria-activedescendant', id);
    }
    getTargetElementWidth(selector) {
        const targetElement = this._getTargetElement(selector);
        return targetElement.getBoundingClientRect().width;
    }
    _emitInputEvent(type) {
        this._inputElement.dispatchEvent(new Event(type));
    }
    emitInputEvent(type, data) {
        emitEvent(this._inputElement, type, data);
    }
    setInputReadonly(value) {
        this._inputElement.readOnly = value;
    }
    setToggleDisabled(value) {
        if (this._toggleElement) {
            this._toggleElement.setAttribute('aria-disabled', value.toString());
            if ('disabled' in this._toggleElement) {
                this._toggleElement.disabled = value;
            }
            else {
                const button = this._toggleElement.querySelector('button');
                if (button) {
                    button.disabled = value;
                }
            }
        }
    }
    hasActiveOption() {
        var _a, _b;
        return ((_b = (_a = this._listDropdown) === null || _a === void 0 ? void 0 : _a.getActiveOptionIndex()) !== null && _b !== void 0 ? _b : -1) >= 0;
    }
    activateOptionByIndex(index) {
        var _a;
        (_a = this._listDropdown) === null || _a === void 0 ? void 0 : _a.activateOption(index);
    }
    activateFirstOption() {
        var _a;
        (_a = this._listDropdown) === null || _a === void 0 ? void 0 : _a.activateFirstOption();
    }
    getActiveOption() {
        var _a;
        return (_a = this._listDropdown) === null || _a === void 0 ? void 0 : _a.getActiveOption();
    }
    _getTargetElement(selector) {
        if (this._targetElement) {
            return this._targetElement;
        }
        this._targetElement = selector ? this._component.querySelector(selector) || this._getDefaultTargetElement() : this._getDefaultTargetElement();
        return this._targetElement;
    }
    _getDefaultTargetElement() {
        // This component is often used with the text-field, if so, let's target our popup around one if its internal elements for proper alignnment
        const textField = this._component.querySelector(TEXT_FIELD_CONSTANTS.elementName);
        if (textField && textField.shadowRoot) {
            const textFieldRoot = getShadowElement(textField, TEXT_FIELD_CONSTANTS.selectors.ROOT);
            if (textFieldRoot) {
                return textFieldRoot;
            }
        }
        return this._component; // Otherwise we just use the time-picker host as the target
    }
}
