import {run, Rx} from '@cycle/core';
import {makeDOMDriver, h} from '@cycle/dom';
import CycleTimeTravel from 'cycle-time-travel';
import $ from 'jquery';
import _ from 'lodash';
import rhyme from 'rhyme';

Rx.config.longStackSupport = true;

function log (label) {
  return console.log.bind(console, label);
}

function keyPressed (key, number) {
  return ev => {
    return ev.key === key || ev.keyIdentifier === key || ev.keyCode === number;
  };
}

function addRhyme (wordToRhyme, rhyme) {
  return text => {
    let availableRhymes = rhyme.rhyme(wordToRhyme);

    if (availableRhymes === undefined) {
      availableRhymes = [];
    }

    const madeRhyme = _.sample(availableRhymes) || '';

    return text + madeRhyme.toLowerCase();
  };
}

function updateText (text) {
  return oldText => text;
}

function main ({DOM}) {
  const textUpdate$ = DOM.select('.text').events('input')
    .map(event => event.target.value)
    .startWith('');

  const keyPress$ = DOM.select('.container').events('keydown');

  const tabPress$ = keyPress$.filter(keyPressed('Tab', 9));

  const rhymePress$ = Rx.Observable.merge(
    tabPress$,
    DOM.select('.rhyme').events('click')
  );

  const wordToRhyme$ = textUpdate$.map(
    text => _.chain(text.split('\n'))
      .map(_.trim)
      .select(line => line !== '')
      .map(line => line.split(' '))
      .thru(lines => {
        if (lines.length > 1) {
          return lines[lines.length - 2];
        }

        return _.last(lines);
      })
      .last().value()
  );

  const rhyme$ = Rx.Observable.fromCallback(rhyme)();

  rhymePress$.forEach(ev => ev.preventDefault());

  const action$ = Rx.Observable.merge(
    rhymePress$.withLatestFrom(wordToRhyme$, rhyme$, (ev, wordToRhyme, rhyme) => addRhyme(wordToRhyme, rhyme)),
    textUpdate$.map(text => updateText(text))
  );

  const editorText$ = action$.scan((text, action) => action(text), '');

  return {
    DOM: Rx.Observable.combineLatest(
      editorText$,
      wordToRhyme$,
      (text, timeTravelBar, wordToRhyme) => (
        h('.container', [
          h('h1', 'Ghostwriter'),
          h('.app-inner', [
            h('button.rhyme', 'RHYME'),
            h('textarea.text', {rows: 18, value: text})
          ])
        ])
      ))
  };
}

const drivers = {
  DOM: makeDOMDriver('.app')
};

$(() => run(main, drivers));

@@ -482,17 +482,29 @@
 me, rhym
-e
+ingDictionary
 ) %7B%0A  re
@@ -508,20 +508,21 @@
  return 
+sta
 te
-xt
  =%3E %7B%0A  
@@ -549,17 +549,29 @@
 s = rhym
-e
+ingDictionary
 .rhyme(w
@@ -587,77 +587,113 @@
 e);%0A
-%0A    if (availableRhymes === undefined) %7B%0A      availableRhymes = %5B%5D;
+    state.notification = %22%22%0A%0A    if (_.isEmpty(availableRhymes)) %7B%0A      state.notification = %22No Rhymes%22
 %0A   
@@ -763,16 +763,36 @@
  return 
+%7B%0A      text: state.
 text + m
@@ -817,71 +817,185 @@
 se()
-;%0A  %7D;%0A%7D%0A%0Afunction updateText (text) %7B%0A  return oldText =%3E text
+,%0A      notification: state.notification%0A    %7D;%0A  %7D;%0A%7D%0A%0Afunction updateText (textEnteredByUser) %7B%0A  return state =%3E (%7Btext: textEnteredByUser, notification: state.notification%7D)
 ;%0A%7D%0A
@@ -1118,27 +1118,8 @@
 lue)
-%0A    .startWith('')
 ;%0A%0A 
@@ -1703,17 +1703,29 @@
 nst rhym
-e
+ingDictionary
 $ = Rx.O
@@ -1897,17 +1897,29 @@
 e$, rhym
-e
+ingDictionary
 $, (ev, 
@@ -1935,17 +1935,29 @@
 me, rhym
-e
+ingDictionary
 ) =%3E add
@@ -1979,17 +1979,29 @@
 me, rhym
-e
+ingDictionary
 )),%0A    
@@ -2056,26 +2056,86 @@
   const 
-editorText
+initialState = %7B%0A    text: '',%0A    notification: ''%0A  %7D%0A%0A  const state
 $ = acti
@@ -2144,20 +2144,21 @@
 $.scan((
+sta
 te
-xt
 , action
@@ -2173,148 +2173,194 @@
 ion(
-text), '');%0A%0A  return %7B%0A    DOM: Rx.Observable.combineLatest(%0A      editorText$,%0A      wordToRhyme$,%0A      (text, timeTravelBar, wordToRhyme
+state), initialState)%0A    .startWith(initialState)%0A    .do(function(state)%7B%0A      console.log(%22state%22, JSON.stringify(state))%0A    %7D)%0A%0A  return %7B%0A    DOM: state$.map((%7Btext, notification%7D
 ) =%3E
@@ -2545,16 +2545,62 @@
 : text%7D)
+,%0A            h('.notification', notification)
 %0A       

Add 'No Rhymes' notification when no rhymes are found