text: import _ from 'lodash'
  import Dropzone from 'react-dropzone'
  import injectSheet from 'react-jss'
  import PropTypes from 'prop-types'
  import React, { createRef, Fragment, useEffect, useState } from 'react'
  
  import * as mixins from 'styles/mixins'
  import FieldError from 'components/FieldError'
  import FilledButton from 'components/buttons/FilledButton'
  import Hint from 'components/internal/typography/Hint'
  import Input from 'components/inputs/TextInput'
  import ItemBar from 'components/ItemBar'
  import Spacer from 'components/Spacer'
  import withUniqueId from 'components/decorators/withUniqueId'
  import { Text } from 'components/internal/typography'
  
  function fileUrl(value) {
    return _.isString(value) && value
  }
  
  function imageUrl(value) {
    if (!value) {
      return null
    }
  
    return fileUrl(value) || URL.createObjectURL(value)
  }
  
  function UploadInput({ classes, input, label, meta, note, isImage, previewUrl }) {
    const name = (input && input.name) || 'switch'
    const dropzoneRef = createRef()
    const [ droppedFiles, setDroppedFiles ] = useState([ input.value ])
  
    const image = isImage && imageUrl(input.value)
  
    useEffect(() => {
      input.onChange(droppedFiles[0])
    }, [ input, droppedFiles ])
  
    const openDialog = () => {
      // Note that the ref is set async,
      // so it might be null at some point
      if (dropzoneRef.current) {
        dropzoneRef.current.open()
      }
    }
  
    const update = (files) => {
      setDroppedFiles([ ...files ])
      input.onChange(droppedFiles[0])
    }
  
    const remove = (files) => {
      const newFiles = [ ...droppedFiles ]
      newFiles.splice(newFiles.indexOf(files), 1)
      setDroppedFiles([ ' ' ])
    }
  
    const isFilePresent = droppedFiles[0].name || droppedFiles[0].trim()
  
    return (
      <Fragment>
        <label htmlFor={name} className={classes.label}>
          {label}
        </label>
        <Dropzone
          ref={dropzoneRef}
          onDrop={update}
          multiple={false}
          noKeyboard
          noClick
        >
          {({ getRootProps, getInputProps, acceptedFiles }) => (
            <div {...getRootProps({ className: classes.dropzone })}>
              <input {...getInputProps()} />
              {isFilePresent && image && <div className={classes.previewSection} style={{ backgroundImage: `url(${image})` }} />}
              {isFilePresent && previewUrl && fileUrl(input.value) && (
                <div className={classes.previewSection}>
                  <Text>Uploaded File:</Text>
                  <Hint>{fileUrl(input.value)}</Hint>
                </div>
              )}
              <div className={classes.browseSection}>
                {isFilePresent && acceptedFiles.length > 0 && (
                  <Fragment>
                    {droppedFiles.map(({ path, size }) => (
                      <Text key={path}>
                        {`${path} - ${size} bytes`}
                      </Text>
                    ))}
                  </Fragment>
                )}
                {(!isFilePresent || acceptedFiles.length === 0) && (
                  <Text>Drag &apos;n&apos; drop a file here</Text>
                )}
                <Spacer height={20} />
                <ItemBar>
                  <FilledButton type="button" size="tiny" label="Browse" onClick={openDialog} />
                  {isFilePresent && <FilledButton type="button" size="tiny" label="Remove" onClick={() => remove(acceptedFiles[0])} />}
                </ItemBar>
                {note && (
                  <Fragment>
                    <Spacer height={20} />
                    {note}
                  </Fragment>
                )}
              </div>
              <FieldError active={meta.active} error={Input.fieldError(meta)} />
            </div>
          )}
        </Dropzone>
      </Fragment>
    )
  }
  
  UploadInput.propTypes = {
    isImage: PropTypes.bool,
    previewUrl: PropTypes.bool,
    note: PropTypes.string
  }
  
  UploadInput.defaultProps = {
    isImage: false,
    previewUrl: false,
    note: null
  }
  
  UploadInput = withUniqueId()(UploadInput)
  
  export default injectSheet(({ colors, typography, units }) => ({
    dropzone: {
      backgroundColor: colors.uploadInputBackground,
      borderColor: colors.uploadInputBorder,
      borderRadius: units.uploadInputBorderRadius,
      borderStyle: 'dashed',
      borderWidth: units.uploadInputBorderWidth,
      display: 'flex',
      justifyContent: 'space-around',
      outline: 'none',
      padding: units.uploadInputPadding,
      position: 'relative'
    },
    browseSection: {
      alignItems: 'center',
      alignSelf: 'center',
      display: 'flex',
      flexDirection: 'column'
    },
    label: {
      ...mixins.transitionSimple(),
      ...typography.regularSmallSpaced,
  
      color: colors.text_pale,
      display: 'block',
      marginBottom: 15
    },
    previewSection: {
      backgroundPosition: 'center',
      backgroundRepeat: 'no-repeat',
      backgroundSize: 'contain',
      height: units.uploadInputPreviewHeight,
      width: units.uploadInputPreviewWidth
    }
  }))(UploadInput)
  