import { SelectState, ToggleState, } from '@wix/bex-core';
import { action, computed, makeObservable, reaction } from 'mobx';
import { EventEmitter } from '@wix/bex-core/events';
export class DropdownSelectState {
    constructor(params) {
        this.dropdown = new ToggleState();
        this.events = new EventEmitter();
        this.toKeyedItem = (item, index) => {
            const { filter } = this;
            const key = filter.itemKey(item);
            return {
                id: key,
                key,
                item,
                index,
                indexWithinPage: index,
                pageIndex: 0,
            };
        };
        this.container = params.container;
        this.toolbar = params.toolbar;
        this.select =
            params.select ??
                new SelectState({
                    keyGetter: (value) => value.key,
                });
        this._filter = params.filter;
        makeObservable(this, {
            filterKeyedItems: computed,
            filterKeyedItemsMap: computed,
            finalFilterKeyedItems: computed,
            finalFilterKeyedItemsMap: computed,
            selectedItems: computed({
                keepAlive: true,
            }),
            set: action,
            delete: action,
            deleteKey: action,
            init: action.bound,
            open: action.bound,
            clear: action.bound,
            syncSelectedItems: action.bound,
            syncSelectedItemsIfChanged: action.bound,
        });
        this.syncSelectedItems();
    }
    get filterKeyedItemsMap() {
        return new Map(this.filterKeyedItems.map((e) => [e.key, e]));
    }
    get filter() {
        return this.toolbar.getPendingFilter(this._filter);
    }
    get hasPendingFilter() {
        return this._filter !== this.filter;
    }
    get finalFilterKeyedItems() {
        const { _filter } = this;
        return _filter.value.map(this.toKeyedItem);
    }
    get finalFilterKeyedItemsMap() {
        return new Map(this.finalFilterKeyedItems.map((e) => [e.key, e]));
    }
    get filterKeyedItems() {
        const { filter } = this;
        return filter.value.map(this.toKeyedItem);
    }
    syncSelectedItems() {
        const { select, events } = this;
        select.clear();
        select.finalizeMany(this.filterKeyedItems);
        events.emit('syncSelectedItems');
    }
    syncSelectedItemsIfChanged() {
        const { selectedItems, filter } = this;
        if (filter.value !== selectedItems) {
            this.syncSelectedItems();
        }
    }
    get selectedItems() {
        const { select } = this;
        return select.selectedValues.map(({ item }) => item);
    }
    set(item) {
        const { select } = this;
        select.set(item);
        this.refreshIfChanged({ actionType: 'add', clickedValueKey: item.key });
    }
    setSingle(item) {
        const { select } = this;
        select.clear();
        this.set(item);
    }
    clear() {
        const { select } = this;
        select.clear();
        this.refreshIfChanged({ actionType: 'remove', clickedValueKey: '' });
    }
    delete(item) {
        const { select } = this;
        select.delete(item);
        this.refreshIfChanged({ actionType: 'remove', clickedValueKey: item.key });
    }
    deleteKey(key) {
        const { select } = this;
        select.deleteKey(key);
        this.refreshIfChanged({ actionType: 'remove', clickedValueKey: key });
    }
    refreshIfChanged(options = {}) {
        const { selectedItems, filter } = this;
        if (filter == null) {
            return;
        }
        if (filter.value === selectedItems) {
            return;
        }
        filter.setValue(selectedItems, {
            emitEvents: ['change', 'beforeRefresh', 'refresh'],
            ...options,
        });
    }
    close() {
        const { dropdown, events } = this;
        dropdown.setOff();
        events.emit('close');
    }
    open() {
        const { dropdown, events } = this;
        dropdown.setOn();
        events.emit('open');
    }
    closeAndChangeSelectedItems() {
        this.close();
        const { selectedItems, filter } = this;
        if (filter.value === selectedItems) {
            return;
        }
        filter.setValue(selectedItems, {
            emitEvents: ['change', 'beforeRefresh', 'refresh'],
            actionType: 'add',
        });
    }
    init() {
        const { filter } = this;
        const disposers = [
            reaction(() => filter?.value, this.syncSelectedItemsIfChanged),
        ];
        return () => {
            disposers.forEach((d) => d());
        };
    }
}
//# sourceMappingURL=DropdownSelectState.js.map