/**
 * @jsx React.DOM
 */
/*jshint quotmark: false */
/*jshint white: false */
/*jshint trailing: false */
/*jshint newcap: false */
/*global React, Utils */
(function (window) {
    'use strict';

    var ESCAPE_KEY = 27;
    var ENTER_KEY = 13;

    window.TodoItem = React.createClass({
        handleSubmit: function () {
            var val = this.state.editText.trim();
            if (val) {
                this.props.onSave(val);
                this.setState({editText: val});
            } else {
                this.props.onDestroy();
            }
            return false;
        },
        handleEdit: function () {
            // react optimizes renders by batching them. This means you can't call
            // parent's `onEdit` (which in this case triggeres a re-render), and
            // immediately manipulate the DOM as if the rendering's over. Put it as a
            // callback. Refer to app.js' `edit` method
            this.props.onEdit(function () {
                var node = this.refs.editField.getDOMNode();
                node.focus();
                node.setSelectionRange(node.value.length, node.value.length);
            }.bind(this));
        },

        handleKeyDown: function (event) {
            if (event.keyCode === ESCAPE_KEY) {
                this.setState({editText: this.props.todo.title});
                this.props.onCancel();
            } else if (event.keyCode === ENTER_KEY) {
                this.handleSubmit();
            } else {
                this.setState({editText: event.target.value});
            }
        },

        handleChange: function (event) {
            this.setState({editText: event.target.value});
        },

        getInitialState: function () {
            return {editText: this.props.todo.title};
        },

        componentWillReceiveProps: function (nextProps) {
            if (nextProps.todo.title !== this.props.todo.title) {
                this.setState(this.getInitialState());
            }
        },

        render: function () {
            return (
                <li class={Utils.stringifyObjKeys({
                    completed: this.props.todo.completed,
                    editing: this.props.editing
                })}>
                    <div class="view">
                        <input
                            class="toggle"
                            type="checkbox"
                            checked={this.props.todo.completed ? 'checked' : null}
                            onChange={this.props.onToggle}
                        />
                        <label onDoubleClick={this.handleEdit}>
                            {this.props.todo.title}
                        </label>
                        <button class='destroy' onClick={this.props.onDestroy} />
                    </div>
                    <input
                        ref="editField"
                        class="edit"
                        value={this.state.editText}
                        onBlur={this.handleSubmit}
                        onChange={this.handleChange}
                        onKeyDown={this.handleKeyDown}
                    />
                </li>
            );
        }
    });
})(window);
