/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { getShadowElement, isString, removeAllChildren, removeClass, removeElement, toggleElementPlaceholder } from '@tylertech/forge-core';
import { BaseAdapter } from '../core/base/base-adapter';
import { TOAST_CONSTANTS } from './toast-constants';
/**
 * The DOM adapter for the `ToastComponent` web component.
 */
export class ToastAdapter extends BaseAdapter {
    constructor(component) {
        super(component);
        this._containerElement = getShadowElement(component, TOAST_CONSTANTS.selectors.CONTAINER);
        this._messageElement = getShadowElement(component, TOAST_CONSTANTS.selectors.MESSAGE);
        this._actionButtonElement = getShadowElement(component, TOAST_CONSTANTS.selectors.ACTION_BUTTON);
        this._closeButtonElement = getShadowElement(component, TOAST_CONSTANTS.selectors.CLOSE_BUTTON);
    }
    /**
     * Sets an attrinbute on the host element.
     * @param name The attribute name.
     * @param value The attribute value.
     */
    setHostAttribute(name, value) {
        if (this._component.getAttribute(name) !== value) {
            this._component.setAttribute(name, value);
        }
    }
    /**
     * Sets the message text on the toast element.
     * @param value The message text.
     */
    setMessage(value) {
        this._messageElement.innerText = value;
    }
    /**
     * Sets a custom template on the message element.
     * @param tpl The message template.
     */
    setMessageTemplate(tpl) {
        this._containerElement.classList.add(TOAST_CONSTANTS.classes.CUSTOM);
        if (isString(tpl)) {
            this._component.innerHTML = tpl;
        }
        else {
            removeAllChildren(this._messageElement);
            this._component.appendChild(tpl);
        }
    }
    /**
     * Toggles the visibility of the action button element.
     * @param isVisible The visibility.
     */
    setActionVisibility(isVisible) {
        this._actionButtonPlaceholder = toggleElementPlaceholder(this._component, isVisible, TOAST_CONSTANTS.elementName, TOAST_CONSTANTS.selectors.ACTION_BUTTON, this._actionButtonElement, this._actionButtonPlaceholder);
    }
    /**
     * Sets the action button text.
     * @param message The message text.
     */
    setActionText(message) {
        this._actionButtonElement.innerText = message;
    }
    /**
     * Adds an event listener to the action button element.
     * @param type The event type.
     * @param listener The event listener.
     */
    registerActionListener(type, listener) {
        this._actionButtonElement.addEventListener(type, listener);
    }
    /**
     * Removes an event listener from the action button.
     * @param type The event type.
     * @param listener The event listener.
     */
    deregisterActionListener(type, listener) {
        this._actionButtonElement.removeEventListener(type, listener);
    }
    /**
     * Adjusts the class applied to the toast container to position it properly.
     * @param placement The screen placement position.
     */
    setPlacement(placement) {
        removeClass([
            TOAST_CONSTANTS.classes.TOP,
            TOAST_CONSTANTS.classes.TOP_LEFT,
            TOAST_CONSTANTS.classes.TOP_RIGHT,
            TOAST_CONSTANTS.classes.BOTTOM,
            TOAST_CONSTANTS.classes.BOTTOM_LEFT,
            TOAST_CONSTANTS.classes.BOTTOM_RIGHT
        ], this._containerElement);
        const placementClass = this._getPlacementClass(placement);
        if (placementClass) {
            this._containerElement.classList.add(placementClass);
        }
    }
    /**
     * Triggers the addition of classes to the container element to hide or show the toast using CSS transitions.
     * @param isActive Active or not.
     */
    setActive(isActive) {
        if (isActive) {
            // We need to force a reflow here to make sure that our new transform gets applied by the active class
            window.getComputedStyle(this._containerElement).getPropertyValue('bottom');
            this._containerElement.classList.add(TOAST_CONSTANTS.classes.ACTIVE);
        }
        else {
            this._containerElement.classList.remove(TOAST_CONSTANTS.classes.ACTIVE);
            const animationCompletedListener = () => {
                this._containerElement.removeEventListener('transitionend', animationCompletedListener);
                removeElement(this._component);
            };
            this._containerElement.addEventListener('transitionend', animationCompletedListener);
        }
    }
    setCloseButtonVisibility(visible) {
        if (visible) {
            this._closeButtonElement.style.removeProperty('display');
        }
        else {
            this._closeButtonElement.style.display = 'none';
        }
    }
    registerCloseListener(listener) {
        this._closeButtonElement.addEventListener('click', listener);
    }
    _getPlacementClass(placement) {
        switch (placement) {
            case 'top':
                return TOAST_CONSTANTS.classes.TOP;
            case 'top-start':
                return TOAST_CONSTANTS.classes.TOP_LEFT;
            case 'top-end':
                return TOAST_CONSTANTS.classes.TOP_RIGHT;
            case 'bottom':
                return TOAST_CONSTANTS.classes.BOTTOM;
            case 'bottom-start':
                return TOAST_CONSTANTS.classes.BOTTOM_LEFT;
            case 'bottom-end':
                return TOAST_CONSTANTS.classes.BOTTOM_RIGHT;
        }
        return null;
    }
}
