import { __assign, __extends } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
import { createRef, Component } from 'react';
import { MenuListItem, handleItemClick } from './MenuListItem';
var menuListPaddingTop = 0;
var MenuList = (function (_super) {
    __extends(MenuList, _super);
    function MenuList(props) {
        var _this = _super.call(this, props) || this;
        _this.refMenuScrollContainer = createRef();
        _this.refMenuItemList = createRef();
        _this.onKeyDown = function (e) {
            switch (e.key) {
                case 'Escape':
                    _this.close();
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    if (_this.state.open) {
                        _this.moveFocusIndexDown();
                    }
                    break;
                case 'ArrowUp': {
                    e.preventDefault();
                    if (_this.state.open) {
                        _this.moveFocusIndexUp();
                    }
                    break;
                }
                case 'Enter': {
                    if (_this.state.open) {
                        _this.selectCurrentFocusIndex(e);
                    }
                    break;
                }
                default:
            }
        };
        _this.setFocusIndex = function (focusIdx, autoScroll) {
            if (autoScroll === void 0) { autoScroll = true; }
            _this.setState({
                focusIdx: focusIdx == null ? null : _this.getItemIdxInItems(focusIdx),
                autoScrollFocusIdx: autoScroll ? focusIdx : null,
            });
        };
        _this.getItemIdxInItems = function (idx) {
            var items = _this.props.items;
            var targetIdx = idx % items.length;
            if (targetIdx < 0) {
                targetIdx += items.length;
            }
            return targetIdx;
        };
        _this.getValidItemIdx = function (idx, searchDown) {
            if (searchDown === void 0) { searchDown = true; }
            var items = _this.props.items;
            if (!(items && items.length) ||
                items.every(function (item) { return item.isDivider && item.isGroup; }) ||
                typeof idx !== 'number' ||
                Number.isNaN(idx)) {
                return null;
            }
            var targetIdx = _this.getItemIdxInItems(idx);
            var item = items[targetIdx];
            if (!item || item.isDivider || item.isGroup || item.disabled) {
                var initialIdx = targetIdx;
                targetIdx = _this.getItemIdxInItems(searchDown ? targetIdx + 1 : targetIdx - 1);
                item = items[targetIdx];
                while (!item ||
                    ((item.isDivider || item.isGroup || item.disabled) &&
                        targetIdx !== initialIdx)) {
                    targetIdx = _this.getItemIdxInItems(searchDown ? targetIdx + 1 : targetIdx - 1);
                    item = items[targetIdx];
                }
            }
            return targetIdx;
        };
        _this.getTopMenu = function () {
            return _this;
        };
        _this.moveFocusIndex = function (offset) {
            var focusIdx = _this.state.focusIdx;
            if (focusIdx !== null) {
                _this.setFocusIndex(_this.getValidItemIdx(focusIdx + offset, offset > 0));
            }
            else {
                _this.setFocusIndex(_this.getValidItemIdx(0));
            }
        };
        _this.moveFocusIndexDown = function () {
            _this.getTopMenu().moveFocusIndex(1);
        };
        _this.moveFocusIndexUp = function () {
            _this.getTopMenu().moveFocusIndex(-1);
        };
        _this.selectCurrentFocusIndex = function (e) {
            var ins = _this.getTopMenu();
            var focusIdx = ins.state.focusIdx;
            if (focusIdx !== null) {
                var _a = _this.props, items = _a.items, onRequestClose = _a.onRequestClose;
                var item = items[focusIdx];
                handleItemClick({ item: item, event: e, onRequestClose: onRequestClose });
            }
        };
        _this.close = function () {
            _this.setState({
                open: false,
            });
        };
        _this.renderItems = function (items) {
            if (items === void 0) { items = []; }
            var onRequestClose = _this.props.onRequestClose;
            var focusIdx = _this.state.focusIdx;
            return items.map(function (item, index) {
                return (_jsx(MenuListItem, { index: index, item: item, onRequestClose: onRequestClose, focusTo: _this.setFocusIndex, hover: focusIdx === index }, item.value === undefined ? index : item.value));
            });
        };
        _this.state = {
            focusIdx: null,
        };
        return _this;
    }
    MenuList.prototype.componentDidUpdate = function () {
        this.autoScroll();
    };
    MenuList.prototype.autoScroll = function () {
        var itemsLength = (this.props.items || []).length;
        var _a = this.state, focusIdx = _a.focusIdx, autoScrollFocusIdx = _a.autoScrollFocusIdx;
        var menuListNode = this.refMenuItemList.current;
        var scrollContainer = this.refMenuScrollContainer.current;
        if (itemsLength &&
            focusIdx !== null &&
            focusIdx === autoScrollFocusIdx &&
            menuListNode &&
            scrollContainer) {
            var focusedItemNode = menuListNode.childNodes[this.state.focusIdx];
            if (!focusedItemNode) {
                return;
            }
            var itemOffsetTop = focusedItemNode.offsetTop;
            var itemOffsetHeight = focusedItemNode.offsetHeight;
            var containerOffsetHeight = scrollContainer.offsetHeight;
            var containerScrollTop = scrollContainer.scrollTop;
            if (containerOffsetHeight + containerScrollTop <
                itemOffsetTop + itemOffsetHeight) {
                scrollContainer.scrollTop =
                    itemOffsetTop +
                        itemOffsetHeight -
                        containerOffsetHeight -
                        menuListPaddingTop;
            }
            else if (containerScrollTop > itemOffsetTop) {
                scrollContainer.scrollTop = itemOffsetTop - menuListPaddingTop;
            }
        }
    };
    MenuList.prototype.render = function () {
        var items = this.props.items;
        return (_jsx("div", __assign({ ref: this.refMenuScrollContainer, className: "zent-popup-menu", tabIndex: 0, onKeyDown: this.onKeyDown, "data-zv": 'v10.0.11' }, { children: items && items.length ? (_jsx("ul", __assign({ ref: this.refMenuItemList, "data-zv": 'v10.0.11' }, { children: this.renderItems(items) }), void 0)) : null }), void 0));
    };
    return MenuList;
}(Component));
export default MenuList;
