import React from "react";
import AppDefinition from "./AppDefinition";
import NoAppsFound from "./NoAppsFound";
import FilterSort from "./FilterSort";
import { getStore } from "../stores/LauncherStore";
import storeActions from "../stores/StoreActions";
import sortFunctions from "../utils/sort-functions";
import { FEAGlobals } from "../../../../../../common/Globals";
const ADVANCED_APP_LAUNCHER = "Advanced App Launcher";
window.storeActions = storeActions;
// To be assigned a value later in the constructor
let store;
export default class Content extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            apps: storeActions.getApps(),
            tags: storeActions.getTags(),
            sortBy: storeActions.getSortBy(),
            filterText: storeActions.getSearchText().toLowerCase(),
            folder: storeActions.getActiveFolder(),
        };
        this.onSort = this.onSort.bind(this);
        this.onSearch = this.onSearch.bind(this);
        this.onTagsUpdate = this.onTagsUpdate.bind(this);
        this.onActiveFolderChanged = this.onActiveFolderChanged.bind(this);
        this.onAppListUpdate = this.onAppListUpdate.bind(this);
        this.onAppLauncherUpdate = this.onAppLauncherUpdate.bind(this);
        this.updateAppDefinitions = this.updateAppDefinitions.bind(this);
        store = getStore();
    }
    _setFolderState() {
        this.setState({
            folder: storeActions.getActiveFolder(),
        });
    }
    filterApps() {
        const { folder } = this.state;
        let apps = folder.name === ADVANCED_APP_LAUNCHER ? Object.values(storeActions.getAllApps()) : folder.apps;
        if (!folder || !apps) {
            return [];
        }
        const sortFunc = sortFunctions[this.state.sortBy];
        const filteredApps = this.filterAppsByTags(sortFunc(apps));
        if (!this.state.filterText) {
            return filteredApps;
        }
        return filteredApps.filter(({ displayName, name }) => {
            var _a;
            return (_a = displayName === null || displayName === void 0 ? void 0 : displayName.toLowerCase().includes(this.state.filterText.toLowerCase())) !== null && _a !== void 0 ? _a : name === null || name === void 0 ? void 0 : name.toLowerCase().includes(this.state.filterText.toLowerCase());
        });
    }
    filterAppsByTags(apps) {
        if (!this.state.tags) {
            return apps;
        }
        //All active tags must be present in an app for it to show
        return apps.filter((app) => {
            var _a;
            for (let i = 0; i < this.state.tags.length; i++) {
                let tag = this.state.tags[i];
                if (!((_a = app.tags) === null || _a === void 0 ? void 0 : _a.includes(tag))) {
                    return false;
                }
            }
            return true;
        });
    }
    onActiveFolderChanged() {
        // Quick fix for release 6.3.0
        // There are 2 listeners for "activeFolder". One in this file, the other is in packages\ui\src\components\toolbar\advancedAppLauncher\stores\StoreActions.ts
        // The first listener is invoked earlier with nonupdated 'activeFolder' value in the storeActions. So I use a timeout to change this.
        // Otherwise, for correct re-rendering, we need to do double-click on the left folders panel.
        setTimeout(() => {
            this._setFolderState();
        }, 50);
    }
    onSearch(error, data) {
        this.setState({
            filterText: data.value,
        });
    }
    onSort(error, data) {
        this.setState({
            sortBy: data.value,
        });
    }
    onTagsUpdate(error, data) {
        this.setState({
            tags: data.value,
        });
    }
    /**
     * Mainly used to know when a user remove an app from a folder
     * Because there is no way to subscribe to
     * folders[index].appDefinitions updates.
     */
    onAppListUpdate() {
        this._setFolderState();
    }
    onAppLauncherUpdate() {
        this.setState({
            apps: storeActions.getApps(),
        });
    }
    updateAppDefinitions(err, response) {
        FEAGlobals.FSBL.Clients.Logger.system.debug("list updated", err, response);
        if (err) {
            return console.error(err);
        }
        storeActions.refreshAppDefinitions(response.data.componentList);
        this.onAppListUpdate();
    }
    componentDidMount() {
        //this.setStateValues();
        store === null || store === void 0 ? void 0 : store.addListener({ field: "activeFolder" }, this.onActiveFolderChanged);
        store === null || store === void 0 ? void 0 : store.addListener({ field: "filterText" }, this.onSearch);
        store === null || store === void 0 ? void 0 : store.addListener({ field: "sortBy" }, this.onSort);
        store === null || store === void 0 ? void 0 : store.addListener({ field: "activeLauncherTags" }, this.onTagsUpdate);
        // We can't subscribe to folders[index].appDefinitions
        // So we are looking at appFolders.folders update
        // Since that update is done After removing an app of definitions
        store === null || store === void 0 ? void 0 : store.addListener({ field: "appFolders.folders" }, this.onAppListUpdate);
        store === null || store === void 0 ? void 0 : store.addListener({ field: "appDefinitions" }, this.onAppLauncherUpdate);
        this.routerSubscription = FEAGlobals.FSBL.Clients.RouterClient.subscribe("Launcher.update", this.updateAppDefinitions);
    }
    componentWillUnmount() {
        store === null || store === void 0 ? void 0 : store.removeListener({ field: "activeFolder" }, this.onActiveFolderChanged);
        store === null || store === void 0 ? void 0 : store.removeListener({ field: "filterText" }, this.onSearch);
        store === null || store === void 0 ? void 0 : store.removeListener({ field: "sortBy" }, this.onSort);
        store === null || store === void 0 ? void 0 : store.removeListener({ field: "activeLauncherTags" }, this.onTagsUpdate);
        store === null || store === void 0 ? void 0 : store.removeListener({ field: "appFolders.folders" }, this.onAppListUpdate);
        store === null || store === void 0 ? void 0 : store.removeListener({ field: "appDefinitions" }, this.onAppLauncherUpdate);
        FEAGlobals.FSBL.Clients.RouterClient.unsubscribe(this.routerSubscription.subscribeID);
    }
    renderAppList() {
        return this.filterApps().map((app, index) => React.createElement(AppDefinition, { app: app, folder: this.state.folder, key: index }));
    }
    getNoResultsMessage() {
        const messages = {
            search: ["No results found. Please try again."],
            Favorites: ["There’s nothing here!", React.createElement("br", { key: 1 }), "Add apps to Favorites to view them here."],
            //Dashboards: ['There’s nothing here!', <br />, 'Press “New Dashboard” to construct an Dashboard.'],
            default: ["There’s nothing here!", React.createElement("br", { key: 2 }), "Add apps to folders to view them here."],
        };
        if (!this.state.folder) {
            return ["Loading data...", React.createElement("br", { key: 3 })];
        }
        // User is searching so we need the search message
        if (this.state.filterText || this.state.tags.length) {
            return messages.search;
        }
        // Now let's check which folder is currently active
        switch (this.state.folder.name) {
            case "Favorites":
                return messages.Favorites;
                break;
            case "Dashboards":
                return [""];
            // return messages.Dashboards;
            default:
                return messages.default;
        }
    }
    render() {
        const apps = this.renderAppList();
        return (React.createElement("div", { className: "complex-menu-content-row" },
            React.createElement(FilterSort, null),
            React.createElement("div", { className: "item-wrapper" }, apps.length ? apps : React.createElement(NoAppsFound, { message: this.getNoResultsMessage() }))));
    }
}
//# sourceMappingURL=Content.js.map