import { MenuItemController } from '../../../menu/internal/controllers/menuItemController.js';

/**
 * @license
 * Copyright 2023 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * Creates an event fired by a SelectOption to request selection from md-select.
 * Typically fired after `selected` changes from `false` to `true`.
 */
function createRequestSelectionEvent() {
    return new Event('request-selection', {
        bubbles: true,
        composed: true,
    });
}
/**
 * Creates an event fired by a SelectOption to request deselection from
 * md-select. Typically fired after `selected` changes from `true` to `false`.
 */
function createRequestDeselectionEvent() {
    return new Event('request-deselection', {
        bubbles: true,
        composed: true,
    });
}
/**
 * A controller that provides most functionality and md-select compatibility for
 * an element that implements the SelectOption interface.
 */
class SelectOptionController {
    /**
     * The recommended role of the select option.
     */
    get role() {
        return this.menuItemController.role;
    }
    /**
     * The text that is selectable via typeahead. If not set, defaults to the
     * innerText of the item slotted into the `"headline"` slot, and if there are
     * no slotted elements into headline, then it checks the _default_ slot, and
     * then the `"supporting-text"` slot if nothing is in _default_.
     */
    get typeaheadText() {
        return this.menuItemController.typeaheadText;
    }
    setTypeaheadText(text) {
        this.menuItemController.setTypeaheadText(text);
    }
    /**
     * The text that is displayed in the select field when selected. If not set,
     * defaults to the textContent of the item slotted into the `"headline"` slot,
     * and if there are no slotted elements into headline, then it checks the
     * _default_ slot, and then the `"supporting-text"` slot if nothing is in
     * _default_.
     */
    get displayText() {
        if (this.internalDisplayText !== null) {
            return this.internalDisplayText;
        }
        return this.menuItemController.typeaheadText;
    }
    setDisplayText(text) {
        this.internalDisplayText = text;
    }
    /**
     * @param host The SelectOption in which to attach this controller to.
     * @param config The object that configures this controller's behavior.
     */
    constructor(host, config) {
        this.host = host;
        this.internalDisplayText = null;
        this.lastSelected = this.host.selected;
        this.firstUpdate = true;
        /**
         * Bind this click listener to the interactive element. Handles closing the
         * menu.
         */
        this.onClick = () => {
            this.menuItemController.onClick();
        };
        /**
         * Bind this click listener to the interactive element. Handles closing the
         * menu.
         */
        this.onKeydown = (e) => {
            this.menuItemController.onKeydown(e);
        };
        this.menuItemController = new MenuItemController(host, config);
        host.addController(this);
    }
    hostUpdate() {
        if (this.lastSelected !== this.host.selected) {
            this.host.ariaSelected = this.host.selected ? 'true' : 'false';
        }
    }
    hostUpdated() {
        // Do not dispatch event on first update / boot-up.
        if (this.lastSelected !== this.host.selected && !this.firstUpdate) {
            // This section is really useful for when the user sets selected on the
            // option programmatically. Most other cases (click and keyboard) are
            // handled by md-select because it needs to coordinate the
            // single-selection behavior.
            if (this.host.selected) {
                this.host.dispatchEvent(createRequestSelectionEvent());
            }
            else {
                this.host.dispatchEvent(createRequestDeselectionEvent());
            }
        }
        this.lastSelected = this.host.selected;
        this.firstUpdate = false;
    }
}

export { SelectOptionController, createRequestDeselectionEvent, createRequestSelectionEvent };
