"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get EmptyDataState () {
        return EmptyDataState;
    },
    get PLUGIN_KEY () {
        return PLUGIN_KEY;
    },
    get PLUGIN_PRIORITY () {
        return PLUGIN_PRIORITY;
    }
});
const _base = require("../base");
const _ui = require("./ui");
const _object = require("../../helpers/object");
const _constants = /*#__PURE__*/ _interop_require_wildcard(require("../../i18n/constants"));
function _check_private_redeclaration(obj, privateCollection) {
    if (privateCollection.has(obj)) {
        throw new TypeError("Cannot initialize the same private elements twice on an object");
    }
}
function _class_apply_descriptor_get(receiver, descriptor) {
    if (descriptor.get) {
        return descriptor.get.call(receiver);
    }
    return descriptor.value;
}
function _class_apply_descriptor_set(receiver, descriptor, value) {
    if (descriptor.set) {
        descriptor.set.call(receiver, value);
    } else {
        if (!descriptor.writable) {
            throw new TypeError("attempted to set read only private field");
        }
        descriptor.value = value;
    }
}
function _class_extract_field_descriptor(receiver, privateMap, action) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to " + action + " private field on non-instance");
    }
    return privateMap.get(receiver);
}
function _class_private_field_get(receiver, privateMap) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
    return _class_apply_descriptor_get(receiver, descriptor);
}
function _class_private_field_init(obj, privateMap, value) {
    _check_private_redeclaration(obj, privateMap);
    privateMap.set(obj, value);
}
function _class_private_field_set(receiver, privateMap, value) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
    _class_apply_descriptor_set(receiver, descriptor, value);
    return value;
}
function _class_private_method_get(receiver, privateSet, fn) {
    if (!privateSet.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return fn;
}
function _class_private_method_init(obj, privateSet) {
    _check_private_redeclaration(obj, privateSet);
    privateSet.add(obj);
}
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
const PLUGIN_KEY = 'emptyDataState';
const PLUGIN_PRIORITY = 370;
const SOURCE = Object.freeze({
    UNKNOWN: 'unknown',
    FILTERS: 'filters',
    LOADING: 'loading'
});
const SHORTCUTS_CONTEXT_NAME = `plugin:${PLUGIN_KEY}`;
var /**
   * Flag indicating if emptyDataState is currently visible.
   *
   * @type {boolean}
   */ _isVisible = /*#__PURE__*/ new WeakMap(), /**
   * UI instance of the emptyDataState plugin.
   *
   * @type {EmptyDataStateUI}
   */ _ui1 = /*#__PURE__*/ new WeakMap(), /**
   * MutationObserver instance for monitoring DOM changes.
   *
   * @type {MutationObserver}
   */ _observer = /*#__PURE__*/ new WeakMap(), /**
   * Flag indicating if there are filter conditions.
   *
   * @type {boolean}
   */ _hasFilterConditions = /*#__PURE__*/ new WeakMap(), /**
   * Keeps the selection state that will be restored after the overlay is closed.
   *
   * @type {SelectionState | null}
   */ _selectionState = /*#__PURE__*/ new WeakMap(), /**
   * Whether the DataProvider-driven loading branch of the overlay is active.
   *
   * @type {boolean}
   */ _loadingActive = /*#__PURE__*/ new WeakMap(), /**
   * Registers the DOM listeners.
   */ _registerEvents = /*#__PURE__*/ new WeakSet(), /**
   * Registers the mutation observers for the emptyDataState plugin.
   */ _registerObservers = /*#__PURE__*/ new WeakSet(), /**
   * Sets the loading active flag and toggles the emptyDataState.
   */ _setLoadingActive = /*#__PURE__*/ new WeakSet(), /**
   * Clears the loading active flag and hides the emptyDataState.
   */ _clearLoadingActive = /*#__PURE__*/ new WeakSet(), /**
   * Disconnects the mutation observers for the emptyDataState plugin.
   */ _disconnectObservers = /*#__PURE__*/ new WeakSet(), /**
   * Registers the focus scope for the emptyDataState plugin.
   */ _registerFocusScope = /*#__PURE__*/ new WeakSet(), /**
   * Unregisters the focus scope for the emptyDataState plugin.
   */ _unregisterFocusScope = /*#__PURE__*/ new WeakSet(), /**
   * Get the message by the source for the emptyDataState.
   *
   * @param {string} source - The source.
   * @returns {object} The message.
   */ _getMessage = /*#__PURE__*/ new WeakSet(), /**
   * Toggle visibility and content of the emptyDataState.
   *
   * Shows emptyDataState when table has no data or when all data is hidden by filters.
   * When DataProvider loading is active, the overlay can show over non-empty data.
   */ _toggleEmptyDataState = /*#__PURE__*/ new WeakSet(), /**
   * Shows the emptyDataState overlay.
   */ _show = /*#__PURE__*/ new WeakSet(), /**
   * Updates the content of the emptyDataState overlay.
   */ _update = /*#__PURE__*/ new WeakSet(), /**
   * Hides the emptyDataState overlay.
   */ _hide = /*#__PURE__*/ new WeakSet(), /**
   * Handles the mouse wheel event.
   *
   * @param {WheelEvent} event - The wheel event.
   */ _onMouseWheel = /*#__PURE__*/ new WeakSet(), /**
   * Called after the initialization of the table is completed.
   * It toggles the emptyDataState.
   */ _onAfterInit = /*#__PURE__*/ new WeakSet(), /**
   * Called after the rendering of the table is completed.
   * It updates the height and class names of the emptyDataState element.
   */ _onAfterRender = /*#__PURE__*/ new WeakSet(), /**
   * Called before the filtering of the table is completed.
   * It updates the flag indicating if there are filter conditions.
   *
   * @param {Array} conditions - The filter conditions.
   */ _onBeforeFilter = /*#__PURE__*/ new WeakSet();
class EmptyDataState extends _base.BasePlugin {
    static get PLUGIN_KEY() {
        return PLUGIN_KEY;
    }
    static get PLUGIN_PRIORITY() {
        return PLUGIN_PRIORITY;
    }
    static get DEFAULT_SETTINGS() {
        return {
            message: undefined
        };
    }
    static get SETTINGS_VALIDATORS() {
        return {
            message: (value)=>typeof value === 'string' || typeof value === 'function' || (0, _object.isObject)(value) && (typeof value?.title === 'undefined' || typeof value?.title === 'string') && (typeof value?.description === 'undefined' || typeof value?.description === 'string') && (typeof value?.buttons === 'undefined' || Array.isArray(value?.buttons) && value?.buttons.every((item)=>typeof item === 'object' && typeof item.text === 'string' && typeof item.type === 'string' && [
                        'primary',
                        'secondary'
                    ].includes(item.type) && typeof item.callback === 'function')) || value === undefined
        };
    }
    /**
   * Check if the plugin is enabled in the handsontable settings.
   *
   * @returns {boolean}
   */ isEnabled() {
        return !!this.hot.getSettings()[PLUGIN_KEY];
    }
    /**
   * Enable plugin for this Handsontable instance.
   */ enablePlugin() {
        if (this.enabled) {
            return;
        }
        if (!_class_private_field_get(this, _ui1)) {
            _class_private_field_set(this, _ui1, new _ui.EmptyDataStateUI({
                rootElement: this.hot.rootGridElement,
                rootDocument: this.hot.rootDocument
            }));
            _class_private_method_get(this, _registerFocusScope, registerFocusScope).call(this);
            _class_private_method_get(this, _registerEvents, registerEvents).call(this);
            _class_private_method_get(this, _registerObservers, registerObservers).call(this);
        }
        this.addHook('afterInit', ()=>_class_private_method_get(this, _onAfterInit, onAfterInit).call(this));
        this.addHook('afterRender', ()=>_class_private_method_get(this, _onAfterRender, onAfterRender).call(this));
        this.addHook('afterRowSequenceCacheUpdate', ()=>{
            _class_private_method_get(this, _toggleEmptyDataState, toggleEmptyDataState).call(this);
        });
        this.addHook('afterColumnSequenceCacheUpdate', ()=>{
            _class_private_method_get(this, _toggleEmptyDataState, toggleEmptyDataState).call(this);
        });
        this.addHook('beforeFilter', (conditions)=>_class_private_method_get(this, _onBeforeFilter, onBeforeFilter).call(this, conditions));
        this.addHook('beforeDataProviderFetch', (queryParameters)=>{
            if (!queryParameters.skipLoading) {
                _class_private_method_get(this, _setLoadingActive, setLoadingActive).call(this);
            }
        });
        this.addHook('afterDataProviderFetch', ()=>_class_private_method_get(this, _clearLoadingActive, clearLoadingActive).call(this));
        this.addHook('afterDataProviderFetchError', ()=>_class_private_method_get(this, _clearLoadingActive, clearLoadingActive).call(this));
        super.enablePlugin();
        _class_private_method_get(this, _toggleEmptyDataState, toggleEmptyDataState).call(this);
    }
    /**
   * Update plugin state after Handsontable settings update.
   */ updatePlugin() {
        this.disablePlugin();
        this.enablePlugin();
        _class_private_method_get(this, _update, update).call(this);
        if (this.isVisible()) {
            _class_private_field_get(this, _ui1).show();
        }
        super.updatePlugin();
    }
    /**
   * Disable plugin for this Handsontable instance.
   */ disablePlugin() {
        _class_private_field_set(this, _loadingActive, false);
        _class_private_method_get(this, _unregisterFocusScope, unregisterFocusScope).call(this);
        _class_private_method_get(this, _disconnectObservers, disconnectObservers).call(this);
        _class_private_field_get(this, _ui1).destroy();
        _class_private_field_set(this, _ui1, null);
        super.disablePlugin();
    }
    /**
   * Check if the plugin is currently visible.
   *
   * @returns {boolean}
   */ isVisible() {
        return _class_private_field_get(this, _isVisible);
    }
    /**
   * Destroy plugin instance.
   */ destroy() {
        _class_private_field_set(this, _loadingActive, false);
        _class_private_field_set(this, _isVisible, false);
        _class_private_field_get(this, _ui1)?.destroy();
        _class_private_field_set(this, _ui1, null);
        _class_private_field_set(this, _observer, null);
        _class_private_field_set(this, _hasFilterConditions, false);
        _class_private_field_set(this, _selectionState, null);
        super.destroy();
    }
    constructor(...args){
        super(...args), _class_private_method_init(this, _registerEvents), _class_private_method_init(this, _registerObservers), _class_private_method_init(this, _setLoadingActive), _class_private_method_init(this, _clearLoadingActive), _class_private_method_init(this, _disconnectObservers), _class_private_method_init(this, _registerFocusScope), _class_private_method_init(this, _unregisterFocusScope), _class_private_method_init(this, _getMessage), _class_private_method_init(this, _toggleEmptyDataState), _class_private_method_init(this, _show), _class_private_method_init(this, _update), _class_private_method_init(this, _hide), _class_private_method_init(this, _onMouseWheel), _class_private_method_init(this, _onAfterInit), _class_private_method_init(this, _onAfterRender), _class_private_method_init(this, _onBeforeFilter), _class_private_field_init(this, _isVisible, {
            writable: true,
            value: void 0
        }), _class_private_field_init(this, _ui1, {
            writable: true,
            value: void 0
        }), _class_private_field_init(this, _observer, {
            writable: true,
            value: void 0
        }), _class_private_field_init(this, _hasFilterConditions, {
            writable: true,
            value: void 0
        }), _class_private_field_init(this, _selectionState, {
            writable: true,
            value: void 0
        }), _class_private_field_init(this, _loadingActive, {
            writable: true,
            value: void 0
        }), _class_private_field_set(this, _isVisible, false), _class_private_field_set(this, _ui1, null), _class_private_field_set(this, _observer, null), _class_private_field_set(this, _hasFilterConditions, false), _class_private_field_set(this, _selectionState, null), _class_private_field_set(this, _loadingActive, false);
    }
}
function registerEvents() {
    this.eventManager.addEventListener(_class_private_field_get(this, _ui1).getElement(), 'wheel', (event)=>_class_private_method_get(this, _onMouseWheel, onMouseWheel).call(this, event));
}
function registerObservers() {
    // Observe the root element for changes and move the emptyDataState element to the correct position
    _class_private_field_set(this, _observer, new MutationObserver(()=>{
        if (!this.hot) {
            return;
        }
        const element = _class_private_field_get(this, _ui1).getElement();
        if (this.hot.rootGridElement.nextElementSibling !== element) {
            this.hot.rootGridElement.after(element);
        }
    }));
    _class_private_field_get(this, _observer).observe(this.hot.rootWrapperElement, {
        childList: true
    });
}
function setLoadingActive() {
    if (_class_private_field_get(this, _loadingActive)) {
        return;
    }
    _class_private_field_set(this, _loadingActive, true);
    _class_private_method_get(this, _toggleEmptyDataState, toggleEmptyDataState).call(this);
}
function clearLoadingActive() {
    if (!_class_private_field_get(this, _loadingActive)) {
        return;
    }
    _class_private_field_set(this, _loadingActive, false);
    _class_private_method_get(this, _hide, hide).call(this);
    _class_private_method_get(this, _toggleEmptyDataState, toggleEmptyDataState).call(this);
    this.hot.render();
}
function disconnectObservers() {
    _class_private_field_get(this, _observer).disconnect();
    _class_private_field_set(this, _observer, null);
}
function registerFocusScope() {
    this.hot.getFocusScopeManager().registerScope(PLUGIN_KEY, _class_private_field_get(this, _ui1).getElement(), {
        shortcutsContextName: SHORTCUTS_CONTEXT_NAME,
        runOnlyIf: ()=>this.isVisible(),
        onActivate: (focusSource)=>{
            const focusableElements = _class_private_field_get(this, _ui1)?.getFocusableElements();
            if (focusableElements.length > 0) {
                if (focusSource === 'tab_from_above') {
                    focusableElements.at(0).focus();
                } else if (focusSource === 'tab_from_below') {
                    focusableElements.at(-1).focus();
                }
            }
        }
    });
}
function unregisterFocusScope() {
    this.hot.getFocusScopeManager().unregisterScope(PLUGIN_KEY);
}
function getMessage(source) {
    let message;
    if (typeof this.getSetting('message') === 'function') {
        message = this.getSetting('message')(source);
    } else {
        message = this.getSetting('message');
    }
    // If the message is a string, set the title
    if (typeof message === 'string') {
        message = {
            title: message
        };
    }
    // If the message is not set, set the default message object
    if (!message?.title && !message?.description && !message?.buttons) {
        message = {};
        if (source === SOURCE.FILTERS) {
            message.title = this.hot.getTranslatedPhrase(_constants.EMPTY_DATA_STATE_TITLE_FILTERS);
            message.description = this.hot.getTranslatedPhrase(_constants.EMPTY_DATA_STATE_DESCRIPTION_FILTERS);
            message.buttons = [
                {
                    text: this.hot.getTranslatedPhrase(_constants.EMPTY_DATA_STATE_BUTTONS_FILTERS_RESET),
                    type: 'secondary',
                    callback: ()=>{
                        const filtersPlugin = this.hot.getPlugin('filters');
                        if (filtersPlugin) {
                            filtersPlugin.clearConditions();
                            filtersPlugin.filter();
                        }
                    }
                }
            ];
        } else if (source === SOURCE.LOADING) {
            message.title = this.hot.getTranslatedPhrase(_constants.EMPTY_DATA_STATE_TITLE_LOADING);
            message.description = this.hot.getTranslatedPhrase(_constants.EMPTY_DATA_STATE_DESCRIPTION_LOADING);
        } else {
            message.title = this.hot.getTranslatedPhrase(_constants.EMPTY_DATA_STATE_TITLE);
            message.description = this.hot.getTranslatedPhrase(_constants.EMPTY_DATA_STATE_DESCRIPTION);
        }
    }
    return message;
}
function toggleEmptyDataState() {
    if (!this.hot.view) {
        return;
    }
    if (_class_private_field_get(this, _loadingActive)) {
        if (_class_private_field_get(this, _isVisible)) {
            _class_private_method_get(this, _update, update).call(this);
        } else {
            _class_private_method_get(this, _show, show).call(this);
        }
        return;
    }
    if (this.hot.view.countRenderableColumns() === 0 || this.hot.view.countRenderableRows() === 0) {
        _class_private_method_get(this, _show, show).call(this);
    } else {
        _class_private_method_get(this, _hide, hide).call(this);
    }
}
function show() {
    if (_class_private_field_get(this, _isVisible)) {
        return;
    }
    this.hot.runHooks('beforeEmptyDataStateShow');
    _class_private_method_get(this, _update, update).call(this);
    _class_private_field_get(this, _ui1).show();
    _class_private_field_set(this, _isVisible, true);
    _class_private_field_set(this, _selectionState, this.hot.selection.exportSelection());
    this.hot.getFocusScopeManager().activateScope(PLUGIN_KEY);
    this.hot.runHooks('afterEmptyDataStateShow');
}
function update() {
    if (_class_private_field_get(this, _loadingActive)) {
        _class_private_field_get(this, _ui1).updateContent(_class_private_method_get(this, _getMessage, getMessage).call(this, SOURCE.LOADING), true);
    } else if (_class_private_field_get(this, _hasFilterConditions)) {
        _class_private_field_get(this, _ui1).updateContent(_class_private_method_get(this, _getMessage, getMessage).call(this, SOURCE.FILTERS), false);
    } else {
        _class_private_field_get(this, _ui1).updateContent(_class_private_method_get(this, _getMessage, getMessage).call(this, SOURCE.UNKNOWN), false);
    }
}
function hide() {
    if (!_class_private_field_get(this, _isVisible)) {
        return;
    }
    this.hot.runHooks('beforeEmptyDataStateHide');
    _class_private_field_get(this, _ui1).hide();
    _class_private_field_set(this, _isVisible, false);
    this.hot.getFocusScopeManager().deactivateScope(PLUGIN_KEY);
    if (_class_private_field_get(this, _selectionState)?.ranges.length > 0) {
        this.hot.selection.importSelection(_class_private_field_get(this, _selectionState));
        this.hot.view.render();
        _class_private_field_set(this, _selectionState, null);
    } else {
        this.hot.selectCell(0, 0, undefined, undefined, false);
    }
    this.hot.runHooks('afterEmptyDataStateHide');
}
function onMouseWheel(event) {
    const deltaX = Number.isNaN(event.deltaX) ? -1 * event.wheelDeltaX : event.deltaX;
    if (deltaX !== 0 && this.hot.view.hasHorizontalScroll() && !this.hot.view.isHorizontallyScrollableByWindow()) {
        this.hot.view.setTableScrollPosition({
            left: this.hot.view.getTableScrollPosition().left + deltaX
        });
        event.preventDefault();
    }
}
function onAfterInit() {
    _class_private_method_get(this, _toggleEmptyDataState, toggleEmptyDataState).call(this);
    this.hot.render();
}
function onAfterRender() {
    if (_class_private_field_get(this, _ui1)?.getElement() && this.isVisible() && this.hot.view) {
        _class_private_field_get(this, _ui1).updateSize(this.hot.view, _class_private_field_get(this, _loadingActive));
        _class_private_field_get(this, _ui1).updateClassNames(this.hot.view);
    }
}
function onBeforeFilter(conditions) {
    _class_private_field_set(this, _hasFilterConditions, conditions?.length > 0);
    if (this.isVisible()) {
        _class_private_method_get(this, _update, update).call(this);
    }
}
