import {Rx} from '@cycle/core';
import {h} from '@cycle/dom';

import TimeTravel from 'cycle-time-travel';

function todoView ({todo, complete}, index) {
  return (
    h('.todo', [
      h('span.title', todo),
      h('input.toggle', {type: 'checkbox', checked: complete, todoId: index})
    ])
  );
}

function todosView (todos) {
  return (
    h('.todos', todos.map(todoView))
  );
}

function todoAppView (todos) {
  const completeCount = todos.filter(todo => todo.complete).length;

  return (
    h('.todo-app', [
      h('.complete-count', `Complete: ${completeCount}`),
      h('input.new-todo'),
      h('button.add-todo', 'Add todo'),
      h('div', [h('button.clear-complete', 'Clear Complete')]),
      todosView(todos)
    ])
  );
}

function addTodo (todo) {
  return (todos) => {
    return todos.concat([{todo, complete: false}]);
  };
}

function toggleTodo ({complete, index}) {
  return (todos) => {
    const newTodos = todos.slice(); // duplicate

    newTodos[index].complete = complete;

    return newTodos;
  };
}

function clearComplete () {
  return (todos) => todos.filter(todo => !todo.complete);
}

export default function main ({DOM}) {
  const newTodoText$ = DOM
    .select('.new-todo')
    .events('input')
    .map(event => event.target.value);

  const addTodo$ = DOM
    .select('.add-todo')
    .events('click')
    .withLatestFrom(newTodoText$, (_, todoText) => addTodo(todoText));

  const toggleTodo$ = DOM
    .select('.toggle')
    .events('click')
    .map(event => ({complete: event.target.checked, index: event.target.todoId}))
    .map(toggleTodo);

  const clearComplete$ = DOM
    .select('.clear-complete')
    .events('click')
    .map(clearComplete);

  const startingTodos = [
    {todo: 'Display todos', complete: true},
    {todo: 'Add todos', complete: true},
    {todo: 'Toggle todo', complete: true},
    {todo: 'Clear complete', complete: true},
    {todo: 'Display complete count', complete: false}
  ];

  const action$ = Rx.Observable.merge(
    addTodo$, toggleTodo$, clearComplete$
  );

  const todos$ = action$
    .startWith(startingTodos)
    .scan((todos, action) => action(todos));

  const timeTravel = TimeTravel(DOM, [
    {stream: todos$, label: 'todos$', feature: true},
    {stream: addTodo$, label: 'addTodo$'},
    {stream: newTodoText$, label: 'newTodoText$'},
    {stream: toggleTodo$, label: 'toggleTodo$'},
    {stream: clearComplete$, label: 'clearComplete$'}
  ]);

  const view$ = timeTravel.timeTravel.todos$.map(todoAppView);

  return {
    DOM: Rx.Observable.combineLatest(view$, timeTravel.DOM,
      (...vtrees) => h('div', vtrees)
    )
  };
}


@@ -1127,43 +1127,36 @@
 %0A%7D%0A%0A
-export default function main
+function addTodoAction$
  (
-%7B
 DOM
-%7D
 ) %7B%0A
@@ -1274,24 +1274,14 @@
 %0A%0A  
-const addTodo$ =
+return
  DOM
@@ -1402,30 +1402,54 @@
 ));%0A
-%0A  const toggleTodo$ =
+%7D%0A%0Afunction toggleTodoAction$ (DOM) %7B%0A  return
  DOM
@@ -1597,24 +1597,27 @@
 eTodo);%0A
-%0A  const
+%7D%0A%0Afunction
  clearCo
@@ -1622,19 +1622,40 @@
 Complete
-$ =
+Action$ (DOM) %7B%0A  return
  DOM%0A   
@@ -1725,24 +1725,211 @@
 Complete);%0A%0A
+%7D%0A%0Afunction intent (DOM) %7B%0A  return Rx.Observable.merge(%0A    addTodoAction$(DOM),%0A    toggleTodoAction$(DOM),%0A    clearCompleteAction$(DOM)%0A  );%0A%7D%0A%0Aexport default function main (%7BDOM%7D) %7B%0A
   const star
@@ -2199,73 +2199,18 @@
 $ = 
-Rx.Observable.merge(%0A    addTodo$, toggleTodo$, clearComplete$%0A  
+intent(DOM
 );%0A%0A
@@ -2405,206 +2405,8 @@
 rue%7D
-,%0A    %7Bstream: addTodo$, label: 'addTodo$'%7D,%0A    %7Bstream: newTodoText$, label: 'newTodoText$'%7D,%0A    %7Bstream: toggleTodo$, label: 'toggleTodo$'%7D,%0A    %7Bstream: clearComplete$, label: 'clearComplete$'%7D
 %0A  %5D

Refactor intent into separate functions