// Copyright (c) 2009-2026 SAP SE, All Rights Reserved

sap.ui.define([
    "sap/ui/core/Element",
    "sap/ushell/modules/BaseAPI",
    "sap/ushell/state/StateManager"
], (
    Element,
    BaseAPI,
    StateManager
) => {
    "use strict";

    // shortcut for sap.ushell.state.StateManager.Operation
    const Operation = StateManager.Operation;

    /**
     * @alias sap.ushell.modules.ProductSwitch.ProductSwitchAPI
     * @namespace
     * @description The API object for the ProductSwitch module.
     * This module cannot be required it gets injected in the constructor of the ProductSwitch module.
     * @see sap.ushell.modules.ProductSwitch.ProductSwitch
     *
     * @hideconstructor
     *
     * @since 1.144.0
     * @private
     * @ui5-restricted CEP
     */
    class ProductSwitchAPI extends BaseAPI {
        /**
         * The instance of the ShellBar or ShellHeader depending on the ushell Config.
         *
         * @type {sap.ushell.gen.ui5.webcomponents-fiori.dist.ShellBar|sap.ushell.ui.ShellHeader}
         * @since 1.144.0
         * @private
         */
        #oShellBar;

        /**
         * Creates a new instance of the ProductSwitchAPI.
         *
         * @param {object} oConfig The configuration object for the product switch module.
         * @since 1.144.0
         * @private
         * @ui5-restricted CEP
         */
        constructor (oConfig) {
            super(oConfig);
            this.#oShellBar = Element.getElementById("shell-header")?.getComponentInstance?.()?.getRootControl()?.byId("shellBar");
            if (!this.#oShellBar) {
                // use the ShellHeader for compatibility reasons
                this.#oShellBar = Element.getElementById("shell-header");
            }
        }

        /**
         * Gets the product switch button by ID as it would be expected in the ShellHeader.
         * In case the ShellBar is used this method returns undefined as the button is not available.
         *
         * @returns {sap.ushell.ui.shell.ShellHeadItem|undefined} The product switch button or undefined if not available.
         * @since 1.144.0
         * @private
         */
        #getShellHeaderProductSwitchButton () {
            if (this.#isShellBar()) {
                // only available in ShellHeader
                return;
            }

            return Element.getElementById("productSwitchBtn");
        }

        /**
         * Checks if the ShellBar instance is available. This is used as long as the ShellHeader may still be used.
         *
         * @returns {boolean} True if the ShellBar instance is available, false otherwise.
         * @since 1.144.0
         * @private
         */
        #isShellBar () {
            return this.#oShellBar?.isA("sap.f.gen.ui5.webcomponents_fiori.dist.ShellBar");
        }

        /**
         * Sets whether the product switch should be currently shown.
         * The actual value can differ from the set value due FLP state management.
         *
         * @param {boolean} bShow Whether to show the product switch.
         * @since 1.144.0
         * @private
         * @ui5-restricted CEP
         */
        setShowProductSwitch (bShow) {
            StateManager.updateAllBaseStates("header.productSwitch.visible", Operation.Set, bShow);
        }

        /**
         * Returns whether the product switch is currently shown.
         * The returned value can differ from last set value due FLP state management.
         *
         * @returns {boolean} Whether the product switch is shown.
         * @since 1.144.0
         * @private
         * @ui5-restricted CEP
         */
        getShowProductSwitch () {
            if (this.#isShellBar()) {
                return this.#oShellBar.getShowProductSwitch();
            }
            return this.#getShellHeaderProductSwitchButton()?.getVisible();
        }

        /**
         * Binds the the notifaction visibility to a model. The model value must be compatible with
         * the value of @see #setShowProductSwitch.
         *
         * @param {string} sPath Absolute path to the property in the model.
         * @param {sap.ui.model.Model} oModel The model to bind to.
         * @since 1.144.0
         * @private
         * @ui5-restricted CEP
         */
        bindShowProductSwitch (sPath, oModel) {
            this.bindModelProperty(sPath, oModel, "showProductSwitch", this.setShowProductSwitch.bind(this));
        }

        /**
         * Unbinds the notifaction visibility.
         *
         * @since 1.144.0
         * @private
         * @ui5-restricted CEP
         */
        unbindShowProductSwitch () {
            this.unbindModelProperty("showProductSwitch");
        }

        /**
         * Attaches a handler to the product switch press event.
         *
         * @param {object} [oData] An object that will be passed to the handler along with the event object when the event is fired
         * @param {function} fnFunction The handler function to call when the event occurs.
         * This function will be called in the context of the oListener instance (if present)
         * or on the event provider instance. The event object (@see: sap.ui.base.Event) is provided
         * as first argument of the handler. Handlers must not change the content of the event.
         * The second argument is the specified oData instance (if present).
         * @param {object} [oListener] The object that wants to be notified when the event occurs (this context within the handler function).
         *
         * @since 1.142.0
         * @private
         * @ui5-restricted CEP
         */
        attachProductSwitchPress (...args) {
            if (this.#isShellBar()) {
                this.#oShellBar.attachProductSwitchClick(...args);
            } else {
                this.#getShellHeaderProductSwitchButton()?.attachPress(...args);
            }
        }

        /**
         * Detaches a handler from the product switch press event.
         *
         * @param {function} fnFunction The handler function to detach from the event.
         * @param {object} [oListener] The object that wanted to be notified when the event occurred.
         *
         * @since 1.144.0
         * @private
         * @ui5-restricted CEP
         */
        detachProductSwitchPress (...args) {
            if (this.#isShellBar()) {
                this.#oShellBar.detachProductSwitchClick(...args);
            } else {
                this.#getShellHeaderProductSwitchButton()?.detachPress(...args);
            }
        }

        /**
         * Gets the DOM reference for the product switch area.
         *
         * @returns {Element} The DOM reference.
         * @since 1.144.0
         * @private
         * @ui5-restricted CEP
         */
        getProductSwitchDomRef () {
            if (this.#isShellBar()) {
                return this.#oShellBar.getProductSwitchDomRef();
            }
            return this.#getShellHeaderProductSwitchButton()?.getDomRef();
        }
    }

    return ProductSwitchAPI;
});
