var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
            t[p[i]] = s[p[i]];
    return t;
};
import { ButtonType } from '../../enums/button-type.enum';
import { QuickNavigatorType } from '../../interfaces/quick-navigator-interface';
import { getNavigatorItems } from './quick-navigator-queries';
export class EdelQuickNavigator {
    constructor() {
        this.language = 'de';
        this.onlyOrgItemTypes = true;
        this.reloadData = 0;
        this.pageSize = 20;
        this.zeroData = { title: 'No data' };
        this.current = null;
        this.navigatorItems = [];
        this.navigationStack = [];
        this.isLoading = false;
        this.reloadingNavigatorItems = false;
        this.endCursor = '';
        this.moreToLoad = false;
    }
    render() {
        if (this.navigatorItems.length === 0) {
            return (h("edel-zero-data", { title: this.zeroData.title, details: this.zeroData.details ? this.zeroData.details : '', center: this.zeroData.center ? this.zeroData.center : true, grid: this.zeroData.grid ? this.zeroData.grid : false }));
        }
        else {
            return this.renderItems(this.navigatorItems);
        }
    }
    async reloadNavigatorItems() {
        await this.componentWillLoad();
    }
    async componentWillLoad() {
        const current = this.current || { resourceId: null, navigatorType: null };
        this.isLoading = true;
        await getNavigatorItems(this.graphClient, {
            first: this.pageSize,
            previous: this.navigationStack,
            resourceId: current.resourceId,
            navigatorType: current.navigatorType,
            language: this.language
        })
            .then(res => {
            this.navigatorItems = res.data.navigatorItems.edges.map(node => (Object.assign({}, node.node)));
            this.endCursor = res.data.navigatorItems.pageInfo.endCursor
                ? res.data.navigatorItems.pageInfo.endCursor
                : '';
            this.moreToLoad = res.data.navigatorItems.pageInfo.hasNextPage
                ? res.data.navigatorItems.pageInfo.hasNextPage
                : false;
        })
            .catch()
            .then(() => (this.isLoading = false));
    }
    get enableBackIcon() {
        return !!this.current;
    }
    get title() {
        if (this.isLoading) {
            return this.current ? this.current.title : '';
        }
        if (this.current == null) {
            return `Item Types (${this.navigatorItems.length})`;
        }
        return `${this.current.title} (${this.current.count || 0})`;
    }
    async goBack() {
        this.current = this.navigationStack.pop() || null;
        await this.componentWillLoad();
    }
    renderItems(items) {
        return (h("div", { class: "quicknavigator quicknavigator--is-sidebar" },
            h("edel-quick-navigator-head", { onBack: () => this.goBack(), "enable-back-icon": this.enableBackIcon, title: this.title }),
            this.isLoading ? (h("edel-loading-spinner", null)) : (h("ul", { class: "quicknavigator-list", onScroll: (e) => this.loadMore(e) },
                items.map(item => (h("edel-quick-navigator-entry", { canNavigate: item.count !== 0, label: item.title, onNavigate: () => this.navigateToItem(item), onSelect: () => this.select(item), icon: item.icon }))),
                this.moreToLoad ? this.renderLoadMoreButton() : null))));
    }
    async loadMore(e) {
        if (!this.moreToLoad || this.reloadingNavigatorItems)
            return;
        const target = e
            ? e.target
            : this.host.getElementsByClassName('quicknavigator-list')[0];
        if (!target)
            return;
        if (target.scrollTop >= target.scrollHeight - (target.clientHeight + 20)) {
            const current = this.current || { resourceId: null, navigatorType: null };
            this.reloadingNavigatorItems = true;
            await getNavigatorItems(this.graphClient, {
                first: this.pageSize,
                after: this.endCursor,
                previous: this.navigationStack,
                resourceId: current.resourceId,
                navigatorType: current.navigatorType,
                language: this.language
            })
                .then(res => {
                this.navigatorItems = [
                    ...this.navigatorItems,
                    ...res.data.navigatorItems.edges.map(node => (Object.assign({}, node.node)))
                ];
                this.endCursor = res.data.navigatorItems.pageInfo.endCursor
                    ? res.data.navigatorItems.pageInfo.endCursor
                    : '';
                this.moreToLoad = res.data.navigatorItems.pageInfo.hasNextPage
                    ? res.data.navigatorItems.pageInfo.hasNextPage
                    : false;
            })
                .catch()
                .then(() => (this.reloadingNavigatorItems = false));
        }
    }
    renderLoadMoreButton() {
        const loadMoreButton = this.reloadingNavigatorItems ? (h("edel-loading-spinner", { withMargin: true })) : (h("edel-button", { type: ButtonType.default, full: true, plain: true, icon: "sync", onEmit: () => this.loadMore() }));
        return this.moreToLoad ? loadMoreButton : null;
    }
    async navigateToItem(item) {
        if (item.count === 0) {
            return;
        }
        if (this.current) {
            this.navigationStack.push(this.current);
        }
        const { __typename } = item, mappedItem = __rest(item, ["__typename"]);
        this.current = mappedItem;
        await this.componentWillLoad();
        this.navigated.emit(this.selectionFromNavigationEntry(item));
    }
    async select(item) {
        await this.navigateToItem(item);
        this.selected.emit(this.selectionFromNavigationEntry(item));
    }
    selectionFromNavigationEntry(item) {
        if (item.navigatorType === QuickNavigatorType.Item) {
            return {
                type: item.navigatorType,
                itemId: item.resourceId,
                title: item.title
            };
        }
        else if (item.navigatorType === QuickNavigatorType.ItemType) {
            return {
                type: item.navigatorType,
                itemTypeId: item.resourceId,
                title: item.title
            };
        }
        else {
            return {
                type: item.navigatorType,
                itemLinkId: item.resourceId,
                itemId: this.navigationStack[this.navigationStack.length - 1]
                    .resourceId,
                title: item.title
            };
        }
    }
    static get is() { return "edel-quick-navigator"; }
    static get properties() { return {
        "current": {
            "state": true
        },
        "endCursor": {
            "state": true
        },
        "graphClient": {
            "type": "Any",
            "attr": "graph-client"
        },
        "host": {
            "elementRef": true
        },
        "isLoading": {
            "state": true
        },
        "language": {
            "type": String,
            "attr": "language"
        },
        "moreToLoad": {
            "state": true
        },
        "navigationStack": {
            "state": true
        },
        "navigatorItems": {
            "state": true
        },
        "onlyOrgItemTypes": {
            "type": Boolean,
            "attr": "only-org-item-types"
        },
        "pageSize": {
            "type": Number,
            "attr": "page-size"
        },
        "reloadData": {
            "type": Number,
            "attr": "reload-data",
            "watchCallbacks": ["reloadNavigatorItems"]
        },
        "reloadingNavigatorItems": {
            "state": true
        },
        "zeroData": {
            "type": "Any",
            "attr": "zero-data"
        }
    }; }
    static get events() { return [{
            "name": "navigated",
            "method": "navigated",
            "bubbles": true,
            "cancelable": true,
            "composed": true
        }, {
            "name": "selected",
            "method": "selected",
            "bubbles": true,
            "cancelable": true,
            "composed": true
        }]; }
}
