import { __assign, __extends } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Component, createRef } from 'react';
import cn from 'classnames';
import memoize from '../utils/memorize-one';
import Input from '../input';
import Popover from '../popover';
import SelectMenu from '../select-menu';
import { DisabledContext } from '../disabled';
var caselessMatchFilterOption = SelectMenu.caselessMatchFilterOption;
var AutoComplete = (function (_super) {
    __extends(AutoComplete, _super);
    function AutoComplete(props) {
        var _this = _super.call(this, props) || this;
        _this.blurHandlerPrevented = false;
        _this.refMenuItemList = createRef();
        _this.onSearchTextChange = function (e) {
            var searchText = e.target.value;
            var value = _this.props.valueFromOptions
                ? _this.getSelectedValueFromSearchText(searchText)
                : searchText;
            _this.setState({
                searchText: searchText,
                value: value,
            });
            if (!_this.state.open) {
                _this.open();
            }
            _this.props.onSearch && _this.props.onSearch(searchText);
            _this.props.onChange && _this.props.onChange(value);
        };
        _this.onSearchKeyDown = function (e) {
            switch (e.key) {
                case 'Escape':
                    _this.close();
                    break;
                case 'Tab':
                    _this.close();
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    if (_this.state.open) {
                        _this.moveFocusIndexDown();
                    }
                    break;
                case 'ArrowUp': {
                    e.preventDefault();
                    if (_this.state.open) {
                        _this.moveFocusIndexUp();
                    }
                    break;
                }
                case 'Enter': {
                    if (_this.state.open) {
                        _this.selectCurrentFocusIndex(e);
                    }
                    break;
                }
                default:
            }
        };
        _this.onSearchBlur = function () {
            if (_this.props.valueFromOptions) {
                setTimeout(function () {
                    if (!_this.blurHandlerPrevented) {
                        var _a = _this.state, searchText = _a.searchText, value = _a.value;
                        var selectedValue = _this.getSelectedValueFromSearchText(searchText);
                        if (selectedValue) {
                            if (selectedValue !== value) {
                                _this.props.onSelect && _this.props.onSelect(selectedValue);
                                _this.props.onChange && _this.props.onChange(selectedValue);
                            }
                        }
                        else {
                            _this.props.onSelect && _this.props.onSelect(null);
                            _this.props.onChange && _this.props.onChange(null);
                        }
                    }
                    _this.blurHandlerPrevented = false;
                }, 100);
            }
        };
        _this.getSelectedValueFromSearchText = function (searchText) {
            var selectedValue = null;
            _this.getTransformedItemConfigsFromProps().some(function (item) {
                if (item.searchContent === searchText ||
                    item.content === searchText ||
                    item.value === searchText) {
                    selectedValue = item.value;
                    return true;
                }
                return false;
            });
            return selectedValue;
        };
        _this.onSelect = function (value) {
            _this.blurHandlerPrevented = true;
            _this.setState({
                value: value,
            });
            _this.props.onSelect && _this.props.onSelect(value);
            _this.props.onChange && _this.props.onChange(value);
            _this.close();
        };
        _this.getTransformedItemConfigs = memoize(function (valueField, textField, contentField, items, data) {
            return (items || data || []).map(function (item) {
                if (typeof item === 'string' || typeof item === 'number') {
                    return {
                        value: item,
                        content: item,
                    };
                }
                if (typeof item === 'object') {
                    return __assign(__assign({}, item), { value: item[valueField], content: item[contentField] || item[textField] || item[valueField] });
                }
                throw new Error('AutoComplete unresolvable option!');
            });
        });
        _this.getDisplayText = function () {
            var value = _this.state.value;
            var displayValue = value || '';
            var item = _this.getItemByValue(value);
            if (item) {
                if (typeof item.searchContent === 'string') {
                    displayValue = item.searchContent;
                }
                else if (typeof item.content === 'string') {
                    displayValue = item.content;
                }
            }
            return displayValue;
        };
        _this.open = function () {
            var newState = {
                open: true,
                searchText: _this.getDisplayText() || '',
            };
            _this.setState(newState);
        };
        _this.close = function () {
            _this.setState({
                open: false,
            });
        };
        _this.togglePopoverOpen = function () {
            if (_this.state.open) {
                _this.close();
            }
            else {
                _this.open();
            }
        };
        _this.iterateItems = function (items, value) {
            var result = null;
            (items || []).some(function (item) {
                if (item && item.value === value) {
                    result = item;
                    return true;
                }
                return false;
            });
            return result;
        };
        _this.getItemByValue = function (value) {
            return _this.iterateItems(_this.getTransformedItemConfigsFromProps(), value);
        };
        _this.moveFocusIndexDown = function () {
            var menuList = _this.refMenuItemList.current;
            if (menuList) {
                return menuList.moveFocusIndexDown();
            }
        };
        _this.moveFocusIndexUp = function () {
            var menuList = _this.refMenuItemList.current;
            if (menuList) {
                return menuList.moveFocusIndexUp();
            }
        };
        _this.selectCurrentFocusIndex = function (e) {
            var menuList = _this.refMenuItemList.current;
            if (menuList) {
                return menuList.selectCurrentFocusIndex(e);
            }
        };
        _this.state = {
            open: false,
            value: props.initialValue || props.value || null,
            searchText: '',
        };
        return _this;
    }
    AutoComplete.getDerivedStateFromProps = function (props, state) {
        var value = props.value;
        return value === undefined || state.value === value
            ? null
            : {
                value: props.value,
            };
    };
    AutoComplete.prototype.getTransformedItemConfigsFromProps = function () {
        var _a = this.props, items = _a.items, data = _a.data, textField = _a.textField, valueField = _a.valueField, contentField = _a.contentField;
        return this.getTransformedItemConfigs(valueField, textField, contentField, items, data);
    };
    AutoComplete.prototype.render = function () {
        var _a = this.props, width = _a.width, placeholder = _a.placeholder, className = _a.className, popupClassName = _a.popupClassName, _b = _a.disabled, disabled = _b === void 0 ? this.context.value : _b, inline = _a.inline;
        var _c = this.state, open = _c.open, searchText = _c.searchText;
        var items = this.getTransformedItemConfigsFromProps();
        var prefixCls = 'zent-auto-complete';
        var displayValue = this.getDisplayText();
        return (_jsxs(Popover, __assign({ position: Popover.Position.AutoBottomLeft, visible: open, className: cn(prefixCls, popupClassName), onVisibleChange: this.togglePopoverOpen, cushion: 4 }, { children: [_jsx(Popover.Trigger.Click, { children: _jsx(Input, { className: cn('zent-auto-complete', className, {
                            active: open,
                        }), value: (open ? searchText : displayValue) || '', placeholder: placeholder, onChange: this.onSearchTextChange, onKeyDown: this.onSearchKeyDown, onBlur: this.onSearchBlur, disabled: disabled, width: width, inline: inline }, void 0) }, void 0), _jsx(Popover.Content, { children: _jsx(SelectMenu, { ref: this.refMenuItemList, items: items, value: this.state.value, searchText: this.state.searchText, onSelect: this.onSelect, filterOption: this.props.filterOption, onRequestClose: this.close }, void 0) }, void 0)] }), void 0));
    };
    AutoComplete.defaultProps = {
        filterOption: caselessMatchFilterOption,
        valueFromOptions: false,
        valueField: 'value',
        contentField: 'content',
        textField: 'text',
        width: 160,
    };
    AutoComplete.contextType = DisabledContext;
    return AutoComplete;
}(Component));
export { AutoComplete };
export default AutoComplete;
