/**
 * @jsx React.DOM
 */
/*jshint quotmark:false */
/*jshint white:false */
/*jshint trailing:false */
/*jshint newcap:false */
/*global Utils, ALL_TODOS, ACTIVE_TODOS, COMPLETED_TODOS,
    TodoItem, TodoFooter, React, Router*/

(function (window, React) {
    'use strict';

    window.ALL_TODOS = 'all';
    window.ACTIVE_TODOS = 'active';
    window.COMPLETED_TODOS = 'completed';

    var ENTER_KEY = 13;

    var TodoApp = React.createClass({
        getInitialState: function () {
            var todos = Utils.store('react-todos');
            return {
                todos: todos,
                nowShowing: ALL_TODOS,
                editing: null
            };
        },

        componentDidMount: function () {
            var router = Router({
                '/': this.setState.bind(this, {nowShowing: ALL_TODOS}),
                '/active': this.setState.bind(this, {nowShowing: ACTIVE_TODOS}),
                '/completed': this.setState.bind(this, {nowShowing: COMPLETED_TODOS})
            });
            router.init();
            this.refs.newField.getDOMNode().focus();
        },

        handleNewTodoKeyDown: function (event) {
            if (event.which !== ENTER_KEY) {
                return;
            }

            var val = this.refs.newField.getDOMNode().value.trim();
            var todos;
            var newTodo;

            if (val) {
                todos = this.state.todos;
                newTodo = {
                    id: Utils.uuid(),
                    title: val,
                    completed: false
                };
                this.setState({todos: todos.concat([newTodo])});
                this.refs.newField.getDOMNode().value = '';
            }

            return false;
        },

        toggleAll: function (event) {
            var checked = event.target.checked;

            this.state.todos.forEach(function (todo) {
                todo.completed = checked;
            });

            this.setState({todos: this.state.todos});
        },

        toggle: function (todo) {
            todo.completed = !todo.completed;
            this.setState({todos: this.state.todos});
        },

        destroy: function (todo) {
            var newTodos = this.state.todos.filter(function (candidate) {
                return candidate.id !== todo.id;
            });

            this.setState({todos: newTodos});
        },

        edit: function (todo, callback) {
            // refer to todoItem.js `handleEdit` for the reasoning behind the
            // callback
            this.setState({editing: todo.id}, function () {
                callback();
            });
        },

        save: function (todo, text) {
            todo.title = text;
            this.setState({todos: this.state.todos, editing: null});
        },

        cancel: function () {
            this.setState({editing: null});
        },

        clearCompleted: function () {
            var newTodos = this.state.todos.filter(function (todo) {
                return !todo.completed;
            });

            this.setState({todos: newTodos});
        },

        componentDidUpdate: function () {
            Utils.store('react-todos', this.state.todos);
        },

        render: function () {
            var footer = null;
            var main = null;
            var todoItems = {};
            var activeTodoCount;
            var completedCount;

            var shownTodos = this.state.todos.filter(function (todo) {
                switch (this.state.nowShowing) {
                case ACTIVE_TODOS:
                    return !todo.completed;
                case COMPLETED_TODOS:
                    return todo.completed;
                default:
                    return true;
                }
            }.bind(this));

            shownTodos.forEach(function (todo) {
                todoItems[todo.id] = (
                    <TodoItem
                        todo={todo}
                        onToggle={this.toggle.bind(this, todo)}
                        onDestroy={this.destroy.bind(this, todo)}
                        onEdit={this.edit.bind(this, todo)}
                        editing={this.state.editing === todo.id}
                        onSave={this.save.bind(this, todo)}
                        onCancel={this.cancel}
                    />
                );
            }.bind(this));

            activeTodoCount = this.state.todos.filter(function (todo) {
                return !todo.completed;
            }).length;

            completedCount = this.state.todos.length - activeTodoCount;

            if (activeTodoCount || completedCount) {
                footer =
                    <TodoFooter
                        count={activeTodoCount}
                        completedCount={completedCount}
                        nowShowing={this.state.nowShowing}
                        onClearCompleted={this.clearCompleted}
                    />;
            }

            if (this.state.todos.length) {
                main = (
                    <section id="main">
                        <input
                            id="toggle-all"
                            type="checkbox"
                            onChange={this.toggleAll}
                            checked={activeTodoCount === 0}
                        />
                        <ul id="todo-list">
                            {todoItems}
                        </ul>
                    </section>
                );
            }

            return (
                <div>
                    <header id="header">
                        <h1>todos</h1>
                        <input
                            ref="newField"
                            id="new-todo"
                            placeholder="What needs to be done?"
                            onKeyDown={this.handleNewTodoKeyDown}
                        />
                    </header>
                    {main}
                    {footer}
                </div>
            );
        }
    });

    React.renderComponent(<TodoApp />, document.getElementById('todoapp'));
    React.renderComponent(
        <div>
            <p>Double-click to edit a todo</p>
            <p>Created by{' '}
                <a href="http://github.com/petehunt/">petehunt</a>
            </p>
            <p>Part of{' '}<a href="http://todomvc.com">TodoMVC</a></p>
        </div>,
        document.getElementById('info'));
})(window, React);
