import React, { useCallback, useRef, useState } from 'react';
import i18n from 'ui-i18n';
import classnames from 'classnames';
import { always, any, append, ifElse, not, pipe, pluck, propEq, reject } from 'ramda';
import Button from '@mui/material/Button';
import ListItem from '@mui/material/ListItem';
import Typography from '@mui/material/Typography';
import AddIcon from '@mui/icons-material/Add';
import { AttributeListItem } from '../AttributeListItem';
import { SelectionPopup } from '../SelectionPopup';
import { Highlighter } from '../Highlighter';
import { useKeyboardNavigation } from '../hooks/useKeyboardNavigation';
import { VirtualGroupedList } from '../VirtualGroupedList';
import { useMoreAttributesItems } from './useMoreAttributesItems';
import { ITEM_GROUP_TITLE_HEIGHT, CONTAINER_HEADER_HEIGHT, ITEM_HEIGHT, LIST_CONTAINER_WIDTH, MAX_LIST_CONTAINER_HEIGHT, MIN_CONTAINER_HEIGHT } from './constants';
import { useStyles } from './styles';
export var MoreAttributesButton = function (_a) {
    var _b;
    var label = _a.label, _c = _a.popupTitle, popupTitle = _c === void 0 ? label : _c, data = _a.data, parent = _a.parent, dense = _a.dense, onApply = _a.onApply, _d = _a.disabled, disabled = _d === void 0 ? false : _d;
    var styles = useStyles();
    var inputRef = useRef(null);
    var _e = useState(false), isOpen = _e[0], setIsOpen = _e[1];
    var togglePopupOpen = function () { return setIsOpen(!isOpen); };
    var closePopup = function () { return setIsOpen(false); };
    var _f = useState(''), filter = _f[0], setFilter = _f[1];
    var clearFilter = function () { return setFilter(''); };
    var _g = useState([]), selectedItems = _g[0], setSelectedItems = _g[1];
    var clearSelectedItems = function () { return setSelectedItems([]); };
    var _h = useMoreAttributesItems({ data: data, parent: parent, filter: filter }), items = _h.items, hasGroups = _h.hasGroups, parentGroupLength = _h.parentGroupLength, attributesGroupLength = _h.attributesGroupLength;
    var addSelectedAttributes = function () {
        if (selectedItems.length > 0) {
            onApply(pluck('attrType', selectedItems));
        }
    };
    var handleListItemClick = useCallback(function (item, checked) {
        setSelectedItems(ifElse(always(checked), append(item), reject(propEq('id', item.id)))(selectedItems));
    }, [selectedItems]);
    var getItemSize = useCallback(function (i, item) { return (item.items ? ITEM_GROUP_TITLE_HEIGHT : ITEM_HEIGHT); }, []);
    var handleSearchOnEnter = useCallback(function (_a) {
        var item = _a.item;
        handleListItemClick(item, not(any(propEq('id', item.id))(selectedItems)));
    }, [handleListItemClick, selectedItems]);
    var _j = useKeyboardNavigation({
        items: items,
        open: isOpen,
        onSelectFocusedItem: handleSearchOnEnter,
        selectedItems: selectedItems
    }), focusIndex = _j.focusIndex, handleKeyDown = _j.handleKeyDown;
    var focusIndexRef = useRef(null);
    focusIndexRef.current = focusIndex;
    var groupsCount = hasGroups ? (parentGroupLength ? 1 : 0) + (attributesGroupLength ? 1 : 0) : 0;
    var itemsCount = items.length - groupsCount;
    var listHeight = Math.min(MAX_LIST_CONTAINER_HEIGHT, ITEM_HEIGHT * itemsCount + ITEM_GROUP_TITLE_HEIGHT * groupsCount);
    var containerHeight = Math.max(MIN_CONTAINER_HEIGHT, listHeight + CONTAINER_HEADER_HEIGHT);
    var listItemRenderer = useCallback(function (style, _a, index) {
        var _b;
        var item = _a.item, _c = _a.level, level = _c === void 0 ? 0 : _c;
        var isChecked = any(propEq('id', item.id))(selectedItems);
        var isFocused = focusIndexRef.current === index;
        return (React.createElement(AttributeListItem, { key: item.uri, onClick: handleListItemClick, checked: isChecked, level: level, data: item, label: React.createElement(Highlighter, { text: item.label, highlight: filter }), labelInText: item.label, style: style, isFocused: isFocused, isRequired: !!((_b = item.attrType) === null || _b === void 0 ? void 0 : _b.required), LogoIcon: item.LogoIcon }));
    }, [filter, handleListItemClick, selectedItems]);
    var renderGroupTitle = useCallback(function (style, item) { return (React.createElement(ListItem, { component: 'div', className: styles.subHeader, style: style, key: "group-".concat(item.item.id) }, item.item.label)); }, []);
    return (React.createElement("div", { className: classnames(styles.moreAttributes, (_b = {}, _b[styles.dense] = dense, _b)) },
        React.createElement(Button, { color: "primary", onClick: togglePopupOpen, ref: inputRef, className: styles.moreButton, disabled: disabled },
            React.createElement(AddIcon, { classes: { root: styles.icon } }),
            React.createElement("div", { className: styles.buttonLabel }, label)),
        React.createElement(SelectionPopup, { open: isOpen, className: classnames(styles.moreAttributesPopup, styles.popupContainer), anchorEl: inputRef.current, onClose: pipe(addSelectedAttributes, closePopup, clearFilter, clearSelectedItems), onSearch: setFilter, containerHeight: containerHeight, title: popupTitle, containerWidth: LIST_CONTAINER_WIDTH, searchInputOnKeyDown: handleKeyDown },
            React.createElement(VirtualGroupedList, { getItemSize: getItemSize, renderItem: listItemRenderer, renderGroupTitle: renderGroupTitle, disableHorizontalScrollbar: true, items: items, height: listHeight, focusIndex: focusIndex }),
            items.length === 0 && (React.createElement("div", { className: styles.noResultsCaptionContainer },
                React.createElement(Typography, { variant: "caption", display: "block", gutterBottom: true }, i18n.text('No results found')))))));
};
