/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { getShadowElement } from '@tylertech/forge-core';
import { BaseAdapter } from '../core';
import { isLabelAware } from './label-aware';
import { LABEL_CONSTANTS } from './label-constants';
export class LabelAdapter extends BaseAdapter {
    constructor(component) {
        super(component);
        this._targetElement = null;
        this._slotElement = getShadowElement(component, LABEL_CONSTANTS.selectors.SLOT);
    }
    destroy() {
        var _a;
        (_a = this._targetElement) === null || _a === void 0 ? void 0 : _a.labelChangedCallback(null);
        this._targetElement = null;
    }
    hasTargetElement() {
        return !!this._targetElement;
    }
    getTargetElement() {
        return this._targetElement;
    }
    setTargetElement(el) {
        if (el && this._checkLabelAwareness(el)) {
            this._targetElement = el;
            return;
        }
        this._targetElement = null;
    }
    trySetTarget(value) {
        this._targetElement = this._locateTargetElement(value);
    }
    /**
     * Calls the target's `labelClickedCallback`.
     */
    clickTarget() {
        var _a, _b;
        (_b = (_a = this._targetElement) === null || _a === void 0 ? void 0 : _a.labelClickedCallback) === null || _b === void 0 ? void 0 : _b.call(_a);
    }
    /**
     * Computes the text content of the label then passes it to the target's `labelChangedCallback`.
     */
    updateTargetLabel() {
        var _a, _b, _c;
        const value = (_b = (_a = this._component.textContent) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
        (_c = this._targetElement) === null || _c === void 0 ? void 0 : _c.labelChangedCallback(value);
    }
    addSlotChangeListener(callback) {
        this._slotElement.addEventListener('slotchange', callback);
    }
    removerSlotChangeListener(callback) {
        this._slotElement.removeEventListener('slotchange', callback);
    }
    addMutationObserver(callback) {
        this._mutationObserver = new MutationObserver(callback);
        this._mutationObserver.observe(this._component, {
            subtree: true,
            characterData: true,
            childList: true
        });
        // Run the callback once to capture the current state of the label
        callback([], this._mutationObserver);
    }
    ;
    removeMutationObserver() {
        var _a;
        (_a = this._mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
        this._mutationObserver = undefined;
    }
    /**
     * Returns `true` if the provided element is label aware, `false` otherwise. If `false` a warning
     * is logged to the console.
     */
    _checkLabelAwareness(el) {
        if (!isLabelAware(el)) {
            console.warn('Label target element is not label aware.', el);
            return false;
        }
        return true;
    }
    /**
     * Returns a label aware element queried from the provided id or a child element of the
     * component or `null` if none exists.
     */
    _locateTargetElement(id) {
        let targetEl;
        if (id) {
            const rootNode = this._component.getRootNode();
            targetEl = rootNode.querySelector(`#${id}`);
        }
        else {
            // Used for nested elements within the label component
            const selector = LABEL_CONSTANTS.labelableChildSelectors.join(',');
            targetEl = this._component.querySelector(selector);
        }
        if (targetEl && !this._checkLabelAwareness(targetEl)) {
            return null;
        }
        return targetEl;
    }
}
