import { actions } from 'pubsweet-client'
import { SubmissionError } from 'redux-form'
import { get, find, capitalize, pick } from 'lodash'
import { update, create } from 'pubsweet-client/src/helpers/api'

export const parseTitle = version => {
  const title = get(version, 'metadata.title')
  if (title) {
    return title.replace(/<p[^>]*>/g, '').replace(/<\/p>/g, '')
  }
  return 'Untitled'
}

export const parseAuthor = version => {
  const author = find(get(version, 'authors'), a => a.isSubmitting)
  return author ? `${author.firstName} ${author.lastName}` : 'N/A'
}

export const parseType = version => {
  const type = get(version, 'metadata.type')
  return type ? type.replace('-', ' ') : 'N/A'
}

export const parseVersion = version => ({
  author: parseAuthor(version),
  title: parseTitle(version),
  type: parseType(version),
  abstract: get(version, 'metadata.abstract'),
  version: get(version, 'version'),
})

export const parseJournalIssue = (journal, metadata) =>
  journal.issueTypes.find(t => t.value === get(metadata, 'issue'))

export const getUserTitle = (journal, title) =>
  get(journal.title.find(t => t.value === title), 'label')

export const mapStatusToLabel2 = status => {
  switch (status) {
    case 'he-invited':
      return 'Handling Editor Assigned'
    case 'submitted':
      return 'Submitted'
    case 'under-review':
      return 'Under Review'
    default:
      return 'Draft'
  }
}

export const mapStatusToLabel = ({ visibleStatus, status }) => {
  if (visibleStatus) {
    return visibleStatus
  } else if (status) {
    return capitalize(status)
  }
  return 'Draft'
}

export const handleError = fn => e => {
  fn(
    get(
      JSON.parse(e.response),
      'error',
      'Something went wrong. Please try again.',
    ),
  )
}

export const handleFormError = error => {
  const err = get(error, 'response')
  if (err) {
    const errorMessage =
      get(JSON.parse(err), 'error') || get(JSON.parse(err), 'message')
    throw new SubmissionError({
      _error: errorMessage || 'Something went wrong. Please try again.',
    })
  }
}

// #region Validators
const emailRegex = new RegExp(
  /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, //eslint-disable-line
)

export const emailValidator = value =>
  emailRegex.test(value) ? undefined : 'Invalid email'

const digitRegex = new RegExp(/^[0-9]*$/)
export const digitValidator = value =>
  digitRegex.test(value) ? undefined : 'Only digits are allowed.'

export const manuscriptIdSizeValidator = size => value =>
  value.length !== size ? `The ID must be ${size} digits long.` : undefined
// #endregion

export const redirectToError = redirectFn => err => {
  const errorText = get(JSON.parse(err.response), 'error')
  redirectFn(
    '/error-page',
    errorText || 'Something went wrong. Please try again.',
  )
}
export const parseSearchParams = url => {
  const params = new URLSearchParams(url)
  const parsedObject = {}
  /* eslint-disable */
  for ([key, value] of params) {
    parsedObject[key] = value
  }
  /* eslint-enable */
  return parsedObject
}

export const parseUpdateUser = values => {
  const valuesToSave = [
    'admin',
    'firstName',
    'lastName',
    'affiliation',
    'title',
    'country',
    'roles',
    'editorInChief',
    'handlingEditor',
    'isActive',
    'username',
  ]

  return pick(values, valuesToSave)
}

// TODO: move to a dataservice
export const onSubmitUser = (values, dispatch, { setEditMode }) =>
  update(`/users/${values.id}`, parseUpdateUser(values))
    .then(user => {
      setEditMode(false)()
      dispatch(actions.getCurrentUser())
    })
    .catch(handleFormError)

export const saveUserDetails = (userId, values) => dispatch =>
  update(`/users/${userId}`, values).then(user => {
    dispatch(actions.getCurrentUser())
    return user
  })

export const onSubmitChangePassword = (
  { currentPassword, password },
  dispatch,
  { history },
) =>
  create(`/users/change-password`, { currentPassword, password })
    .then(() => {
      history.goBack()
    })
    .catch(handleFormError)