import React, {Component} from 'react';
import Autosuggest from 'react-autosuggest';
import Label from '../Label';
import Hint from '../Hint';
import ErrorLabel from '../ErrorLabel';
import PropTypes from 'prop-types';
import './style.scss';

const theme = {
    container: 'Autocomplete__container',
    containerOpen: 'Autocomplete__container_open',
    input: 'Autocomplete__input',
    inputOpen: 'Autocomplete__input_open',
    inputFocused: 'Autocomplete__input_focused',
    suggestionsContainer: 'Autocomplete__suggestions-container',
    suggestionsContainerOpen: 'Autocomplete__suggestions-container_open',
    suggestionsList: 'Autocomplete__suggestions-list',
    suggestion: 'Autocomplete__suggestion',
    suggestionHighlighted: 'Autocomplete__suggestion_highlighted',
};

class Autocomplete extends Component {
    static getAutocompleteClass(type) {
        switch (type) {
            case 'danger':
                return 'Autocomplete_danger';
            default:
                return '';
        }
    }

    constructor(props) {
        super(props);

        this.state = {
            value: props.value,
            suggestions: props.suggestions,
            isDisabled: props.isDisabled,
            errors: props.errors,
        };

        this.getSuggestions = this.getSuggestions.bind(this);
        this.getSuggestionValue = this.getSuggestionValue.bind(this);
        this.renderSuggestion = this.renderSuggestion.bind(this);
        this.onChange = this.onChange.bind(this);
        this.onSuggestionsFetchRequested = this.onSuggestionsFetchRequested.bind(this);
        this.onSuggestionsClearRequested = this.onSuggestionsClearRequested.bind(this);
    }

    componentWillReceiveProps(nextProps) {
        this.setState({
            errors: nextProps.errors.length ? nextProps.errors : [],
            type: nextProps.errors.length ? 'danger' : '',
            isDisabled: nextProps.isDisabled,
        });
    }

    onChange(event, {newValue}) {
        const country = this.props.suggestions.find((item) => item[this.props.titleField] === newValue);
        this.setState({value: newValue}, () => {
            this.props.onChange({[this.props.name]: country});
        });
    }

    onSuggestionsFetchRequested({value}) {
        this.setState({
            suggestions: this.getSuggestions(value),
        });
    }

    onSuggestionsClearRequested() {
        this.setState({
            suggestions: [],
        });
    }

    getSuggestions(value) {
        const inputValue = value.trim().toLowerCase();
        const inputLength = inputValue.length;

        return inputLength === 0 ? [] : this.props.suggestions.filter((item) =>
            item[this.props.titleField].toLowerCase().slice(0, inputLength) === inputValue);
    }

    getSuggestionValue(suggestion) {
        return suggestion[this.props.titleField];
    }

    renderSuggestion(suggestion) {
        return (
            <div>
                {suggestion[this.props.titleField]}
            </div>
        );
    }

    render() {
        const {value, suggestions} = this.state;
        const hint = this.props.hint
            ? (
                <Hint message={this.props.hint} />
            )
            : '';
        const label = this.props.label
            ? (
                <div>
                    <Label
                        label={this.props.label}
                        for=""
                        required={this.props.required}
                    />
                    {hint}
                </div>
            )
            : '';

        const inputProps = {
            placeholder: this.props.placeholder,
            value,
            onChange: this.onChange,
        };

        return (
            <div>
                {label}
                <div className={`Autocomplete ${Autocomplete.getAutocompleteClass(this.state.type)} ${this.state.isDisabled ? 'Autocomplete_disabled' : ''}`}>
                    <Autosuggest
                        suggestions={suggestions}
                        onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
                        onSuggestionsClearRequested={this.onSuggestionsClearRequested}
                        getSuggestionValue={this.getSuggestionValue}
                        renderSuggestion={this.renderSuggestion}
                        inputProps={inputProps}
                        theme={theme}
                    />
                    <div className="Autocomplete__helpers">
                        <ErrorLabel errors={this.state.errors} />
                    </div>
                </div>
            </div>
        );
    }
}

Autocomplete.propTypes = {
    errors: PropTypes.array,
    isDisabled: PropTypes.bool,
    placeholder: PropTypes.string,
    label: PropTypes.string,
    name: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
    required: PropTypes.bool,
    suggestions: PropTypes.array.isRequired,
    titleField: PropTypes.string.isRequired,
    hint: PropTypes.string,
    value: PropTypes.string,
};

Autocomplete.defaultProps = {
    errors: [],
    isDisabled: false,
    placeholder: 'Start to type',
    label: '',
    hint: '',
    value: '',
    required: false,
};

export default Autocomplete;
