import { action, makeObservable, observable } from 'mobx';
import { addResizeObserver, isMobileDevice, } from '@wix/bex-core';
export class TabsResponsiveState {
    constructor(params) {
        // We save the badges in a Map and not in an Array because the badge is optional
        // on a per-tab basis, but we still need to know the index of each badge.
        this.badges = new Map();
        this.mode = 'tabs';
        this.panelMinWidth = 0;
        this.itemsCount = 0;
        this.itemPadding = 32;
        this.itemMaxWidth = 200;
        this.itemTextMinWidth = 48;
        this.itemBadgeMargin = 6;
        this.itemsMinWidths = [];
        this._onResize = action(() => {
            const { container } = this;
            if (process.env.NODE_ENV === 'test') {
                return;
            }
            if (!container) {
                return;
            }
            // Force dropdown mode on mobile
            if (this.isMobile) {
                this.mode = 'dropdown';
                return;
            }
            const nextPanelWidth = this.getPanelMinWidth();
            // If the measurements show 0, this means that not all elements have loaded yet,
            // so we skip such events.
            if (nextPanelWidth !== 0 && nextPanelWidth > this.panelMinWidth) {
                this.itemsMinWidths = this.getItemsMinWidth();
                this.panelMinWidth = nextPanelWidth;
            }
            // The "container" is a node that wraps both Tabs and Dropdown components (but only
            // one of them is rendered). It expands for as much space as all its elements
            // inside need and shrinks down to the smallest possible state of the elements inside.
            // Basically max-width and min-width with complications.
            //
            // Complications here are badges — they don't shrink, only tabs titles shrink.
            //
            // The state is switched when the certain container width (aka panelMinWidth) is reached.
            // It is defined as: itemsCount * (itemMinWidth + itemPadding) + all badges widths.
            // Tabs is shown when the container width is more or equal than panelMinWidth.
            // Dropdown is shown when the container width is less than panelMinWidth.
            if (this.panelMinWidth !== 0 &&
                container.clientWidth < this.panelMinWidth) {
                this.mode = 'dropdown';
            }
            else {
                this.mode = 'tabs';
            }
        });
        this.isMobile = isMobileDevice();
        this.onResizeThrottled = params.container.lodash.throttle(() => window.requestAnimationFrame(this._onResize), 300);
        makeObservable(this, {
            mode: observable.ref,
            panelMinWidth: observable.ref,
        });
    }
    getBadgesWidth() {
        return Array.from(this.badges.values()).reduce((sum, badge) => {
            return sum + badge.clientWidth + this.itemBadgeMargin;
        }, 0);
    }
    getItemsMinWidth() {
        const { itemTextMinWidth, itemBadgeMargin } = this;
        return Array.from({ length: this.itemsCount }).map((_, index) => {
            const badge = this.badges.get(index);
            const maybeBadgeWidth = badge ? badge.clientWidth + itemBadgeMargin : 0;
            return itemTextMinWidth + maybeBadgeWidth;
        });
    }
    getPanelMinWidth() {
        const { itemsCount, itemTextMinWidth, itemPadding } = this;
        const itemMinWidth = itemTextMinWidth + itemPadding;
        const badgesWidth = this.getBadgesWidth();
        return itemsCount * itemMinWidth + badgesWidth;
    }
    init({ container, itemsCount, }) {
        this.container = container;
        this.itemsCount = itemsCount;
        const disposer = addResizeObserver(container, this.onResizeThrottled);
        this.onResizeThrottled();
        return () => {
            disposer?.();
        };
    }
}
//# sourceMappingURL=TabsResponsiveState.js.map