/* *
 *
 *  Grid Context Menu Button class
 *
 *  (c) 2020-2026 Highsoft AS
 *
 *  Integration of this software requires a license.
 *  - For commercial use, see www.highcharts.com/license
 *  - For non-commercial, see www.highcharts.com/license-eula
 *
 *
 *  Authors:
 *  - Dawid Draguła
 *
 * */
'use strict';
import { createGridIcon } from './SvgIcons.js';
import Globals from '../Globals.js';
import GridUtils from '../GridUtils.js';
const { makeHTMLElement } = GridUtils;
/* *
 *
 *  Class
 *
 * */
export class ContextMenuButton {
    /* *
     *
     *  Constructor
     *
     * */
    constructor(options) {
        /**
         * Used to remove the event listeners when the button is destroyed.
         */
        this.eventListenerDestroyers = [];
        /**
         * Whether the button is active.
         */
        this.isActive = false;
        this.options = options;
    }
    /* *
     *
     *  Methods
     *
     * */
    /**
     * Adds the button to the context menu.
     *
     * @param contextMenu
     * The context menu to add the button to.
     */
    add(contextMenu) {
        const cfg = this.options;
        this.contextMenu = contextMenu;
        contextMenu.buttons.push(this);
        const container = contextMenu.ensureItemsContainer();
        if (!container) {
            return;
        }
        const liEl = this.wrapper = makeHTMLElement('li', cfg.classNameKey && {
            className: Globals.getClassName(cfg.classNameKey)
        }, container);
        const buttonEl = this.buttonEl = makeHTMLElement('button', {
            className: Globals.getClassName('menuItem')
        }, liEl);
        const iconEl = this.iconWrapper = makeHTMLElement('span', {
            className: Globals.getClassName('menuItemIcon')
        }, buttonEl);
        this.spanEl = makeHTMLElement('span', {
            className: Globals.getClassName('menuItemLabel'),
            innerText: cfg.label || ''
        }, buttonEl);
        const chevronEl = makeHTMLElement('span', {
            className: Globals.getClassName('menuItemIcon')
        }, buttonEl);
        iconEl.setAttribute('aria-hidden', 'true');
        chevronEl.setAttribute('aria-hidden', 'true');
        buttonEl.setAttribute('type', 'button');
        buttonEl.setAttribute('tabindex', '-1');
        this.refreshState();
        if (cfg.chevron) {
            const grid = this.contextMenu?.grid;
            chevronEl.appendChild(createGridIcon('chevronRight', grid?.options?.rendering?.icons));
        }
        if (cfg.icon) {
            this.setIcon(cfg.icon);
        }
        this.addEventListeners();
        return this;
    }
    focus(options) {
        this.buttonEl?.focus(options);
        const cm = this.contextMenu;
        if (cm) {
            cm.focusCursor = cm.buttons.indexOf(this);
        }
    }
    /**
     * Triggers button click programmatically.
     */
    click() {
        this.buttonEl?.click();
    }
    setLabel(label) {
        if (this.spanEl) {
            this.spanEl.innerText = label;
        }
    }
    /**
     * Sets the icon for the button.
     *
     * @param icon
     * The icon to set (built-in name or custom name from rendering.icons).
     */
    setIcon(icon) {
        this.icon?.remove();
        if (!icon) {
            return;
        }
        const grid = this.contextMenu?.grid;
        this.icon = createGridIcon(icon, grid?.options?.rendering?.icons);
        this.iconWrapper?.appendChild(this.icon);
    }
    setActive(active) {
        this.isActive = active;
        this.buttonEl?.classList.toggle('active', active);
        const { activeIcon, icon } = this.options;
        if (activeIcon) {
            this.setIcon(active ? activeIcon : icon);
        }
    }
    setHighlighted(highlighted) {
        this.buttonEl?.classList.toggle('highlighted', highlighted);
    }
    /**
     * Destroys the button.
     */
    destroy() {
        this.popup?.hide();
        this.removeEventListeners();
        this.wrapper?.remove();
        // Unregister from the context menu
        const cm = this.contextMenu;
        if (cm) {
            const buttonIndex = cm.buttons.indexOf(this);
            if (buttonIndex !== -1) {
                cm.buttons.splice(buttonIndex, 1);
            }
            delete this.contextMenu;
        }
    }
    /**
     * Initializes the state of the button.
     */
    refreshState() {
        // Do nothing, to be overridden by subclasses
    }
    /**
     * Handles the click event for the button.
     *
     * @param event
     * The mouse event.
     */
    clickHandler(event) {
        this.options.onClick?.(event, this);
    }
    /**
     * Adds event listeners to the button.
     */
    addEventListeners() {
        const clickListener = (event) => {
            this.clickHandler(event);
        };
        this.buttonEl?.addEventListener('click', clickListener);
        this.eventListenerDestroyers.push(() => {
            this.buttonEl?.removeEventListener('click', clickListener);
        });
    }
    /**
     * Removes event listeners from the button.
     */
    removeEventListeners() {
        for (const destroyer of this.eventListenerDestroyers) {
            destroyer();
        }
        this.eventListenerDestroyers.length = 0;
    }
}
/* *
 *
 *  Default Export
 *
 * */
export default ContextMenuButton;
