'use strict';

var React = require('react');
var framerMotion = require('framer-motion');
var classnames = require('classnames');
var DataListLayoutContext = require('./DataListLayoutContext-cjs.js');
var DataListItemActions = require('./DataListItemActions-cjs.js');
var DataListActionsMenu = require('./DataListActionsMenu-cjs.js');
var DataListLayoutContext$1 = require('./DataListLayoutContext-cjs2.js');
var DataList_utils = require('./DataList.utils-cjs.js');
var Checkbox = require('./Checkbox-cjs.js');
var useBatchSelect = require('./useBatchSelect-cjs.js');
var DataList_module = require('./DataList.module-cjs.js');
var DataListItemClickable = require('./DataListItemClickable-cjs.js');
var DataListContext = require('./DataListContext-cjs.js');

function DataListItemInternal({ children, item, }) {
    const { canSelect, hasAtLeastOneSelected, isSelectAll, selectedIDs, selected, onSelect, } = useBatchSelect.useBatchSelect();
    if (!canSelect)
        return children;
    return (React.createElement("div", { className: classnames(DataList_module.styles.selectable, {
            [DataList_module.styles.selected]: hasAtLeastOneSelected,
        }) },
        children,
        React.createElement(Checkbox.Checkbox, { checked: getIsChecked(), onChange: handleChange })));
    function getIsChecked() {
        const isItemInSelectedIDs = selectedIDs.includes(item.id);
        // If we're in a "select all" state, the selectedID's becomes a list of
        // unchecked ID's.
        if (isSelectAll)
            return !isItemInSelectedIDs;
        // Otherwise, we're in a "select some" state, so we can just check if the
        // item is in the selectedIDs list.
        return isItemInSelectedIDs;
    }
    function handleChange() {
        if (isSelectAll)
            return handleSelectAllChange();
        return handleSelectSomeChange();
    }
    function handleSelectAllChange() {
        if (!selected || Array.isArray(selected))
            return;
        if (selectedIDs === null || selectedIDs === void 0 ? void 0 : selectedIDs.includes(item.id)) {
            onSelect === null || onSelect === void 0 ? void 0 : onSelect(Object.assign(Object.assign({}, selected), { unselected: selectedIDs === null || selectedIDs === void 0 ? void 0 : selectedIDs.filter(id => id !== item.id) }));
        }
        else if (selectedIDs) {
            onSelect === null || onSelect === void 0 ? void 0 : onSelect(Object.assign(Object.assign({}, selected), { unselected: [...selectedIDs, item.id] }));
        }
    }
    function handleSelectSomeChange() {
        if (selectedIDs === null || selectedIDs === void 0 ? void 0 : selectedIDs.includes(item.id)) {
            onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedIDs === null || selectedIDs === void 0 ? void 0 : selectedIDs.filter(id => id !== item.id));
        }
        else if (selectedIDs) {
            onSelect === null || onSelect === void 0 ? void 0 : onSelect([...selectedIDs, item.id]);
        }
    }
}

function useGetItemActions(item) {
    var _a;
    const { itemActionComponent } = DataListContext.useDataListContext();
    const disableContextMenu = (_a = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.disableContextMenu) !== null && _a !== void 0 ? _a : false;
    const actions = React.useMemo(() => {
        var _a;
        const children = (_a = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.children) !== null && _a !== void 0 ? _a : [];
        const nodes = React.Children.toArray(children);
        return nodes.filter((node) => {
            if (React.isValidElement(node)) {
                return node.props.visible ? node.props.visible(item) : true;
            }
            return false;
        });
    }, [itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.children, item]);
    return {
        actions,
        hasActions: Boolean(actions.length),
        disableContextMenu,
    };
}

function DataListItem({ item, layout, }) {
    const { hasInLayoutActions } = DataListLayoutContext.useDataListLayoutContext();
    const [showMenu, setShowMenu] = React.useState(false);
    const [contextPosition, setContextPosition] = React.useState();
    const generatedItem = React.useMemo(() => DataList_utils.generateListItemElement(item), [item]);
    const { actions, hasActions, disableContextMenu } = useGetItemActions(item);
    const isContextMenuVisible = Boolean(contextPosition);
    const shouldShowContextMenu = showMenu && isContextMenuVisible && hasActions;
    const shouldShowHoverMenu = showMenu && hasActions && !hasInLayoutActions && !shouldShowContextMenu;
    return (React.createElement(DataListLayoutContext$1.DataListLayoutActionsContext.Provider, { value: { activeItem: item } },
        React.createElement("div", { onMouseEnter: handleShowMenu, onMouseLeave: handleHideMenu, onFocus: handleShowMenu, onBlur: handleHideMenu, onContextMenu: disableContextMenu ? undefined : handleContextMenu, className: classnames(DataList_module.styles.listItem, {
                [DataList_module.styles.active]: showMenu && isContextMenuVisible,
            }), key: item.id },
            React.createElement(DataListItemInternal, { item: item },
                React.createElement(DataListItemClickable.DataListItemClickable, null, layout(generatedItem))),
            React.createElement(framerMotion.AnimatePresence, null,
                shouldShowHoverMenu && (React.createElement(DataListItemActions.InternalDataListItemActions, { actions: actions })),
                React.createElement(DataListActionsMenu.DataListActionsMenu, { key: item.id, visible: shouldShowContextMenu, position: contextPosition || { x: 0, y: 0 }, onRequestClose: () => setContextPosition(undefined) }, actions)))));
    function handleShowMenu() {
        setShowMenu(true);
    }
    function handleHideMenu() {
        if (isContextMenuVisible)
            return;
        setShowMenu(false);
    }
    function handleContextMenu(event) {
        if (!hasActions || isContextMenuVisible)
            return;
        event.preventDefault();
        setContextPosition({
            x: event.clientX,
            y: event.clientY,
        });
    }
}

exports.DataListItem = DataListItem;
