import * as tslib_1 from "tslib";
import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Form, Select, Input, Spin } from 'antd';
import { PrototypeCheck } from '../utils';
import { debounce } from 'lodash';
import { InputSearchTable } from '..';
var FormSelect = function (_a) {
    var label = _a.label, labelCol = _a.labelCol, wrapperCol = _a.wrapperCol, allowClear = _a.allowClear, fetchApi = _a.fetchApi, placeholder = _a.placeholder, showSearch = _a.showSearch, onSelect = _a.onSelect, onChange = _a.onChange, onDeselect = _a.onDeselect, mode = _a.mode, disabled = _a.disabled, popupContainerId = _a.popupContainerId, className = _a.className, form = _a.form, field = _a.field, changeConfirm = _a.changeConfirm, isFormData = _a.isFormData, formDataKey = _a.formDataKey, apiParamsCb = _a.apiParamsCb, options = _a.options, _b = _a.mountFetchApi, mountFetchApi = _b === void 0 ? true : _b, isHugeOptions = _a.isHugeOptions, labelInValue = _a.labelInValue, normalizeGetValue = _a.normalizeGetValue, normalizeSetValue = _a.normalizeSetValue, normalizeDeValue = _a.normalizeDeValue, normalizeRowValue = _a.normalizeRowValue, selectProps = _a.selectProps, tableConfig = _a.tableConfig, restProps = tslib_1.__rest(_a, ["label", "labelCol", "wrapperCol", "allowClear", "fetchApi", "placeholder", "showSearch", "onSelect", "onChange", "onDeselect", "mode", "disabled", "popupContainerId", "className", "form", "field", "changeConfirm", "isFormData", "formDataKey", "apiParamsCb", "options", "mountFetchApi", "isHugeOptions", "labelInValue", "normalizeGetValue", "normalizeSetValue", "normalizeDeValue", "normalizeRowValue", "selectProps", "tableConfig"]);
    var _c = form, getFieldDecorator = _c.getFieldDecorator, getFieldValue = _c.getFieldValue, setFieldsValue = _c.setFieldsValue;
    var initialValue = restProps.initialValue, required = restProps.required, validator = restProps.validator;
    var _d = useState([]), localOptions = _d[0], setLocalOptions = _d[1];
    var _e = useState(false), fetching = _e[0], setFetching = _e[1];
    var _f = useState(), inputValue = _f[0], setInputValue = _f[1];
    var tableRef = useRef();
    var isMultipleMode = mode === 'multiple';
    var setOptionsMemoized = useCallback(function (options, value) {
        function setOptions(options, value) {
            var localOptions;
            if (showSearch && value) {
                localOptions = options.reduce(function (prev, curr) {
                    curr.value.includes(value) && prev.push(setOption(curr));
                    return prev;
                }, []);
            }
            else {
                localOptions = isHugeOptions ? [] : options.map(setOption);
            }
            setLocalOptions(localOptions);
        }
        setOptions(options, value);
    }, [showSearch, isHugeOptions, setLocalOptions]);
    useEffect(function () {
        options && setOptionsMemoized(options);
    }, [options, setOptionsMemoized]);
    var fetchApiDataMemoized = useCallback(function (value) {
        function fetchApiData(value) {
            if (!fetchApi) {
                options && setOptionsMemoized(options, value);
                return;
            }
            var apiParams;
            if (apiParamsCb) {
                if (isFormData) {
                    apiParams = new FormData();
                    apiParams.append(formDataKey || 'data', JSON.stringify(apiParamsCb(value)));
                }
                else {
                    apiParams = apiParamsCb(value);
                }
            }
            setFetching(true);
            fetchApi(apiParams || value).then(function (datas) {
                setOptionsMemoized(datas, value);
                setFetching(false);
            });
        }
        fetchApiData(value);
    }, [fetchApi, options, apiParamsCb, isFormData, formDataKey, setOptionsMemoized]);
    useEffect(function () {
        mountFetchApi && fetchApiDataMemoized();
    }, [fetchApiDataMemoized, mountFetchApi]);
    function setOption(v) {
        return (React.createElement(Select.Option, { key: v.key, value: v.key.toString(), "data-original": v }, v.value || v.key));
    }
    var handleSelect = function (value) {
        var _a;
        if (isMultipleMode)
            return;
        if (!PrototypeCheck.isString(value))
            value = value.key;
        var _b = form, setFieldsValue = _b.setFieldsValue, getFieldValue = _b.getFieldValue;
        if (!changeConfirm) {
            setFieldsValue((_a = {}, _a[field] = value, _a));
            return;
        }
        var oldValue = getFieldValue(field);
        var setValue = function (value) {
            var _a;
            return setFieldsValue((_a = {}, _a[field] = value, _a));
        };
        changeConfirm({
            onCancel: function () { return setValue(oldValue); },
            value: value,
            oldValue: oldValue,
        });
    };
    function filterOption(inputValue, option) {
        if (!inputValue)
            return false;
        var props = option.props;
        return props.children.includes(inputValue);
    }
    var onSearch = debounce(function (value) {
        if (value) {
            !mountFetchApi && fetchApiDataMemoized(value);
        }
    }, 500);
    function handleChange(value) {
        var _a;
        if (isMultipleMode) {
            handleMultipleValue(value);
        }
        if (!value) {
            setFieldsValue((_a = {},
                _a[field] = PrototypeCheck.isNumber(value) ? value.toString() : value,
                _a));
        }
        removeOptions();
        function removeOptions() {
            if (fetchApi && isMultipleMode) {
                setLocalOptions([]);
            }
        }
    }
    function handleMultipleValue(value) {
        var _a;
        var setFieldsValue = form.setFieldsValue;
        setFieldsValue((_a = {}, _a[field] = normalizeSetValue ? normalizeSetValue(value) : value, _a));
    }
    function onMultipleDeselect(value) {
        if (isMultipleMode) {
            var _a = form, setFieldsValue_1 = _a.setFieldsValue, getFieldValue_1 = _a.getFieldValue;
            var values = getFieldValue_1(field);
            setFieldsValue_1(normalizeDeValue
                ? normalizeDeValue(values, value)
                : values.filter(function (val) { return val.key !== value.key; }));
        }
        onDeselect && onDeselect(value);
    }
    function onRowCB(_fn, row) {
        var _a;
        var _b = form, setFieldsValue = _b.setFieldsValue, getFieldValue = _b.getFieldValue;
        var values = getFieldValue(field);
        setFieldsValue((_a = {},
            _a[field] = normalizeRowValue ? normalizeRowValue(values, row) : values.concat([row]),
            _a));
    }
    return (React.createElement(Form.Item, tslib_1.__assign({}, {
        label: label,
        labelCol: labelCol,
        wrapperCol: wrapperCol,
    }, { className: className }),
        getFieldDecorator(field, {
            initialValue: initialValue,
            rules: [
                { required: required, message: "\u8BF7\u9009\u62E9" + label },
                {
                    validator: function (rule, value, callback) {
                        return validator ? validator(rule, value, callback) : callback();
                    },
                },
            ],
        })(React.createElement(Input, { style: { display: 'none' } })),
        restProps.readOnly ? (restProps.render ? (restProps.render(getFieldValue(field), form)) : (React.createElement("span", null, getFieldValue(field)))) : (React.createElement(React.Fragment, null,
            React.createElement(Select, tslib_1.__assign({}, selectProps, { allowClear: allowClear, style: { width: '100%' }, showSearch: showSearch, placeholder: placeholder || "\u8BF7\u9009\u62E9" + label, onSearch: function (value) {
                    setInputValue(value);
                    onSearch(value);
                    tableRef.current && tableRef.current.setTableVisible(true);
                }, onSelect: function (value, option) {
                    onSelect && onSelect(value, option, form);
                    handleSelect(value);
                }, onChange: function (value, option) {
                    onChange && onChange(value, option, form);
                    handleChange(value);
                }, filterOption: filterOption, optionFilterProp: "children", onDeselect: onMultipleDeselect }, tslib_1.__assign({ mode: mode,
                disabled: disabled }, (labelInValue && { labelInValue: labelInValue }), (popupContainerId && {
                getPopupContainer: function () { return document.getElementById(popupContainerId); },
            }), (isMultipleMode && {
                notFoundContent: fetching ? React.createElement(Spin, { size: "small" }) : null,
            }), (tableConfig && { open: false })), { value: normalizeGetValue
                    ? normalizeGetValue(getFieldValue(field))
                    : getFieldValue(field) }), localOptions),
            tableConfig && (React.createElement(InputSearchTable, { onRowCB: onRowCB, inputValue: inputValue, tableConfig: tableConfig, ref: tableRef }))))));
};
export default FormSelect;
//# sourceMappingURL=index.js.map