import { get, pick } from 'lodash'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import {
  MultiAction,
  handleError,
  withFetching,
  withFilePreview,
  withFileDownload,
} from 'pubsweet-component-faraday-ui'
import { DragDropContext } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { change as changeForm, getFormSyncErrors, isPristine } from 'redux-form'
import { withModal } from 'pubsweet-component-modal/src/components'
import {
  compose,
  toClass,
  withProps,
  withHandlers,
  setDisplayName,
} from 'recompose'

import {
  addAuthor,
  deleteAuthor,
} from 'pubsweet-components-faraday/src/redux/authors'

import {
  uploadFile,
  deleteFile,
} from 'pubsweet-components-faraday/src/redux/files'

import { onChange, onSubmit, getInitialValues, validate } from './utils'

export default compose(
  withRouter,
  withFetching,
  withFilePreview,
  withFileDownload,
  connect(
    state => ({
      isPristine: isPristine('revision')(state),
      formErrors: getFormSyncErrors('revision')(state),
    }),
    { changeForm },
  ),
  withProps(() => ({
    modalKey: 'submitRevision',
  })),
  withModal(({ isFetching }) => ({
    isFetching,
    modalComponent: MultiAction,
  })),
  withHandlers({
    addResponseFile: ({
      setError,
      fragment,
      changeForm,
      setFetching,
    }) => file => {
      setFetching(true)
      return uploadFile({
        file,
        fragment,
        type: 'responseToReviewers',
      })
        .then(f => {
          setFetching(false)
          changeForm('revision', 'responseToReviewers.file', f)
        })
        .catch(err => {
          setFetching(false)
          handleError(setError)(err)
        })
    },
    deleteResponseFile: ({ setError, changeForm, setFetching }) => file => {
      setFetching(true)
      return deleteFile(file.id, 'responseToReviewers')
        .then(r => {
          setFetching(false)
          changeForm('revision', 'responseToReviewers.file', null)
        })
        .catch(err => {
          setFetching(false)
          handleError(setError)(err)
        })
    },
    addFile: () => uploadFile,
    addAuthor: () => addAuthor,
    deleteFile: () => deleteFile,
    deleteAuthor: () => deleteAuthor,
    previewFile: ({ previewFile }) => previewFile,
    downloadFile: ({ downloadFile }) => downloadFile,
  }),
  DragDropContext(HTML5Backend),
  toClass,
  withProps(props => ({
    submitRevision: {
      initialValues: getInitialValues(props.fragment),
      ...pick(props, [
        'addFile',
        'journal',
        'history',
        'fragment',
        'addAuthor',
        'showModal',
        'changeForm',
        'collection',
        'isFetching',
        'deleteFile',
        'currentUser',
        'setFetching',
        'previewFile',
        'downloadFile',
        'deleteAuthor',
        'getSignedUrl',
        'fetchingError',
        'addResponseFile',
        'deleteResponseFile',
      ]),
      onChange,
      onSubmit,
      validate,
      hasFormError: !props.isPristine && !!props.formErrors,
      responseFile: get(
        props,
        'formValues.revision.responseToReviewers.file',
        null,
      ),
    },
  })),

  setDisplayName('SubmitRevisionHOC'),
)