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

/**
 * @fileOverview Navigation Controller for the Navigation Sample Application.
 *
 * Provides functionality for testing cross-application navigation including:
 * - Intent generation with semantic object, action, and parameters
 * - AppState embedding in navigation parameters
 * - Navigation preview and execution
 *
 * @since 1.147
 */
sap.ui.define([
    "sap/base/Log",
    "sap/m/Popover",
    "sap/m/MessageStrip",
    "sap/ui/core/mvc/Controller",
    "sap/ui/model/json/JSONModel",
    "sap/ushell/Container"
], (
    Log,
    Popover,
    MessageStrip,
    Controller,
    JSONModel,
    Container
) => {
    "use strict";

    /**
     * Navigation controller for testing FLP cross-application navigation.
     *
     * @class
     * @extends sap.ui.core.mvc.Controller
     * @alias sap.ushell.sandbox.NavigationSample.controller.Navigation
     * @since 1.147
     * @private
     */
    return Controller.extend("sap.ushell.sandbox.NavigationSample.controller.Navigation", {

        /**
         * Initializes the view model for navigation parameters.
         *
         * @private
         */
        onInit: function () {
            this.oViewModel = new JSONModel();
            this.getView().setModel(this.oViewModel, "navigationView");
        },

        /**
         * Generates navigation arguments from the view model.
         *
         * @param {sap.ui.model.json.JSONModel} oViewModel The view model containing navigation parameters
         * @returns {{target: {semanticObject: string, action: string}, params: object}} Navigation arguments
         * @private
         */
        _generateArguments: function (oViewModel) {
            const semanticObject = oViewModel.getProperty("/semanticObject");
            const action = oViewModel.getProperty("/action");
            const params = [...new URLSearchParams(oViewModel.getProperty("/params"))].reduce((accParams, [key, value]) => {
                accParams[key] = value;
                return accParams;
            }, {});

            const sAppStateJson = oViewModel.getProperty("/appStateJson");
            if (sAppStateJson) {
                params["sap-xapp-state-data"] = JSON.stringify(JSON.parse(sAppStateJson));
            }

            return {
                target: { semanticObject, action },
                params
            };
        },

        /**
         * Opens an informational Popover next to the triggering control.
         *
         * @param {sap.ui.base.Event} oEvent - Press event from the triggering control
         * @private
         */
        onInfoPress: async function (oEvent) {
            const sKey = oEvent.getSource().data("infoKey");
            const oBundle = await this.getView().getModel("i18n").getResourceBundle();
            const sText = oBundle.getText(sKey);
            if (!this._infoPopover) {
                this._infoPopover = new Popover({
                    showHeader: false,
                    content: [
                        new MessageStrip({
                            type: "Information",
                            showCloseButton: false
                        })
                    ]
                });
                this.getView().addDependent(this._infoPopover);
            }
            this._infoPopover.getContent()[0].setText(sText);
            this._infoPopover.openBy(oEvent.getSource());
        },

        /**
         * Copies the intent preview to the clipboard.
         *
         * @private
         */
        onCopyPreview: async function () {
            try {
                await navigator.clipboard.writeText(this.oViewModel.getProperty("/intentPreview"));
            } catch (error) {
                Log.error(error.message);
            }
        },

        /**
         * Updates the intent preview based on current navigation parameters.
         *
         * @private
         */
        updateIntentPreview: function () {
            Container.getServiceAsync("Navigation").then(async (oNavService) => {
                const sIntent = await oNavService.getHref(this._generateArguments(this.oViewModel));
                this.oViewModel.setProperty("/intentPreview", sIntent);
            });
        },

        /**
         * Executes the navigation with current parameters.
         *
         * @private
         */
        onNavigatePress: function () {
            Container.getServiceAsync("Navigation").then((oNavService) => {
                oNavService.navigate(this._generateArguments(this.oViewModel));
            });
        }
    });
});
