import React from 'react'
import { get, tail, findKey } from 'lodash'
import { reduxForm } from 'redux-form'
import styled from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { required } from 'xpub-validators'
import { compose, withProps } from 'recompose'
import { Button, Menu, ValidatedField } from '@pubsweet/ui'
import { withModal } from 'pubsweet-component-modal/src/components'

import {
  Row,
  Text,
  Label,
  Textarea,
  MultiAction,
  ContextualBox,
  ItemOverrideAlert,
  withFetching,
} from 'pubsweet-component-faraday-ui/src'

const options = [
  {
    value: 'publish',
    label: 'Publish',
    message: 'Recommend Manuscript for Publishing',
    button: 'Submit Recommendation',
  },
  {
    value: 'reject',
    label: 'Reject',
    message: 'Recommend Manuscript for Rejection',
    button: 'Submit Recommendation',
  },
  {
    value: 'minor',
    label: 'Request Minor Revision',
    message: 'Request Minor Revision',
    button: 'Request Revision',
  },
  {
    value: 'major',
    label: 'Request Major Revision',
    message: 'Request Major Revision',
    button: 'Request Revision',
  },
]

const optionsWhereHECanOnlyReject = {
  reviewersInvited: 'reviewersInvited',
  underReview: 'underReview',
  revisionRequested: 'revisionRequested',
}

const showHEOptions = (collection, hasReviewerReports, fragment) => {
  const { status, fragments } = collection
  const { invitations } = fragment
  if (findKey(optionsWhereHECanOnlyReject, sts => sts === status)) {
    return [options[1]]
  } else if (!hasReviewerReports && fragments.length === 1) {
    return tail(options)
  } else if (invitations === []) {
    return [options[1]]
  }
  return options
}

const parseFormValues = ({ recommendation, ...rest }) => {
  const comments = Object.entries(rest).map(([key, value]) => ({
    content: value,
    public: key === 'public',
    files: [],
  }))

  return {
    comments,
    recommendation,
    recommendationType: 'editorRecommendation',
  }
}

const HERecommendation = ({
  formValues,
  handleSubmit,
  hasReviewerReports,
  highlight,
  collection,
  fragment,
}) => (
  <ContextualBox
    highlight={highlight}
    label="Your Editorial Recommendation"
    mb={2}
  >
    <Root>
      <Row justify="flex-start">
        <ItemOverrideAlert
          data-test-id="editorial-recommendation-choose-options"
          flex={0}
          vertical
        >
          <Label required>Recommendation</Label>
          <ValidatedField
            component={input => (
              <Menu
                options={showHEOptions(
                  collection,
                  hasReviewerReports,
                  fragment,
                )}
                {...input}
              />
            )}
            name="recommendation"
            validate={[required]}
          />
        </ItemOverrideAlert>
      </Row>

      {get(formValues, 'recommendation') === 'minor' ||
      get(formValues, 'recommendation') === 'major' ? (
        <Row mt={2}>
          <ResponsiveItem
            data-test-id="editorial-recommendation-message-for-author"
            mr={1}
            vertical
          >
            <Label>
              Message for Author <Text secondary>Optional</Text>
            </Label>
            <ValidatedField component={Textarea} name="public" />
          </ResponsiveItem>
        </Row>
      ) : (
        <ResponsiveRow mt={2}>
          <ResponsiveItem
            data-test-id="editorial-recommendation-message-for-author"
            mr={1}
            vertical
          >
            <Label>
              Message for Author <Text secondary>Optional</Text>
            </Label>
            <ValidatedField component={Textarea} name="public" />
          </ResponsiveItem>

          <ResponsiveItem
            data-test-id="editorial-recommendation-message-for-eic"
            ml={1}
            vertical
          >
            <Label>
              Message for Editor in Chief <Text secondary>Optional</Text>
            </Label>
            <ValidatedField component={Textarea} name="private" />
          </ResponsiveItem>
        </ResponsiveRow>
      )}

      <Row justify="flex-end" mt={2}>
        <Button
          data-test-id="button-editorial-recommendation-submit"
          onClick={handleSubmit}
          primary
          size="medium"
        >
          {
            options.find(
              o => o.value === get(formValues, 'recommendation', 'publish'),
            ).button
          }
        </Button>
      </Row>
    </Root>
  </ContextualBox>
)

export default compose(
  withFetching,
  withModal(({ isFetching }) => ({
    isFetching,
    modalComponent: MultiAction,
  })),
  withProps(({ formValues }) => ({
    modalTitle: options.find(
      o => o.value === get(formValues, 'recommendation', 'publish'),
    ).message,
    confirmMessage: options.find(
      o => o.value === get(formValues, 'recommendation', 'publish'),
    ).button,
  })),
  reduxForm({
    form: 'HERecommendation',
    onSubmit: (
      values,
      dispatch,
      {
        onRecommendationSubmit,
        showModal,
        setFetching,
        modalTitle,
        confirmMessage,
      },
    ) => {
      showModal({
        title: `${modalTitle}?`,
        confirmText:
          confirmMessage === 'Submit Recommendation'
            ? 'Submit'
            : confirmMessage,

        onConfirm: props => {
          onRecommendationSubmit(parseFormValues(values), {
            ...props,
            setFetching,
          })
        },
      })
    },
  }),
)(HERecommendation)

// #region styles
const Root = styled.div`
  display: flex;
  flex-direction: column;
  padding: ${th('gridUnit')};
`

const ResponsiveRow = styled(Row)`
  @media (max-width: 800px) {
    flex-direction: column;
  }
`

const ResponsiveItem = styled(ItemOverrideAlert)`
  @media (max-width: 800px) {
    margin-right: 0;
    margin-left: 0;
    width: 100%;
  }
`
// #endregion