/**
 * DevExtreme (esm/__internal/grids/grid_core/state_storing/m_state_storing.js)
 * Version: 23.2.6 (build 24140-0112)
 * Build date: Sun May 19 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
import {
    equalByValue,
    getKeyHash
} from "../../../../core/utils/common";
import {
    Deferred
} from "../../../../core/utils/deferred";
import {
    extend
} from "../../../../core/utils/extend";
import {
    isDefined
} from "../../../../core/utils/type";
import {
    StateStoringController
} from "./m_state_storing_core";
var getDataState = that => {
    var pagerView = that.getView("pagerView");
    var dataController = that.getController("data");
    var state = {
        allowedPageSizes: pagerView ? pagerView.getPageSizes() : void 0,
        filterPanel: {
            filterEnabled: that.option("filterPanel.filterEnabled")
        },
        filterValue: that.option("filterValue"),
        focusedRowKey: that.option("focusedRowEnabled") ? that.option("focusedRowKey") : void 0
    };
    return extend(state, dataController.getUserState())
};
var processLoadState = that => {
    var columnsController = that.getController("columns");
    var selectionController = that.getController("selection");
    var exportController = that.getController("export");
    var dataController = that.getController("data");
    if (columnsController) {
        columnsController.columnsChanged.add(() => {
            that.updateState({
                columns: columnsController.getUserState()
            })
        })
    }
    if (selectionController) {
        selectionController.selectionChanged.add(e => {
            that.updateState({
                selectedRowKeys: e.selectedRowKeys,
                selectionFilter: e.selectionFilter
            })
        })
    }
    if (dataController) {
        that._initialPageSize = that.option("paging.pageSize");
        that._initialFilterValue = that.option("filterValue");
        dataController.changed.add(() => {
            var state = getDataState(that);
            that.updateState(state)
        })
    }
    if (exportController) {
        exportController.selectionOnlyChanged.add(() => {
            that.updateState({
                exportSelectionOnly: exportController.selectionOnly()
            })
        })
    }
};
var DEFAULT_FILTER_VALUE = null;
var getFilterValue = (that, state) => {
    var filterSyncController = that.getController("filterSync");
    var columnsController = that.getController("columns");
    var hasFilterState = state.columns || void 0 !== state.filterValue;
    if (filterSyncController) {
        if (hasFilterState) {
            return state.filterValue || filterSyncController.getFilterValueFromColumns(state.columns)
        }
        return that._initialFilterValue || filterSyncController.getFilterValueFromColumns(columnsController.getColumns())
    }
    return DEFAULT_FILTER_VALUE
};
var rowsView = Base => class extends Base {
    init() {
        super.init();
        this._dataController.stateLoaded.add(() => {
            if (this._dataController.isLoaded() && !this._dataController.getDataSource()) {
                this.setLoading(false);
                this.renderNoDataText();
                var columnHeadersView = this.component.getView("columnHeadersView");
                columnHeadersView && columnHeadersView.render();
                this.component._fireContentReadyAction()
            }
        })
    }
};
var stateStoring = Base => class extends Base {
    init() {
        super.init.apply(this, arguments);
        processLoadState(this);
        return this
    }
    isLoading() {
        return super.isLoading() || this.getDataController().isStateLoading()
    }
    state(state) {
        var result = super.state.apply(this, arguments);
        if (void 0 !== state) {
            this.applyState(extend(true, {}, state))
        }
        return result
    }
    updateState(state) {
        if (this.isEnabled()) {
            var oldState = this.state();
            var newState = extend({}, oldState, state);
            var oldStateHash = getKeyHash(oldState);
            var newStateHash = getKeyHash(newState);
            if (!equalByValue(oldStateHash, newStateHash)) {
                state = extend(true, {}, state);
                extend(this._state, state);
                this.save()
            }
        } else {
            extend(this._state, state)
        }
    }
    applyState(state) {
        var _a;
        var {
            allowedPageSizes: allowedPageSizes
        } = state;
        var {
            searchText: searchText
        } = state;
        var {
            selectedRowKeys: selectedRowKeys
        } = state;
        var {
            selectionFilter: selectionFilter
        } = state;
        var scrollingMode = this.option("scrolling.mode");
        var isVirtualScrollingMode = "virtual" === scrollingMode || "infinite" === scrollingMode;
        var showPageSizeSelector = true === this.option("pager.visible") && this.option("pager.showPageSizeSelector");
        var hasHeight = null === (_a = this.getView("rowsView")) || void 0 === _a ? void 0 : _a.hasHeight();
        this.component.beginUpdate();
        if (this.getColumnsController()) {
            this.getColumnsController().setUserState(state.columns)
        }
        if (this.getExportController()) {
            this.getExportController().selectionOnly(state.exportSelectionOnly)
        }
        if (!this.option("selection.deferred")) {
            this.option("selectedRowKeys", selectedRowKeys || [])
        }
        this.option("selectionFilter", selectionFilter);
        if (allowedPageSizes && "auto" === this.option("pager.allowedPageSizes")) {
            this.option("pager").allowedPageSizes = allowedPageSizes
        }
        if (this.option("focusedRowEnabled")) {
            this.option("focusedRowIndex", -1);
            this.option("focusedRowKey", state.focusedRowKey || null)
        }
        this.component.endUpdate();
        this.option("searchPanel.text", searchText || "");
        this.option("filterValue", getFilterValue(this, state));
        this.option("filterPanel.filterEnabled", state.filterPanel ? state.filterPanel.filterEnabled : true);
        this.option("paging.pageIndex", (!isVirtualScrollingMode || hasHeight) && state.pageIndex || 0);
        this.option("paging.pageSize", (!isVirtualScrollingMode || showPageSizeSelector) && isDefined(state.pageSize) ? state.pageSize : this._initialPageSize);
        this.getDataController() && this.getDataController().reset()
    }
};
var columns = Base => class extends Base {
    _shouldReturnVisibleColumns() {
        var result = super._shouldReturnVisibleColumns.apply(this, arguments);
        return result && (!this._stateStoringController.isEnabled() || this._stateStoringController.isLoaded())
    }
};
var data = Base => class extends Base {
    dispose() {
        clearTimeout(this._restoreStateTimeoutID);
        super.dispose()
    }
    callbackNames() {
        return super.callbackNames().concat(["stateLoaded"])
    }
    _refreshDataSource() {
        if (this._stateStoringController.isEnabled() && !this._stateStoringController.isLoaded()) {
            clearTimeout(this._restoreStateTimeoutID);
            var deferred = new Deferred;
            this._restoreStateTimeoutID = setTimeout(() => {
                this._stateStoringController.load().always(() => {
                    this._restoreStateTimeoutID = null
                }).done(() => {
                    super._refreshDataSource();
                    this.stateLoaded.fire();
                    deferred.resolve()
                }).fail(error => {
                    this.stateLoaded.fire();
                    this._handleLoadError(error || "Unknown error");
                    deferred.reject()
                })
            });
            return deferred.promise()
        }
        if (!this.isStateLoading()) {
            super._refreshDataSource()
        }
    }
    isLoading() {
        return super.isLoading() || this._stateStoringController.isLoading()
    }
    isStateLoading() {
        return isDefined(this._restoreStateTimeoutID)
    }
    isLoaded() {
        return super.isLoaded() && !this.isStateLoading()
    }
};
var selection = Base => class extends Base {
    _fireSelectionChanged(options) {
        var isDeferredSelection = this.option("selection.deferred");
        if (this._stateStoringController.isLoading() && isDeferredSelection) {
            return
        }
        super._fireSelectionChanged.apply(this, arguments)
    }
};
export var stateStoringModule = {
    defaultOptions: () => ({
        stateStoring: {
            enabled: false,
            storageKey: null,
            type: "localStorage",
            customLoad: null,
            customSave: null,
            savingTimeout: 2e3
        }
    }),
    controllers: {
        stateStoring: StateStoringController
    },
    extenders: {
        views: {
            rowsView: rowsView
        },
        controllers: {
            stateStoring: stateStoring,
            columns: columns,
            data: data,
            selection: selection
        }
    }
};
