"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSelectionEvent = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const react_1 = require("react");
const useProperty_1 = tslib_1.__importDefault(require("../utils/useProperty"));
const SelectableListContext = React.createContext({
    clickInfoRef: null,
    selected: {},
    getItemId: (index) => index,
    toggleOnSimpleClick: false,
    setSelected: (x) => { },
});
const useSelectionEvent = () => {
    const { selected, setSelected, toggleOnSimpleClick, clickInfoRef, getItemId } = (0, react_1.useContext)(SelectableListContext);
    return (event, { index }) => {
        if (index === undefined) {
            return;
        }
        const { lastClickIndexWithoutShift, lastShiftSelectionRange } = clickInfoRef.current;
        let { shiftKey, metaKey, ctrlKey } = event;
        if (ctrlKey) {
            metaKey = true;
        }
        if (metaKey) {
            // as if shift key is not pressed
            shiftKey = false;
        }
        let itemId = `${getItemId(index)}`;
        let newSelection;
        if (!shiftKey) {
            clickInfoRef.current.lastClickIndexWithoutShift = index;
            if (!metaKey && !toggleOnSimpleClick) {
                // a simple click, no key modifiers
                // so reset the selection
                // and only add one item, the currently clicked item
                newSelection = { [itemId]: true };
            }
            else {
                const currentRowSelected = selected[itemId];
                newSelection = { ...selected };
                if (currentRowSelected) {
                    // unselected the current row
                    delete newSelection[itemId];
                    // also, when unselecting, the click position should not be remembered, so need to revert it back
                    clickInfoRef.current.lastClickIndexWithoutShift = lastClickIndexWithoutShift;
                }
                else {
                    newSelection[itemId] = true;
                }
            }
            clickInfoRef.current.lastShiftSelectionRange = null;
            setSelected(newSelection);
        }
        else {
            let prevClickIndex = lastClickIndexWithoutShift;
            let currentClickIndex = index;
            newSelection = { ...selected };
            if (lastShiftSelectionRange) {
                let { start, end } = lastShiftSelectionRange;
                // clear previous shift selection
                for (; start <= end; start++) {
                    delete newSelection[getItemId(start)];
                }
            }
            let [start, end] = [
                Math.min(prevClickIndex, currentClickIndex),
                Math.max(prevClickIndex, currentClickIndex),
            ];
            clickInfoRef.current.lastShiftSelectionRange = { start, end };
            for (; start <= end; start++) {
                newSelection[getItemId(start)] = true;
            }
            setSelected(newSelection);
        }
    };
};
exports.useSelectionEvent = useSelectionEvent;
const SelectableList = (props) => {
    const [selected, setSelected] = (0, useProperty_1.default)(props, 'selected', {});
    const clickInfoRef = (0, react_1.useRef)({
        lastClickIndexWithoutShift: 0,
    });
    const getItemId = (index) => {
        if (props.getItemId) {
            return props.getItemId(index);
        }
        return index;
    };
    return (React.createElement(SelectableListContext.Provider, { value: {
            clickInfoRef,
            toggleOnSimpleClick: props.toggleOnSimpleClick || false,
            selected,
            setSelected,
            getItemId,
        } }, props.children));
};
exports.default = SelectableList;
