import React__default, { useMemo, Children, isValidElement, useState } from 'react';
import { AnimatePresence } from 'framer-motion';
import classnames from 'classnames';
import { u as useDataListLayoutContext } from './DataListLayoutContext-es.js';
import { I as InternalDataListItemActions } from './DataListItemActions-es.js';
import { D as DataListActionsMenu } from './DataListActionsMenu-es.js';
import { D as DataListLayoutActionsContext } from './DataListLayoutContext-es2.js';
import { d as generateListItemElement } from './DataList.utils-es.js';
import { Checkbox } from './Checkbox/index.mjs';
import { u as useBatchSelect } from './useBatchSelect-es.js';
import { s as styles } from './DataList.module-es.js';
import { D as DataListItemClickable } from './DataListItemClickable-es.js';
import { u as useDataListContext } from './DataListContext-es.js';

function DataListItemInternal({ children, item, }) {
    const { canSelect, hasAtLeastOneSelected, isSelectAll, selectedIDs, selected, onSelect, } = useBatchSelect();
    if (!canSelect)
        return children;
    return (React__default.createElement("div", { className: classnames(styles.selectable, {
            [styles.selected]: hasAtLeastOneSelected,
        }) },
        children,
        React__default.createElement(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 } = useDataListContext();
    const disableContextMenu = (_a = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.disableContextMenu) !== null && _a !== void 0 ? _a : false;
    const actions = useMemo(() => {
        var _a;
        const children = (_a = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.children) !== null && _a !== void 0 ? _a : [];
        const nodes = Children.toArray(children);
        return nodes.filter((node) => {
            if (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 } = useDataListLayoutContext();
    const [showMenu, setShowMenu] = useState(false);
    const [contextPosition, setContextPosition] = useState();
    const generatedItem = useMemo(() => 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__default.createElement(DataListLayoutActionsContext.Provider, { value: { activeItem: item } },
        React__default.createElement("div", { onMouseEnter: handleShowMenu, onMouseLeave: handleHideMenu, onFocus: handleShowMenu, onBlur: handleHideMenu, onContextMenu: disableContextMenu ? undefined : handleContextMenu, className: classnames(styles.listItem, {
                [styles.active]: showMenu && isContextMenuVisible,
            }), key: item.id },
            React__default.createElement(DataListItemInternal, { item: item },
                React__default.createElement(DataListItemClickable, null, layout(generatedItem))),
            React__default.createElement(AnimatePresence, null,
                shouldShowHoverMenu && (React__default.createElement(InternalDataListItemActions, { actions: actions })),
                React__default.createElement(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,
        });
    }
}

export { DataListItem as D };
