"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const utils_1 = require("@selfcommunity/utils");
const react_2 = tslib_1.__importDefault(require("virtual-scroller/react"));
/**
 * VirtualizedScroller
 * A component for efficiently rendering large lists of variable height items.
 * VirtualScroller works by measuring each list item's height as it's being rendered, and then, as the user scrolls,
 * it hides the items that are no longer visible, and shows the now-visible items as they're scrolled to.
 * The hidden items at the top are compensated by setting padding-top on the list element, and the hidden items
 * at the bottom are compensated by setting padding-bottom on the list element.
 * The component listens to scroll / resize events and re-renders the currently visible items as the user
 * scrolls (or if the browser window is resized).
 * Set window['VirtualScrollerDebug'] = true; to output debug messages to console.
 */
function VirtualizedScroller(props) {
    const { items = [], ItemComponent, getItemId, initialScrollerState, onScrollerStateChange, onScrollerMount, onScrollerPositionChange, onScrollerSaveState, cacheStrategy = utils_1.CacheStrategies.CACHE_FIRST, cacheScrollStateKey = 'virtual_scroller_st', cacheScrollerPositionKey = 'virtual_scroller_sp' } = props, rest = tslib_1.__rest(props, ["items", "ItemComponent", "getItemId", "initialScrollerState", "onScrollerStateChange", "onScrollerMount", "onScrollerPositionChange", "onScrollerSaveState", "cacheStrategy", "cacheScrollStateKey", "cacheScrollerPositionKey"]);
    // REF
    const virtualScrollerMountState = (0, react_1.useRef)(false);
    // HELPERS
    /**
     * Callback on mount the virtual scroller
     */
    const onVirtualScrollerMount = (0, react_1.useMemo)(() => () => {
        virtualScrollerMountState.current = true;
        onScrollerMount && onScrollerMount();
    }, []);
    /**
     * Get initial scroll position by cacheScrollerPositionKey
     * Recovered only if cacheStrategy = CACHE_FIRST
     */
    const getInitialScrollPosition = (0, react_1.useMemo)(() => () => cacheStrategy === utils_1.CacheStrategies.CACHE_FIRST && cacheScrollerPositionKey ? utils_1.LRUCache.get(cacheScrollerPositionKey) : 0, [cacheStrategy, cacheScrollerPositionKey]);
    /**
     * Callback on virtual scroller position change
     */
    const onScrollPositionChange = (0, react_1.useMemo)(() => (y) => {
        if (cacheScrollerPositionKey) {
            utils_1.LRUCache.set(cacheScrollerPositionKey, y);
        }
        onScrollerPositionChange && onScrollerPositionChange(y);
    }, [cacheScrollerPositionKey]);
    /**
     * Callback on virtual scroller state change
     */
    const onStateScrollChange = (0, react_1.useMemo)(() => (state) => {
        virtualScrollerState.current = state;
        onScrollerStateChange && onScrollerStateChange(state);
    }, []);
    /**
     * Save virtual scroller state
     */
    const saveVirtualScrollerState = (0, react_1.useMemo)(() => (state) => {
        if (cacheScrollerPositionKey) {
            utils_1.LRUCache.set(cacheScrollStateKey, state);
        }
        onScrollerSaveState && onScrollerSaveState(state);
    }, [cacheScrollStateKey]);
    /**
     * Read virtual scroller state
     */
    const readVirtualScrollerState = (0, react_1.useMemo)(() => () => {
        if (cacheStrategy === utils_1.CacheStrategies.CACHE_FIRST && cacheScrollStateKey && utils_1.LRUCache.hasKey(cacheScrollStateKey)) {
            const _state = utils_1.LRUCache.get(cacheScrollStateKey);
            if (_state.items && _state.items.length) {
                return _state;
            }
        }
        return null;
    }, [cacheScrollStateKey, cacheStrategy]);
    // REF
    const virtualScrollerState = (0, react_1.useRef)(readVirtualScrollerState());
    // EFFECTS
    (0, react_1.useEffect)(() => {
        return () => {
            // Save state before the component unmounts.
            saveVirtualScrollerState(virtualScrollerState.current);
        };
    });
    return ((0, jsx_runtime_1.jsx)(react_2.default, Object.assign({ items: items, itemComponent: ItemComponent, onMount: onVirtualScrollerMount }, (getItemId && { getItemId }), { initialState: initialScrollerState ? initialScrollerState : readVirtualScrollerState(), onStateChange: onStateScrollChange, initialScrollPosition: getInitialScrollPosition(), onScrollPositionChange: onScrollPositionChange }, rest)));
}
exports.default = VirtualizedScroller;
