/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { addClass, getShadowElement, removeClass, toggleClass } from '@tylertech/forge-core';
import { BaseAdapter, createUserInteractionListener } from '../core';
import { ForgeRipple, ForgeRippleFoundation } from '../ripple';
import { BUTTON_AREA_CONSTANTS } from './button-area-constants';
export class ButtonAreaAdapter extends BaseAdapter {
    constructor(component) {
        super(component);
        this._rootElement = getShadowElement(component, BUTTON_AREA_CONSTANTS.selectors.ROOT);
        this._buttonSlotElement = getShadowElement(component, BUTTON_AREA_CONSTANTS.selectors.BUTTON_SLOT);
    }
    get root() {
        return this._rootElement;
    }
    get unbounded() {
        return false;
    }
    get disabled() {
        return this.buttonIsDisabled();
    }
    destroy() {
        if (typeof this._destroyUserInteractionListener === 'function') {
            this._destroyUserInteractionListener();
            this._destroyUserInteractionListener = undefined;
        }
    }
    setDisabled(value) {
        var _a;
        toggleClass(this._rootElement, value, BUTTON_AREA_CONSTANTS.classes.DISABLED);
        (_a = this._buttonElement) === null || _a === void 0 ? void 0 : _a.toggleAttribute(BUTTON_AREA_CONSTANTS.attributes.DISABLED, value);
    }
    addListener(type, listener) {
        this._rootElement.addEventListener(type, listener);
    }
    removeListener(type, listener) {
        this._rootElement.removeEventListener(type, listener);
    }
    addSlotChangeListener(listener) {
        this._buttonSlotElement.addEventListener('slotchange', listener);
    }
    removeSlotChangeListener(listener) {
        this._buttonSlotElement.removeEventListener('slotchange', listener);
    }
    startButtonObserver(callback) {
        if (this._buttonElement) {
            this._buttonObserver = new MutationObserver(callback);
            this._buttonObserver.observe(this._buttonElement, { attributeFilter: [BUTTON_AREA_CONSTANTS.attributes.DISABLED] });
        }
    }
    stopButtonObserver() {
        if (this._buttonObserver) {
            this._buttonObserver.disconnect();
            this._buttonObserver = undefined;
        }
    }
    detectSlottedButton() {
        this._buttonElement = this._buttonSlotElement.assignedElements()[0];
    }
    buttonIsDisabled() {
        var _a, _b;
        return (_b = (_a = this._buttonElement) === null || _a === void 0 ? void 0 : _a.disabled) !== null && _b !== void 0 ? _b : true;
    }
    requestDisabledButtonFrame() {
        if (this._buttonElement) {
            this._buttonElement.disabled = true;
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            requestAnimationFrame(() => this._buttonElement.disabled = false);
        }
    }
    async createRipple() {
        if (!this._rippleInstance) {
            const { userInteraction, destroy } = await createUserInteractionListener(this._rootElement);
            this._destroyUserInteractionListener = destroy;
            const { type } = await userInteraction;
            this._destroyUserInteractionListener = undefined;
            if (!this.isConnected) {
                return;
            }
            if (!this._rippleInstance) {
                const adapter = Object.assign(Object.assign({}, ForgeRipple.createAdapter(this)), { isSurfaceActive: () => { var _a, _b; return this._rootElement.matches(':active') || ((_b = (_a = this._buttonElement) === null || _a === void 0 ? void 0 : _a.matches(':active')) !== null && _b !== void 0 ? _b : false); }, isSurfaceDisabled: () => { var _a; return (_a = this.disabled) !== null && _a !== void 0 ? _a : true; }, isUnbounded: () => !!this.unbounded, registerInteractionHandler: (evtType, handler) => {
                        var _a;
                        if (this._isRootEvent(evtType)) {
                            this._rootElement.addEventListener(evtType, handler, { passive: true });
                        }
                        else {
                            (_a = this._buttonElement) === null || _a === void 0 ? void 0 : _a.addEventListener(evtType, handler, { passive: true });
                        }
                    }, deregisterInteractionHandler: (evtType, handler) => {
                        var _a;
                        if (this._isRootEvent(evtType)) {
                            this._rootElement.removeEventListener(evtType, handler, { passive: true });
                        }
                        else {
                            (_a = this._buttonElement) === null || _a === void 0 ? void 0 : _a.removeEventListener(evtType, handler, { passive: true });
                        }
                    }, addClass: (className) => addClass(className, this._rootElement), removeClass: (className) => removeClass(className, this._rootElement), updateCssVariable: (varName, value) => this._rootElement.style.setProperty(varName, value) });
                this._rippleInstance = new ForgeRipple(this._rootElement, new ForgeRippleFoundation(adapter));
                if (type === 'focusin') {
                    this._rippleInstance.handleFocus();
                }
            }
        }
        else {
            this._rippleInstance.destroy();
            this._rippleInstance = undefined;
        }
    }
    _isRootEvent(evtType) {
        return ['touchstart', 'pointerdown', 'mousedown'].includes(evtType);
    }
}
