import { __assign } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState, useCallback, useEffect, useMemo, useContext } from 'react';
import cx from 'classnames';
import pick from '../utils/pick';
import { Direction, ListProps } from './constants';
import TransferItem from './components/TransferItem';
import ArrowButton from './components/ArrowButton';
import { getOppositeDirection, getSingleDirectionSelectedKeysExcludeDisabled, getDisabledKeys, } from './utils';
import { DisabledContext } from '../disabled';
export var Transfer = function (_a) {
    var keyName = _a.keyName, dataSource = _a.dataSource, targetKeys = _a.targetKeys, onChange = _a.onChange, selectedKeysProp = _a.selectedKeys, onSelectChange = _a.onSelectChange, titles = _a.titles, showSearch = _a.showSearch, searchPlaceholder = _a.searchPlaceholder, filterOption = _a.filterOption, children = _a.children, list = _a.list, pagination = _a.pagination, compontentDisabled = _a.disabled, className = _a.className;
    var classNamePrefix = 'zent-transfer';
    var _b = useState(selectedKeysProp), selectedKeysState = _b[0], setSelectedKeys = _b[1];
    var value = useContext(DisabledContext).value;
    var disabled = compontentDisabled !== null && compontentDisabled !== void 0 ? compontentDisabled : value;
    var disabledKeys = useMemo(function () { return getDisabledKeys(dataSource, keyName); }, [dataSource, keyName]);
    var getListProps = useCallback(function (direction) {
        if (!Array.isArray(list)) {
            return list;
        }
        return Direction.Left === direction ? list[0] : list[1];
    }, [list]);
    var getSingleDirectionData = useCallback(function (direction) {
        return Direction.Left === direction
            ? dataSource.filter(function (_a) {
                var _b = keyName, key = _a[_b];
                return !targetKeys.includes(key);
            })
            : targetKeys.map(function (item) {
                return dataSource.find(function (_a) {
                    var _b = keyName, key = _a[_b];
                    return item === key;
                });
            });
    }, [dataSource, keyName, targetKeys]);
    var getSingleDirectionSelectedKeys = useCallback(function (direction) {
        return selectedKeysState.filter(function (key) {
            return Direction.Left === direction
                ? !targetKeys.includes(key)
                : targetKeys.includes(key);
        });
    }, [selectedKeysState, targetKeys]);
    var handleSelectChange = useCallback(function (direction) { return function (keys) {
        var selectedKeys = keys.concat(getSingleDirectionSelectedKeys(getOppositeDirection(direction)));
        onSelectChange
            ? onSelectChange(selectedKeys)
            : setSelectedKeys(selectedKeys);
    }; }, [getSingleDirectionSelectedKeys, onSelectChange]);
    var getColumns = useCallback(function (direction) {
        var columns = getListProps(direction).columns;
        var col = Direction.Left === direction ? columns === null || columns === void 0 ? void 0 : columns[0] : columns === null || columns === void 0 ? void 0 : columns[1];
        return (Array.isArray(columns === null || columns === void 0 ? void 0 : columns[0]) ? col : columns);
    }, [getListProps]);
    var getRenderList = useCallback(function (props) {
        var direction = props.direction, selectedKeys = props.selectedKeys, handleSelectChange = props.handleSelectChange, title = props.title, keyName = props.keyName, dataSets = props.dataSets, showSearch = props.showSearch, searchPlaceholder = props.searchPlaceholder, filterOption = props.filterOption, list = props.list, prefix = props.prefix;
        var childrenNode = children &&
            children({
                direction: direction,
                selectedKeys: selectedKeys,
                handleSelectChange: handleSelectChange,
            });
        return (childrenNode !== null && childrenNode !== void 0 ? childrenNode : (_jsx(TransferItem, { title: title, direction: direction, keyName: keyName, dataSets: dataSets, selectedKeys: selectedKeys, handleSelectChange: handleSelectChange, showSearch: showSearch, searchPlaceholder: searchPlaceholder, filterOption: filterOption, list: list, prefix: prefix, pagination: pagination, disabled: disabled }, void 0)));
    }, [children, pagination, disabled]);
    var handleTransfer = useCallback(function (direction) { return function () {
        var transferredKeys = getSingleDirectionSelectedKeysExcludeDisabled({
            direction: getOppositeDirection(direction),
            selectedKeys: selectedKeysState,
            targetKeys: targetKeys,
            disabledKeys: disabledKeys,
        });
        var selectedKeys = selectedKeysState.filter(function (item) { return !transferredKeys.includes(item); });
        setSelectedKeys(selectedKeys);
        onChange({
            targetKeys: Direction.Right === direction
                ? transferredKeys.concat(targetKeys)
                : targetKeys.filter(function (item) { return !transferredKeys.includes(item); }),
            direction: direction,
            transferredKeys: transferredKeys,
            selectedKeys: selectedKeys,
        });
    }; }, [selectedKeysState, targetKeys, onChange, disabledKeys]);
    var getArrowButton = useCallback(function (direction) { return (_jsx("div", __assign({ className: classNamePrefix + "__arrow__item", "data-zv": 'v10.0.11' }, { children: _jsx(ArrowButton, { disabled: disabled ||
                !getSingleDirectionSelectedKeysExcludeDisabled({
                    direction: getOppositeDirection(direction),
                    selectedKeys: selectedKeysState,
                    targetKeys: targetKeys,
                    disabledKeys: disabledKeys,
                }).length, direction: direction, onChange: handleTransfer(direction), prefix: classNamePrefix }, void 0) }), void 0)); }, [
        handleTransfer,
        classNamePrefix,
        disabled,
        targetKeys,
        selectedKeysState,
        disabledKeys,
    ]);
    useEffect(function () {
        setSelectedKeys(selectedKeysProp);
    }, [selectedKeysProp]);
    return (_jsxs("div", __assign({ className: cx("" + classNamePrefix, className), "data-zv": 'v10.0.11' }, { children: [getRenderList({
                title: titles === null || titles === void 0 ? void 0 : titles[0],
                direction: Direction.Left,
                keyName: keyName,
                dataSets: useMemo(function () { return getSingleDirectionData(Direction.Left); }, [getSingleDirectionData]),
                selectedKeys: getSingleDirectionSelectedKeys(Direction.Left),
                handleSelectChange: handleSelectChange(Direction.Left),
                showSearch: showSearch,
                searchPlaceholder: searchPlaceholder,
                filterOption: filterOption,
                list: __assign({ columns: getColumns(Direction.Left) }, pick(getListProps(Direction.Left), ListProps)),
                prefix: classNamePrefix,
                pagination: pagination,
                disabled: disabled,
            }), _jsxs("div", __assign({ className: classNamePrefix + "__arrow", "data-zv": 'v10.0.11' }, { children: [getArrowButton(Direction.Right), getArrowButton(Direction.Left)] }), void 0), getRenderList({
                title: titles === null || titles === void 0 ? void 0 : titles[1],
                direction: Direction.Right,
                keyName: keyName,
                dataSets: useMemo(function () { return getSingleDirectionData(Direction.Right); }, [getSingleDirectionData]),
                selectedKeys: getSingleDirectionSelectedKeys(Direction.Right),
                handleSelectChange: handleSelectChange(Direction.Right),
                showSearch: showSearch,
                searchPlaceholder: searchPlaceholder,
                filterOption: filterOption,
                list: __assign({ columns: getColumns(Direction.Right) }, pick(getListProps(Direction.Right), ListProps)),
                prefix: classNamePrefix,
                pagination: pagination,
                disabled: disabled,
            })] }), void 0));
};
Transfer.defaultProps = {
    titles: ['Source', 'Target'],
    targetKeys: [],
    selectedKeys: [],
    showSearch: false,
    searchPlaceholder: '',
    className: '',
    pagination: false,
};
export default Transfer;
