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

/**
 * @fileOverview Provides control sap.ushell.ui.footerbar.AddBookmarkButton.
 * @deprecated As of version 1.136.
 */
sap.ui.define([
    "sap/base/Log",
    "sap/m/Button",
    "sap/m/ButtonRenderer",
    "sap/m/Dialog",
    "sap/m/library",
    "sap/ui/core/library",
    "sap/ui/core/mvc/View",
    "sap/ui/Device",
    "sap/ui/model/json/JSONModel",
    "sap/ushell/Config",
    "sap/ushell/library", // css style dependency
    "sap/ushell/resources",
    "sap/ushell/state/StateManager",
    "sap/ushell/utils",
    "sap/ushell/utils/DeprecationLog"
], (
    Log,
    Button,
    ButtonRenderer,
    Dialog,
    mobileLibrary,
    coreLibrary,
    View,
    Device,
    JSONModel,
    Config,
    ushellLibrary,
    ushellResources,
    StateManager,
    ushellUtils,
    DeprecationLog
) => {
    "use strict";

    // shortcut for sap.m.ButtonType
    const ButtonType = mobileLibrary.ButtonType;

    // shortcut for sap.ui.core.ValueState
    const ValueState = coreLibrary.ValueState;

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

    // shortcut for sap.ushell.state.StateManager.ShellMode
    const ShellMode = StateManager.ShellMode;
    const {
        Headerless,
        Standalone,
        Embedded,
        Merged
    } = ShellMode;

    /**
     * @alias sap.ushell.ui.footerbar.AddBookmarkButton
     * @class
     * @classdesc Enables users to save bookmark tiles in the Fiori launchpad.
     * Clicking the button opens a dialog box for saving the app state, so that the app can be launched directly in that state from the launchpad.
     *
     * @param {string} [sId] ID for the new control, generated automatically if no id is given
     * @param {object} [mSettings] Initial settings for the new control

     * @extends sap.m.Button
     *
     * @public
     * @deprecated since 1.136. Use {@link sap.ushell.ui.BookmarkDialog} instead.
     */
    const AddBookmarkButton = Button.extend("sap.ushell.ui.footerbar.AddBookmarkButton", /** @lends sap.ushell.ui.footerbar.AddBookmarkButton.prototype */{
        metadata: {
            library: "sap.ushell",
            properties: {
                /**
                 * A callback function that is called before the save-as-tile dialog is opened.
                 */
                beforePressHandler: { type: "function", group: "Misc", defaultValue: null },

                /**
                 * A callback function that is called after the save-as-tile dialog is closed.
                 */
                afterPressHandler: { type: "function", group: "Misc", defaultValue: null },

                /**
                 * Title to be displayed on the tile.
                 */
                title: { type: "string", group: "Misc", defaultValue: null },

                /**
                 * Subtitle to be displayed below the tile title.
                 */
                subtitle: { type: "string", group: "Misc", defaultValue: null },

                /**
                 * Text to be displayed at the bottom of the tile.
                 */
                info: { type: "string", group: "Misc", defaultValue: null },

                /**
                 * Icon to be displayed in the Tile.
                 */
                tileIcon: { type: "string", group: "Appearance", defaultValue: null },

                /**
                 * For dynamic tile, the unit to be displayed below the number, for example, USD.
                 */
                numberUnit: { type: "string", group: "Appearance", defaultValue: null },

                /**
                 * The keywords based on which the future tile should be indexed and filtered.
                 */
                keywords: { type: "string", group: "Misc", defaultValue: null },

                /**
                 *  The target intent or URL of the bookmark. If the target app runs in the current shell, the URL has
                 *  to be a valid intent, i.e. in the format <code>"#SO-Action?P1=a&P2=x&/route?RPV=1"</code>.
                 *  See also {@link sap.ushell.services.URLParsing#getHash}.
                 */
                customUrl: { type: "any", group: "Misc", defaultValue: null },

                /**
                 * URL of an OData service from which data for a dynamic tile should be read.
                 */
                serviceUrl: { type: "any", group: "Misc", defaultValue: null },

                /**
                 * Data source of the OData service.
                 * See same parameter of {@link sap.ushell.services.Bookmark#addBookmark} for details
                 */
                dataSource: { type: "any", group: "Misc", defaultValue: null },

                /**
                 * Number of seconds after which dynamic content is read from the data source and the display is refreshed.
                 */
                serviceRefreshInterval: { type: "string", group: "Misc", defaultValue: null },

                /**
                 * Whether to display the control for group selection in the save-as-tile dialog in launchpad homepage mode.
                 */
                showGroupSelection: { type: "boolean", group: "Misc", defaultValue: true },

                /**
                 * Whether to display the control for page selection in the save-bookmark dialog in launchpad spaces mode.
                 */
                showPageSelection: { type: "boolean", group: "Misc", defaultValue: true },

                /**
                 * An object containing properties with information about the app, e.g. serviceUrl, numberUnit, ... .
                 * @deprecated since 1.31. Use dedicated properties like afterPressHandler, beforePresshandler, customUrl, ... of the AddBookmarkButton instead.
                 */
                appData: { type: "object", group: "Misc", defaultValue: null, deprecated: true }
            }
        },
        renderer: ButtonRenderer
    });

    AddBookmarkButton.prototype.init = function () {
        DeprecationLog.logModuleDeprecation({
            module: "sap.ushell.ui.footerbar.AddBookmarkButton",
            since: "1.136",
            successor: "sap.ushell.ui.BookmarkDialog"
        });

        // call the parent sap.m.Button init method
        if (Button.prototype.init) {
            Button.prototype.init.apply(this, arguments);
        }

        this.bSpaceEnabled = Config.last("/core/spaces/enabled");
        this.bMyHomeEnabled = Config.last("/core/spaces/myHome/enabled");
        this.setIcon("sap-icon://add-favorite");
        this.bindProperty("text", { path: "i18n>addToHomePageBtn" });
        this.setEnabled(); // disables button if shell not initialized
        this.setModel(ushellResources.i18nModel, "i18n");

        this.attachPress(() => {
            const fnBeforePressCallback = this.getBeforePressHandler();
            if (fnBeforePressCallback) {
                fnBeforePressCallback();
            }

            this.showAddBookmarkDialog();
        });
    };

    AddBookmarkButton.prototype.exit = function () {
        if (this.oBookmarkDialog) {
            this.oBookmarkDialog.destroy();
            this.oBookmarkDialog = null;
        }
        this.oDialog = null;
        // call the parent sap.m.Button exit method
        if (Button.prototype.exit) {
            Button.prototype.exit.apply(this, arguments);
        }
    };

    /**
     * Opens the bookmark dialog using the BookmarkDialog managed object.
     *
     * @returns {Promise} A promise that resolves when the dialog is opened (only relevant for classic homepage mode, as in spaces mode the dialog is opened synchronously).
     * @deprecated As of version 1.136
     */
    AddBookmarkButton.prototype.showAddBookmarkDialog = async function () {
        const oAppData = this.getAppData() || {};

        // Create BookmarkDialog with current properties
        const oShowOptions = {
            title: this.getTitle() || oAppData.title,
            subtitle: this.getSubtitle() || oAppData.subtitle,
            info: this.getInfo() || oAppData.info,
            tileIcon: this.getTileIcon() || oAppData.icon,
            numberUnit: this.getNumberUnit() || oAppData.numberUnit,
            keywords: this.getKeywords() || oAppData.keywords,
            customUrl: this.getCustomUrl() || oAppData.customUrl,
            serviceUrl: this.getServiceUrl() || oAppData.serviceUrl,
            dataSource: this.getDataSource() || oAppData.dataSource,
            serviceRefreshInterval: this.getServiceRefreshInterval() || oAppData.serviceRefreshInterval
        };

        if (this.bSpaceEnabled) {
            const [BookmarkDialog] = await ushellUtils.requireAsync(["sap/ushell/ui/BookmarkDialog"]);
            oShowOptions.icon = oShowOptions.tileIcon;
            delete oShowOptions.tileIcon;
            oShowOptions.target = oShowOptions.customUrl;
            delete oShowOptions.customUrl;
            BookmarkDialog.show(oShowOptions);
        } else {
            oShowOptions.showGroupSelection = this.getShowGroupSelection();

            const oViewData = {
                serviceUrl: this.getServiceUrl() || oAppData.serviceUrl,
                customUrl: this.getCustomUrl() || oAppData.customUrl
            };
            const oViewPromise = View.create({
                viewName: "module:sap/ushell/ui/footerbar/SaveAsTile.view",
                viewData: oViewData
            });

            return oViewPromise.then((oDialogView) => {
                this.setBookmarkTileView(oDialogView);
                oDialogView.setModel(ushellResources.i18nModel, "i18n");
                return (this._openClassicDialog(oDialogView, oShowOptions));
            });
        }
    };

    /**
     * @param {object} oAppData The app data object
     * @returns {this} Returns this for method chaining
     * @deprecated since 1.31. Use dedicated properties instead.
     */
    AddBookmarkButton.prototype.setAppData = function (oAppData) {
        this.setProperty("appData", oAppData, true);
        return this;
    };
    AddBookmarkButton.prototype.setEnabled = function (bEnabled) {
        let bPersonalizationEnabled = true;
        const sCurrentLaunchpadState = StateManager.getLaunchpadState();
        const sCurrentShellMode = StateManager.getShellMode();

        if (sap.ushell.Container) {
            const bConfigPersonalization = Config.last("/core/shell/enablePersonalization");
            if (bConfigPersonalization !== undefined) {
                bPersonalizationEnabled = bConfigPersonalization;
            }

            if (!bPersonalizationEnabled && this.bSpaceEnabled && this.bMyHomeEnabled) {
                bPersonalizationEnabled = true;
            }
        }
        if (!bPersonalizationEnabled || (sCurrentLaunchpadState === LaunchpadState.App && [Headerless, Standalone, Embedded, Merged].includes(sCurrentShellMode))) {
            bEnabled = false;
        }
        if (!sap.ushell.Container) {
            if (this.getEnabled()) {
                Log.warning(
                    "Disabling 'Save as Tile' button: unified shell container not initialized",
                    null,
                    "sap.ushell.ui.footerbar.AddBookmarkButton"
                );
            }
            bEnabled = false;
        }
        Button.prototype.setEnabled.call(this, bEnabled);
        if (!bEnabled) {
            this.addStyleClass("sapUshellAddBookmarkButton");
        }
    };

    // ///////////////////////////  Needed for Classic Home Page  /////////////////////////////

    AddBookmarkButton.prototype._openClassicDialog = function (oContent, oShowOptions) {
        // Set model for dialog
        this.oModel = new JSONModel({
            title: oShowOptions.title || "",
            subtitle: oShowOptions.subtitle || "",
            info: oShowOptions.info || "",
            icon: oShowOptions.tileIcon || "",
            numberUnit: oShowOptions.numberUnit || "",
            keywords: oShowOptions.keywords || "",
            showGroupSelection: oShowOptions.showGroupSelection !== false,
            showPageSelection: oShowOptions.showPageSelection !== false,
            serviceUrl: !!oShowOptions.serviceUrl,
            numberValue: 0
        });
        oContent.setModel(this.oModel);

        // Create and open dialog
        this.oDialog = new Dialog({
            id: "bookmarkDialog",
            title: "{i18n>addToHomePageBtn}",
            contentWidth: "25rem",
            content: oContent,
            beginButton: new Button("bookmarkOkBtn", {
                text: "{i18n>saveBtn}",
                type: ButtonType.Emphasized,
                press: [this._handleOKButtonPress, this]
            }),
            endButton: new Button("bookmarkCancelBtn", {
                text: "{i18n>cancelBtn}",
                press: [this._handleCancelButtonPressClassicMode, this]
            }),
            stretch: Device.system.phone,
            horizontalScrolling: false,
            afterClose: function () {
                const fnAfterPressCallBack = this.getAfterPressHandler();
                if (fnAfterPressCallBack) {
                    fnAfterPressCallBack();
                }
                this._restoreDialogEditableValuesToDefault();
                this.oDialog.destroy();
                delete this.oDialog;
            }.bind(this)
        }).addStyleClass("sapContrastPlus");
        this.oDialog.open();
        this.oDialog.setModel(ushellResources.i18nModel, "i18n");

        return this.oDialog;
    };

    AddBookmarkButton.prototype._handleOKButtonPress = function () {
        if (this.oDialog.getBusy()) {
            return;
        }

        /**
         * @deprecated since 1.119. Deprecated without successor.
         */
        this._handleOKButtonPressClassicMode();
    };

    /**
     * @returns {Promise} A promise which resolves on success
     * @deprecated since 1.118. Deprecated without successor together with the classic homepage.
     */
    AddBookmarkButton.prototype._handleOKButtonPressClassicMode = async function () {
        const oBookmarkTileView = this.getBookmarkTileView();
        const oBookmarkTileController = oBookmarkTileView.getController();
        const oBookmarkData = oBookmarkTileController.getBookmarkTileData();

        if (!oBookmarkData.title || oBookmarkData.title.length < 1) {
            const oTitle = oBookmarkTileView.getTitleInput();
            if (oTitle) {
                oTitle.setValueState(ValueState.Error);
                oTitle.setValueStateText(ushellResources.i18n.getText("bookmarkTitleInputError"));
                throw new Error("Invalid bookmark title");
            }
        }
        this.oDialog.setBusy(true);
        this.oDialog.close(); // dialog is destroyed after closing

        const sTileGroup = oBookmarkData.group ? oBookmarkData.group.object : "";
        delete oBookmarkData.group;

        return Promise.all([
            sap.ushell.Container.getServiceAsync("BookmarkV2"),
            sap.ushell.Container.getServiceAsync("MessageInternal")
        ]).then((aResult) => {
            const oBookmarkService = aResult[0];
            const oMessageService = aResult[1];

            return oBookmarkService.addBookmark(oBookmarkData, sTileGroup)
                .then(() => {
                    oMessageService.info(ushellResources.i18n.getText("tile_created_msg"));
                })
                .catch((oError) => {
                    Log.error("Failed to add bookmark", oError, "sap.ushell.ui.footerbar.AddBookmarkButton");
                    oMessageService.error(ushellResources.i18n.getText("fail_to_add_tile_msg"));
                });
        });
    };

    /**
     * @deprecated since 1.118.
     */
    AddBookmarkButton.prototype._handleCancelButtonPressClassicMode = function () {
        this.oDialog.close();
    };

    AddBookmarkButton.prototype._restoreDialogEditableValuesToDefault = function () {
        if (this.oModel) {
            this.oModel.setProperty("/title", this.getTitle());
            this.oModel.setProperty("/subtitle", this.getSubtitle());
            this.oModel.setProperty("/info", this.getInfo());
        }
    };

    AddBookmarkButton.prototype.setBookmarkTileView = function (oView) {
        this.bookmarkTileView = oView;
    };

    AddBookmarkButton.prototype.getBookmarkTileView = function () {
        return this.bookmarkTileView;
    };

    return AddBookmarkButton;
});
