import React, { PropTypes } from 'react';
import classSet from 'classnames';

import Suggest from '../Suggest';
import PickerItem from './PickerItem.jsx';

const BACKSPACE_KEY = 8;
const DELETE_KEY = 46;

var Picker = React.createClass({
    displayName: 'Picker',

    getInitialState: function () {
        var props = this.props;

        return {
            selectedIndex: -1,
            focused: false,
            items: props.value || props.defaultValue
        };
    },

    componentWillReceiveProps: function (nextProps) {
        if (nextProps.value) {
            this.setState({
                selectedIndex: -1,
                items: nextProps.value
            });
        }
    },

    componentDidUpdate: function (prevProps, prevState) {
        var { items, focused } = this.state;

        if (this.refs.suggest && focused) {
            this.refs.suggest.focus();
        }

        if (this.props.onChange &&
            items.length !== prevState.items.length) {
            this.props.onChange(items.slice(0));
        }
    },

    focus: function () {
        this.refs.suggest.focus();
    },

    value: function () {
        return this.state.items.slice(0);
    },

    _handlePickerFocus: function () {
        this.setState({ focused: true });

        if (this.props.onFocus) {
            this.props.onFocus();
        }
    },

    _handlePickerBlur: function () {
        this.setState({ focused: false });

        if (this.props.onBlur) {
            this.props.onBlur();
        }
    },

    _handleItemClick: function (index, event) {
        event.preventDefault();

        var items = this.state.items.slice(0);

        items.splice(index, 1);

        this.setState({ items });
    },

    _handleSuggestBlur: function () {
        this.setState({
            focused: false,
            selectedIndex: -1
        });
    },

    _handleSuggestKeydown: function (event) {
        var value = event.target.value;
        var keyCode = event.keyCode;

        var index = this.state.selectedIndex;
        var items = this.state.items.slice(0);

        if (index !== -1) {
            if (keyCode === BACKSPACE_KEY || keyCode === DELETE_KEY) {
                items.splice(index, 1);

                this.setState({
                    selectedIndex: -1,
                    items
                });
            } else {
                this.setState({
                    selectedIndex: -1
                });
            }
        } else if (!value.length && keyCode === BACKSPACE_KEY) {
            this.setState({
                selectedIndex: items.length - 1
            });
        }
    },

    _handleSuggestSelect: function (payload) {
        var items = this.state.items.slice(0);

        items.push(payload.item);

        this.setState({
            items,
            focused: true
        });

        this.refs.picker.focus();

        if (this.props.onSuggestSelect) {
            this.props.onSuggestSelect(payload);
        }
    },

    _renderItem: function (item, index) {
        var content = this.props.renderItem ?
            this.props.renderItem(item, index, this.state.selectedIndex) :
            (
                <PickerItem avatar={item.avatar}
                    title={item.title}
                    selected={index === this.state.selectedIndex} />
            );

        return (
            <div className="picker__item"
                key={'item' + index}
                onClick={this._handleItemClick.bind(null, index)}>
                {content}
            </div>
        );
    },

    render: function () {
        var props = this.props;
        var items = this.state.items;
        var filled = !props.multiple && items.length === 1;

        var className = classSet({
            picker: true,
            picker_focused: this.state.focused,
            picker_multiple: props.multiple,
            picker_disabled: !props.source && !items.length,
            picker_multiline: props.multiline,
            [ 'picker_width_' + props.width ]: props.width
        });

        var suggest = null;

        if (props.source && !filled) {
            suggest = (
                <Suggest ref="suggest"
                    placeholder={items.length ? null : props.placeholder}
                    transparent={true}
                    width="available"
                    source={props.source}
                    renderItem={props.renderSuggestion}
                    onSelect={this._handleSuggestSelect}
                    onBlur={this._handleSuggestBlur}
                    onKeyDown={this._handleSuggestKeydown} />
            );
        }

        return (
            <div ref="picker"
                className={className}
                onFocus={this._handlePickerFocus}
                onBlur={this._handlePickerBlur}
                tabIndex={0}>
                <div className="picker__items">
                    {items.map(this._renderItem)}
                </div>
                {suggest}
            </div>
        );

        return null;
    }
});

Picker.defaultProps = {
    tabIndex: 0,
    defaultValue: [],
    multiple: true
};

Picker.propTypes = {
    source: PropTypes.func,
    renderItem: PropTypes.func,
    renderSuggestion: PropTypes.func,
    defaultValue: PropTypes.array,
    value: PropTypes.array,
    onChange: PropTypes.func,
    onSuggestSelect: PropTypes.func,
    onFocus: PropTypes.func,
    onBlur: PropTypes.func,
    placeholder: PropTypes.string,
    tabIndex: PropTypes.number,
    width: PropTypes.oneOf([ 'available' ]),
    multiple: PropTypes.bool,
    multiline: PropTypes.bool
};

export default Picker;
