import React from 'react';
import InputWithOptions from '../InputWithOptions';
import Input from '../Input';
import { classes } from './MultiSelectCheckbox.st.css.js';
import { listItemSelectBuilder } from '../ListItemSelect';
import { listItemSectionBuilder } from '../ListItemSection';
const OPEN_DROPDOWN_CHARS = ['Enter', 'ArrowDown', 'Space', ' '];
class MultiSelectCheckbox extends InputWithOptions {
    createOptions(options) {
        return options.map(option => {
            if (this._isUsingCustomRenderFunction(option)) {
                return this._patchOptionWithSelectionMechanism(option);
            }
            else if (this._isDivider(option)) {
                return listItemSectionBuilder({
                    type: 'divider',
                    ...option,
                });
            }
            else {
                const builder = listItemSelectBuilder({
                    ...option,
                    checkbox: true,
                    title: option.value,
                    label: option.label,
                });
                return this._patchOptionWithSelectionMechanism(builder);
            }
        });
    }
    _patchOptionWithSelectionMechanism(option) {
        const value = option.value;
        return {
            ...option,
            value: props => value({
                ...props,
                selected: this.isSelectedId(option.id),
            }),
        };
    }
    _isUsingCustomRenderFunction({ value }) {
        return typeof value === 'function';
    }
    _isDivider({ value }) {
        return value === '-';
    }
    isSelectedId(optionId) {
        return this.props.selectedOptions.indexOf(optionId) !== -1;
    }
    dropdownAdditionalProps() {
        const { predicate, emptyStateMessage, enableSearch } = this.props;
        const filterFunc = this.state.isEditing ? predicate : () => true;
        let options = enableSearch
            ? this.createOptions(this.props.options.filter(filterFunc))
            : this.createOptions(this.props.options);
        if (options.length === 0 && emptyStateMessage) {
            options = [
                {
                    id: 'empty-state-message',
                    value: emptyStateMessage,
                    disabled: true,
                },
            ];
        }
        return {
            options,
            closeOnSelect: false,
            selectedHighlight: false,
        };
    }
    selectedOptionsToText() {
        return this.props.selectedOptions
            .map(selectedOption => this.props.options.find(option => option.id === selectedOption))
            .filter(selectedOption => selectedOption)
            .map(this.props.valueParser)
            .join(this.props.delimiter);
    }
    inputAdditionalProps() {
        if (this.props.enableSearch) {
            const { selectedOptions, getSelectedOptionsText } = this.props;
            const selectedOptionsText = !!getSelectedOptionsText
                ? getSelectedOptionsText(selectedOptions.length)
                : this.selectedOptionsToText();
            const value = !this._focused && selectedOptions.length > 0
                ? selectedOptionsText
                : this.props.value;
            return {
                readOnly: this.props.readOnly,
                disableEditing: false,
                value,
                placeholder: selectedOptions.length > 0
                    ? selectedOptionsText
                    : this.props.placeholder,
            };
        }
        else {
            const value = this.props.value !== undefined
                ? this.props.value
                : this.selectedOptionsToText();
            return {
                readOnly: this.props.readOnly,
                disableEditing: this.props.disableEditing,
                inputElement: this.props.inputElement ?? (React.createElement(Input, { textOverflow: "ellipsis", disableEditing: this.props.disableEditing })),
                value,
            };
        }
    }
    inputClasses() {
        return this.props.enableSearch ? '' : classes.showPointer;
    }
    _onSelect(option) {
        this.showOptions();
        if (this.closeOnSelect()) {
            this.setState({ showOptions: false });
        }
        // The option object is not the original since it was injected a checkbox
        const originalOption = this.props.options.find(op => option.id === op.id);
        if (this.isSelectedId(originalOption.id)) {
            this.props.onDeselect &&
                this.props.onDeselect(originalOption.id, originalOption);
        }
        else {
            this.props.onSelect &&
                this.props.onSelect(originalOption.id, originalOption);
        }
        if (this.props.enableSearch && this.props.onChange) {
            this.props.onChange({ target: { value: '' } });
            this.setState({ isEditing: false });
        }
    }
    _onOpenChange(event) {
        if (!this.props.readOnly) {
            this.state.showOptions ? this.hideOptions() : this.showOptions();
        }
    }
    _onKeyDown(event) {
        if (OPEN_DROPDOWN_CHARS.includes(event.key) &&
            !(this.state.isEditing && event.key === ' ')) {
            event.preventDefault();
            this.showOptions();
        }
        else if (this.props.enableSearch &&
            event.key !== 'ArrowDown' &&
            event.key !== 'ArrowUp') {
            this.setState({ isEditing: true });
        }
        this.dropdownLayout && this.dropdownLayout._onSelectListKeyDown(event);
    }
    _onFocus(e) {
        if (this.props.disabled) {
            return;
        }
        this._focused = true;
        if (this.props.onFocus) {
            this.props.onFocus(e);
            this.setState({ isEditing: false });
        }
    }
}
MultiSelectCheckbox.displayName = 'MultiSelectCheckbox';
MultiSelectCheckbox.defaultProps = {
    ...InputWithOptions.defaultProps,
    delimiter: ', ',
    selectedOptions: [],
    closeOnSelect: false,
    valueParser: option => option.label || option.value,
    readOnly: false,
    disableEditing: true,
    clearOnBlur: true,
    predicate: () => true,
    enableSearch: false,
};
export default MultiSelectCheckbox;
//# sourceMappingURL=MultiSelectCheckbox.js.map