/* eslint react/prop-types: 0 */

import { Component, EditorSession,
  ProseEditorConfigurator as Configurator } from 'substance'
import NotesEditor from '../../notesEditor/NotesEditor'
import config from '../../notesEditor/config'
import Importer from '../../notesEditor/NotesEditorImporter'
import SimpleExporter from '../../SimpleEditorExporter'
import {isEmpty, find} from 'lodash'

class Notes extends Component {
  constructor (props) {
    super(props)

    this.resize = this.resize.bind(this)
    this.stopResize = this.stopResize.bind(this)
    this.notesPaneHeight
  }

  didMount () {
    this.context.editorSession.onUpdate('document', this.onNotesUpdated, this)
    this.context.editor.emit('ui:updated')
  }

  didUpdate () {
    this.el.el.style.height = this.notesPaneHeight + 'px'
    this.computeMainPane()
  }

  render ($$) {
    const { book, comments, containerId,
            history, disabled, fragment,
            trackChanges, trackChangesView,
            update, user } = this.props

    const { editorSession, configurator } = this._initNotesEditor()

    const resizer = $$('div').addClass('resize-area')

    const el = $$('div')
         .addClass('notes-container').append(resizer)

    if (!fragment) return el

    el.append($$(NotesEditor, {
      book,
      editorSession,
      comments,
      configurator,
      containerId,
      history,
      disabled,
      fragment,
      trackChanges,
      trackChangesView,
      update,
      user
    }))

    resizer.addEventListener('mousedown', this.initResize, false)

    return el
  }

  _initNotesEditor () {
    const configurator = new Configurator().import(config)
    configurator.addImporter('html', Importer)
    const importer = configurator.createImporter('html')

    const provider = this.getProvider()

    const notes = provider.computeEntries()
    const exporter = new SimpleExporter(configurator.config)
    let noteContent = ''

    for (var i = 0; i < notes.length; i++) {
      let isolatedNoteElement = exporter.createElement('isolated-note')
      isolatedNoteElement.setAttribute('data-parent-id', notes[i].id)
      isolatedNoteElement.innerHTML = notes[i]['note-content']
      noteContent += isolatedNoteElement.outerHTML
    }

    const doc = importer.importDocument(noteContent)

    const editorSession = new EditorSession(doc, {
      configurator: configurator
    })

    return {
      editorSession: editorSession,
      configurator: configurator
    }
  }

  initResize (e) {
    window.addEventListener('mousemove', this.resize, false)
    window.addEventListener('mouseup', this.stopResize, false)
  }

  resize (e) {
    this.notesPaneHeight = (this.el.el.offsetHeight + this.el.el.offsetTop - e.clientY)
    const scrollPane = document.getElementById('notes-editor-content-panel').children
    scrollPane[0].style.minHeight = this.notesPaneHeight - 40 + 'px'

    this.el.el.style.height = this.notesPaneHeight + 'px'

    this.computeMainPane()
  }

  stopResize (e) {
    window.removeEventListener('mousemove', this.resize, false)
    window.removeEventListener('mouseup', this.stopResize, false)
  }

  computeMainPane () {
    const mainPane = document.getElementById('content-panel')
    mainPane.style.height = this.el.el.offsetTop - 162 + 'px'
  }

  onNotesUpdated (change) {
    const notesProvider = this.getProvider()
    notesProvider.handleDocumentChange(change)

    const noteCreated = find(change.created, function (value, key) {
      return value.type === 'note'
    })

    const noteDeleted = find(change.deleted, function (value, key) {
      return value.type === 'note'
    })

    if (!isEmpty(noteCreated) || !isEmpty(noteDeleted)) {
      this.rerender()
      if (!isEmpty(noteCreated)) notesProvider.calloutSelected(noteCreated.id)
      return false
    }
  }

  getProvider () {
    return this.context.notesProvider
  }

  dispose () {
    const provider = this.getProvider()
    provider.off(this)
  }
}

export default Notes