/**
 * amis-ui v6.12.0-beta.0
 * Copyright 2018-2025 fex
 */

import { __extends, __spreadArray, __read, __assign, __decorate, __metadata } from 'tslib';
import React__default from 'react';
import isInteger from 'lodash/isInteger';
import debounce from 'lodash/debounce';
import moment from 'moment';
import { autobind, themeable, localeable, uncontrollable } from 'amis-core';
import { Icon } from './icons.js';
import chain from 'lodash/chain';
import Input from './Input.js';
import Spinner from './Spinner.js';

var historyDefaultOptions = {
    enable: false,
    key: 'amis:search_history',
    limit: 5,
    dropdownClassName: ''
};
var SearchBox = /** @class */ (function (_super) {
    __extends(SearchBox, _super);
    function SearchBox() {
        var _this = this;
        var _a;
        _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
        _this.inputRef = React__default.createRef();
        _this.state = {
            isHistoryOpened: false,
            isFocused: false,
            inputValue: (_a = _this.props.value) !== null && _a !== void 0 ? _a : '',
            historyRecords: _this.getHistoryRecords()
        };
        _this.lazyEmitSearch = debounce(function () {
            var _a;
            var onSearch = _this.props.onSearch;
            onSearch === null || onSearch === void 0 ? void 0 : onSearch((_a = _this.state.inputValue) !== null && _a !== void 0 ? _a : '');
        }, 250, {
            leading: false,
            trailing: true
        });
        return _this;
    }
    SearchBox.prototype.componentDidUpdate = function (prevProps) {
        var _a;
        if (prevProps.value !== this.props.value) {
            this.setState({ inputValue: (_a = this.props.value) !== null && _a !== void 0 ? _a : '' });
        }
    };
    SearchBox.prototype.componentWillUnmount = function () {
        this.lazyEmitSearch.cancel();
    };
    SearchBox.prototype.handleActive = function () {
        var _a;
        var onActiveChange = this.props.onActiveChange;
        onActiveChange === null || onActiveChange === void 0 ? void 0 : onActiveChange(true);
        (_a = this.inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
    };
    SearchBox.prototype.handleCancel = function () {
        var _a = this.props, onActiveChange = _a.onActiveChange, onCancel = _a.onCancel, onChange = _a.onChange;
        onActiveChange === null || onActiveChange === void 0 ? void 0 : onActiveChange(false);
        onCancel === null || onCancel === void 0 ? void 0 : onCancel();
        this.setState({ inputValue: '' }, function () { return onChange === null || onChange === void 0 ? void 0 : onChange(''); });
    };
    SearchBox.prototype.handleChange = function (e) {
        var _this = this;
        var _a = this.props, searchImediately = _a.searchImediately, onChange = _a.onChange;
        var inputValue = e.currentTarget.value;
        this.setState({ inputValue: inputValue }, function () {
            onChange === null || onChange === void 0 ? void 0 : onChange(inputValue);
            searchImediately && _this.lazyEmitSearch();
        });
    };
    SearchBox.prototype.handleSearch = function () {
        var onSearch = this.props.onSearch;
        var inputValue = this.state.inputValue;
        var enable = this.getHistoryOptions().enable;
        if (enable) {
            this.insertHistoryRecord(inputValue);
            this.setState({ isFocused: false, isHistoryOpened: false });
        }
        onSearch === null || onSearch === void 0 ? void 0 : onSearch(inputValue || '');
    };
    SearchBox.prototype.handleKeyDown = function (e) {
        if (e.key === 'Enter') {
            this.handleSearch();
            e.preventDefault();
        }
    };
    SearchBox.prototype.handleClear = function () {
        var _this = this;
        var _a = this.props, searchImediately = _a.searchImediately, clearAndSubmit = _a.clearAndSubmit, onChange = _a.onChange;
        this.setState({ inputValue: '' }, function () {
            onChange === null || onChange === void 0 ? void 0 : onChange('');
            if (clearAndSubmit === true || searchImediately) {
                _this.lazyEmitSearch();
            }
        });
    };
    SearchBox.prototype.handleFocus = function () {
        var _a, _b;
        var enable = this.getHistoryOptions().enable;
        this.setState({ isFocused: true, isHistoryOpened: enable });
        (_b = (_a = this.props).onFocus) === null || _b === void 0 ? void 0 : _b.call(_a);
    };
    SearchBox.prototype.handleBlur = function (e) {
        var _a, _b;
        this.setState({ isFocused: false, isHistoryOpened: false });
        (_b = (_a = this.props).onBlur) === null || _b === void 0 ? void 0 : _b.call(_a);
    };
    SearchBox.prototype.handleHistoryRecordSelect = function (record) {
        var _this = this;
        this.setState({ inputValue: record.value, isHistoryOpened: false, isFocused: false }, function () { return _this.handleSearch(); });
    };
    /** 获取历史搜索配置 */
    SearchBox.prototype.getHistoryOptions = function () {
        var _a, _b;
        var history = this.props.history;
        var options = {
            enable: !!(history === null || history === void 0 ? void 0 : history.enable),
            key: (_a = history === null || history === void 0 ? void 0 : history.key) !== null && _a !== void 0 ? _a : historyDefaultOptions.key,
            limit: (history === null || history === void 0 ? void 0 : history.limit) && isInteger(history === null || history === void 0 ? void 0 : history.limit) && (history === null || history === void 0 ? void 0 : history.limit) > 0
                ? history === null || history === void 0 ? void 0 : history.limit
                : historyDefaultOptions.limit,
            dropdownClassName: (_b = history === null || history === void 0 ? void 0 : history.dropdownClassName) !== null && _b !== void 0 ? _b : ''
        };
        return options;
    };
    /** 获取历史记录 */
    SearchBox.prototype.getHistoryRecords = function () {
        var _a = this.getHistoryOptions(), key = _a.key, limit = _a.limit;
        try {
            var storageValues = localStorage.getItem(key);
            return chain(storageValues ? JSON.parse(storageValues) : [])
                .uniqBy('value')
                .orderBy(['timestamp'], ['desc'])
                .slice(0, limit)
                .value();
        }
        catch (_b) { }
        return [];
    };
    /** 清空历史记录 */
    SearchBox.prototype.clearHistoryRecords = function () {
        var key = this.getHistoryOptions().key;
        localStorage.removeItem(key);
        this.setState({ historyRecords: [] });
        return [];
    };
    /** 删除一条历史记录 */
    SearchBox.prototype.removeHistoryRecord = function (record) {
        var key = this.getHistoryOptions().key;
        var datasource = this.getHistoryRecords();
        var recordIndex = datasource.findIndex(function (item) { return item.value === record.value; });
        if (~recordIndex) {
            datasource.splice(recordIndex, 1);
            localStorage.setItem(key, JSON.stringify(datasource));
            this.setState({ historyRecords: datasource });
        }
        return datasource;
    };
    /** 新增一条历史记录 */
    SearchBox.prototype.insertHistoryRecord = function (value) {
        var datasource = this.getHistoryRecords();
        if (!value || datasource.find(function (item) { return item.value === value; })) {
            return datasource;
        }
        try {
            var _a = this.getHistoryOptions(), key = _a.key, limit = _a.limit;
            var newDatasource = chain(__spreadArray(__spreadArray([], __read(datasource), false), [
                { value: value, timestamp: moment().unix() }
            ], false))
                .orderBy(['timestamp'], ['desc'])
                .slice(0, limit)
                .value();
            localStorage.setItem(key, JSON.stringify(newDatasource));
            this.setState({ historyRecords: newDatasource });
            return newDatasource;
        }
        catch (_b) { }
        return datasource;
    };
    SearchBox.prototype.renderInput = function (isHistoryMode) {
        var _a = this.props, cx = _a.classnames, classPrefix = _a.classPrefix, active = _a.active, name = _a.name, className = _a.className, style = _a.style, disabled = _a.disabled, placeholder = _a.placeholder, mini = _a.mini, enhance = _a.enhance, clearable = _a.clearable, mobileUI = _a.mobileUI, __ = _a.translate, loading = _a.loading, loadingConfig = _a.loadingConfig, testIdBuilder = _a.testIdBuilder;
        var _b = this.state, isFocused = _b.isFocused, inputValue = _b.inputValue;
        var enable = this.getHistoryOptions().enable;
        return (React__default.createElement("div", __assign({ className: cx('SearchBox', enhance && 'SearchBox--enhance', !!isHistoryMode ? '' : className, disabled ? 'is-disabled' : '', isFocused ? 'is-focused' : '', !mini || active ? 'is-active' : '', { 'is-history': enable }, { 'is-mobile': mobileUI }), style: style }, testIdBuilder === null || testIdBuilder === void 0 ? void 0 : testIdBuilder.getTestId()),
            React__default.createElement(Input, { name: name, ref: this.inputRef, disabled: disabled, placeholder: __(placeholder || 'placeholder.enter'), value: inputValue !== null && inputValue !== void 0 ? inputValue : '', autoComplete: "off", onFocus: this.handleFocus, onBlur: this.handleBlur, onChange: this.handleChange, onKeyDown: this.handleKeyDown, testIdBuilder: testIdBuilder === null || testIdBuilder === void 0 ? void 0 : testIdBuilder.getChild('input') }),
            !mini && clearable && inputValue && !disabled ? (React__default.createElement("div", __assign({ className: cx('SearchBox-clearable'), onClick: this.handleClear }, testIdBuilder === null || testIdBuilder === void 0 ? void 0 : testIdBuilder.getChild('clear').getTestId()),
                React__default.createElement(Icon, { icon: "input-clear", className: "icon" }))) : null,
            !mini ? (React__default.createElement("a", __assign({ className: cx('SearchBox-searchBtn', {
                    'SearchBox-searchBtn--loading': loading
                }), onClick: this.handleSearch }, testIdBuilder === null || testIdBuilder === void 0 ? void 0 : testIdBuilder.getChild('search').getTestId()), loading ? (React__default.createElement(Spinner, { classnames: cx, classPrefix: classPrefix, className: cx('SearchBox-spinner'), spinnerClassName: cx('SearchBox-spinner-icon'), disabled: disabled, size: "sm", icon: "loading-outline", loadingConfig: loadingConfig })) : (React__default.createElement(Icon, { icon: "search", className: "icon" })))) : active ? (React__default.createElement("a", { className: cx('SearchBox-cancelBtn'), onClick: this.handleCancel },
                React__default.createElement(Icon, { icon: "close", className: "icon" }))) : (React__default.createElement("a", { className: cx('SearchBox-activeBtn'), onClick: this.handleActive },
                React__default.createElement(Icon, { icon: "search", className: "icon" })))));
    };
    SearchBox.prototype.renderTag = function (item, index) {
        var _this = this;
        var cx = this.props.classnames;
        return (React__default.createElement("span", { className: cx('Tag', 'SearchBox-history-tag'), key: index },
            React__default.createElement("span", { className: cx('SearchBox-history-tag-text'), onMouseDown: function (e) {
                    e.preventDefault();
                    _this.handleHistoryRecordSelect(item);
                } }, item.value),
            React__default.createElement("span", { className: cx("SearchBox-history-tag-close"), onMouseDown: function (e) {
                    e.preventDefault();
                    _this.removeHistoryRecord(item);
                } },
                React__default.createElement(Icon, { icon: "close", className: "icon" }))));
    };
    SearchBox.prototype.renderHitoryMode = function () {
        var _this = this;
        var _a = this.props, cx = _a.classnames, __ = _a.translate, className = _a.className, style = _a.style;
        var _b = this.state, isHistoryOpened = _b.isHistoryOpened, inputValue = _b.inputValue, historyRecords = _b.historyRecords;
        var dropdownClassName = this.getHistoryOptions().dropdownClassName;
        var showDropdown = isHistoryOpened && !inputValue && historyRecords.length > 0;
        return (React__default.createElement("div", { id: "searchbox-history", className: cx('SearchBox-history', className), style: style },
            this.renderInput(true),
            React__default.createElement("div", { className: cx('SearchBox-history-dropdown', dropdownClassName, {
                    'is-active': showDropdown
                }) },
                React__default.createElement("header", null,
                    React__default.createElement("h4", null, __('searchHistory')),
                    React__default.createElement("a", { onMouseDown: function (e) {
                            e.preventDefault();
                            _this.clearHistoryRecords();
                        } }, __('clear'))),
                React__default.createElement("div", { className: cx('SearchBox-history-content') }, historyRecords.map(function (item, index) { return _this.renderTag(item, index); })))));
    };
    SearchBox.prototype.render = function () {
        var enable = this.getHistoryOptions().enable;
        return enable ? this.renderHitoryMode() : this.renderInput();
    };
    SearchBox.defaultProps = {
        mini: true,
        enhance: false,
        clearable: false,
        searchImediately: true,
        history: historyDefaultOptions,
        clearAndSubmit: false
    };
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleActive", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleCancel", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleChange", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleSearch", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleKeyDown", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleClear", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleFocus", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], SearchBox.prototype, "handleBlur", null);
    return SearchBox;
}(React__default.Component));
var SearchBox$1 = themeable(localeable(uncontrollable(SearchBox, {
    active: 'onActiveChange',
    value: 'onChange'
})));

export { SearchBox, SearchBox$1 as default };
