import { merge } from 'most'
import keycode from 'keycode'

import { streamDom } from '../stream-dom'
import { findSelectorTarget } from './findSelectorTarget'
import * as actions from '../model/todo-actions'

export function TodoList({
  properties: { todos$ },
  eventStreams: { todoAction },
  createEventStream,
  attachEventStream
}) {
  const change$ = createEventStream()
  const keydown$ = createEventStream()
  const click$ = createEventStream()

  const findTodoSelectorTarget = findSelectorTarget('.todo')

  attachEventStream(todoAction, change$
    .filter(e => e.target.matches('.toggle'))
    .filter(findTodoSelectorTarget)
    .map(e => actions.toggle(e.selectorTarget.id, e.target.checked))
  )

  attachEventStream(todoAction, keydown$
    .filter(e => e.target.matches('.edit') && isCommitEdit(e))
    .filter(findTodoSelectorTarget)
    .map(e => {
      const { id } = e.selectorTarget
      const trimmedText = e.target.value.trim()
      return trimmedText.length === 0 ? actions.destroy(id) : actions.edit(id, trimmedText)
    })
  )

  attachEventStream(todoAction, click$
    .filter(findTodoSelectorTarget)
    .filter(e => e.target.matches('.destroy'))
    .map(e => actions.destroy(e.selectorTarget.id))
  )

  return (
    <ul class="todo-list" e:change={change$} e:keydown={keydown$} e:click={click$}>
      {todos$.map(todos => todos.map(todo => <Todo todo={todo} />))}
    </ul>
  )
}

function Todo({
  properties: { todo },
  createEventStream
}) {
  const { id, text, completed } = todo

  const doubleClick$ = createEventStream()
  const blur$ = createEventStream()
  const keyDown$ = createEventStream()
  const enterKeyDown$ = keyDown$.filter(isCommitEdit)
  const abortEdit$ = merge(
    keyDown$.filter(e => e.keyCode === keycode('Escape')),
    blur$
  )

  const editing$ =
    merge(
      doubleClick$.map(() => true),
      merge(enterKeyDown$, abortEdit$).map(() => false)
    )
    .skipRepeats()
    .startWith(false)

  const class$ = editing$.map(editing => {
    const editingClass = editing ? 'editing' : ''
    const completedClass = completed ? 'completed' : ''
    return `todo ${editingClass} ${completedClass}`
  })

  doubleClick$.observe(({ currentTarget }) => setTimeout(() => {
    const inputNode = currentTarget.querySelector('.edit')
    inputNode.focus()
    inputNode.selectionStart = inputNode.value.length
  }))

  return (
    <li id={id} class={class$} e:dblclick={doubleClick$}>
      <div class="view">
        <input class="toggle" type="checkbox" checked={!!completed} />
        <label>{text}</label>
        <button class="destroy" />
      </div>
      <input class="edit" value={text} e:blur={blur$} e:keydown={keyDown$} />
    </li>
  )
}

function isCommitEdit(e) {
  return e.keyCode === keycode('Enter')
}

@@ -1553,32 +1553,237 @@
 teEventStream()%0A
+  // Ignore double clicks on the edit field to avoid interfering with%0A  // double clicking to select a word in the input.%0A  const doubleClickForEdit$ = doubleClick$.filter(e =%3E !e.target.matches('.edit'))%0A
   const blur$ = 
@@ -2048,20 +2048,26 @@
 lick
-$.map(() =%3E 
+ForEdit$.constant(
 true
@@ -2112,18 +2112,17 @@
 t$).
-map(() =%3E 
+constant(
 fals
@@ -2134,27 +2134,8 @@
   )%0A
-    .skipRepeats()%0A
     
@@ -2373,16 +2373,23 @@
 bleClick
+ForEdit
 $.observ

Stop consuming dblclick on edit input