import React, { Fragment } from 'react'
import { debounce, isEqual } from 'lodash'
import { connect } from 'react-redux'
import { required } from 'xpub-validators'
import styled, { css } from 'styled-components'
import { th, Menu, ValidatedField, Icon, Button } from '@pubsweet/ui'
import { compose, withHandlers, withProps } from 'recompose'
import {
  reduxForm,
  isSubmitting,
  change as changeForm,
  getFormValues,
} from 'redux-form'
import AutosaveIndicator from 'pubsweet-component-wizard/src/components/AutosaveIndicator'
import {
  autosaveRequest,
  autosaveSuccess,
} from 'pubsweet-component-wizard/src/redux/autosave'
import {
  ConfirmationModal,
  withModal2,
} from 'pubsweet-component-modal/src/components'
import {
  selectError,
  selectFetching,
  createRecommendation,
  updateRecommendation,
  getFragmentRecommendations,
} from 'pubsweet-components-faraday/src/redux/recommendations'

import { parseReviewResponseToForm, parseReviewRequest } from './utils'

const guidelinesLink =
  'https://about.hindawi.com/authors/peer-review-at-hindawi/'
const options = [
  {
    value: 'publish',
    label: 'Publish unaltered',
  },
  {
    value: 'major',
    label: 'Consider after major revision',
  },
  {
    value: 'minor',
    label: 'Consider after major revision',
  },
  {
    value: 'reject',
    label: 'Reject',
  },
]

const onChange = (
  values,
  dispatch,
  { project, version, createRecommendation, updateRecommendation },
) => {
  dispatch(autosaveRequest())
  if (values.id) {
    updateRecommendation(parseReviewRequest(values))
      .then(console.log)
      .then(dispatch(autosaveSuccess(new Date())))
  } else {
    createRecommendation(parseReviewRequest(values))
      .then(console.log)
      .then(dispatch(autosaveSuccess(new Date())))
  }
}

const ReviewerReportForm = ({
  isSubmitting,
  changeField,
  handleSubmit,
  formValues = {},
}) => (
  <Root>
    <Row>
      <Label>Recommendation*</Label>
      <ActionLink href={guidelinesLink} target="_blank">
        Hindawi Reviewer Guidelines
      </ActionLink>
    </Row>
    <Row>
      <ValidatedField
        component={input => (
          <Menu
            {...input}
            inline
            onChange={v => changeField('recommendation', v)}
            options={options}
            placeholder="Select"
          />
        )}
        name="recommendation"
        validate={[required]}
      />
    </Row>
    <Spacing />
    <Row>
      <Label>
        Report <ActionText left={12}>Upload file</ActionText>
      </Label>
    </Row>
    <Row>
      <FullWidth>
        <ValidatedField
          component={input => (
            <Textarea
              {...input}
              hasError={input.validationStatus === 'error'}
              onChange={e => changeField('public', e.target.value)}
              rows={6}
            />
          )}
          name="public"
          validate={[required]}
        />
      </FullWidth>
    </Row>
    {formValues.hasConfidential ? (
      <Fragment>
        <Row>
          <Label>
            Note for the editorial team <i>Not shared with the author</i>
          </Label>
          <ActionTextIcon onClick={() => changeField('hasConfidential', false)}>
            <Icon primary size={3}>
              x
            </Icon>
            Remove
          </ActionTextIcon>
        </Row>
        <Row>
          <FullWidth>
            <ValidatedField
              component={input => (
                <Textarea
                  {...input}
                  hasError={input.validationStatus === 'error'}
                  onChange={e => changeField('confidential', e.target.value)}
                  rows={6}
                />
              )}
              name="confidential"
              validate={[required]}
            />
          </FullWidth>
        </Row>
      </Fragment>
    ) : (
      <Row>
        <ActionText onClick={() => changeField('hasConfidential', true)}>
          Add confidential note for the Editorial Team
        </ActionText>
      </Row>
    )}

    <Spacing />
    <Row>
      <ActionButton onClick={handleSubmit}> Submit report </ActionButton>
      <AutosaveIndicator formName="reviewerReport" />
    </Row>
  </Root>
)

const ModalWrapper = compose(
  connect(state => ({
    fetching: selectFetching(state),
    modalError: selectError(state),
  })),
)(({ fetching, ...rest }) => (
  <ConfirmationModal {...rest} isFetching={fetching} />
))

export default compose(
  connect(
    state => ({
      formValues: getFormValues('reviewerReport')(state),
      isSubmitting: isSubmitting('reviewerReport')(state),
    }),
    {
      changeForm,
      getFormValues,
      getFragmentRecommendations,
      createRecommendation,
      updateRecommendation,
    },
  ),
  withProps(({ recommendations = [] }) => ({
    initialValues: parseReviewResponseToForm(recommendations[0]),
  })),
  withModal2(props => ({
    modalComponent: ModalWrapper,
  })),
  withHandlers({
    changeField: ({ changeForm }) => (field, value) => {
      changeForm('reviewerReport', field, value)
    },
  }),
  reduxForm({
    form: 'reviewerReport',
    onChange: debounce(onChange, 1000, { maxWait: 5000 }),
    onSubmit: (
      values,
      dispatch,
      { isSubmitting, showModal, hideModal, project, version },
    ) => {
      showModal({
        title: 'Ready to Submit your Report?',
        subtitle: 'Once submitted, the report can`t be modified',
        confirmText: 'Submit report',
        onConfirm: () => {
          dispatch(autosaveRequest())
          updateRecommendation(parseReviewRequest(values))
            .then(console.log)
            .then(hideModal)
            .then(dispatch(autosaveSuccess(new Date())))
          // sleep(1000)
          //   .then(hideModal)
          //   .then(() => {
          //     // TODO: link to backend
          //     const review = parseReviewRequest(values)
          //     window.alert(
          //       `You submitted:\n\n${JSON.stringify(review, null, 2)}`,
          //     )
          //   })
        },
        onCancel: hideModal,
      })
    },
  }),
)(ReviewerReportForm)

// #region styled-components

const defaultText = css`
  color: ${th('colorPrimary')};
  font-family: ${th('fontReading')};
  font-size: ${th('fontSizeBaseSmall')};
`
const Root = styled.div`
  display: flex;
  flex-direction: column;
  margin: auto;
  [role='listbox'] {
    min-width: 280px;
  }
`

const Label = styled.div`
  ${defaultText};
  text-transform: uppercase;
  i {
    text-transform: none;
    margin-left: ${th('gridUnit')};
  }
`

const ActionText = styled.span`
  ${defaultText};
  text-decoration: underline;
  cursor: pointer;
  margin-left: ${({ left }) => left || 0}px;
`

const ActionTextIcon = styled(ActionText)`
  display: flex;
  align-items: center;
`
const ActionLink = styled.a`
  ${defaultText};
`

const Textarea = styled.textarea`
  width: 100%;
  padding: calc(${th('subGridUnit')}*2);
  font-size: ${th('fontSizeBaseSmall')};
  font-family: ${th('fontWriting')};
  border-color: ${({ hasError }) =>
    hasError ? th('colorError') : th('colorPrimary')};
`

const Spacing = styled.div`
  margin-top: ${th('gridUnit')};
  flex: 1;
`

const FullWidth = styled.div`
  flex: 1;
  > div {
    flex: 1;
  }
`

const Row = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  flex: 1;
  box-sizing: border-box;
  flex-wrap: wrap;
  justify-content: space-between;
`

const ActionButton = styled(Button)`
  ${defaultText};
  align-items: center;
  background-color: ${th('colorPrimary')};
  color: ${th('colorTextReverse')};
  display: flex;
  padding: 4px 8px;
  text-align: center;
  height: calc(${th('subGridUnit')}*5);
  text-transform: uppercase;
`
// #endregion