import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Dropzone from 'react-dropzone';
import FieldControl from '../FieldControl';
import Alert from '../Alert';
import ListFiles from './ListFiles';
import { getInputProps } from '../_helpers/tools';

import './file-input.scss';


const propTypes = {
  className: PropTypes.string,
  children: PropTypes.func,
  onDrop: PropTypes.func,
  onDelete: PropTypes.func,
  accept: PropTypes.string,
  maxSize: PropTypes.number,
  minSize: PropTypes.number,
  input: PropTypes.object,
  label: PropTypes.string,
  mandatory: PropTypes.bool,
  multiple: PropTypes.bool,
  placeHolder: PropTypes.string
};

const defaultProps = {
  className: null,
  children: undefined,
  onDrop: undefined,
  onDelete: undefined,
  accept: undefined,
  maxSize: Infinity,
  minSize: 0,
  input: null,
  label: null,
  mandatory: false,
  multiple: false,
  placeHolder: null
};

class FileInput extends Component {
  handleDelete = (file, row) => {
    const { onDelete } = this.props;
    const { value: [...value], onChange } = getInputProps(this.props);
    value.splice(row, 1);
    if (onDelete) onDelete(value);
    if (onChange) onChange(value);
  };

  handleDrop = filesToUpload => {
    const { onDrop, multiple } = this.props;
    const { onChange, value = [] } = getInputProps(this.props);
    if (onChange && filesToUpload.length) { onChange(multiple ? [...filesToUpload, ...value] : filesToUpload); }
    if (onDrop && filesToUpload.length) { onDrop(filesToUpload); }
  };

  renderWithoutChild() {
    const { value } = getInputProps(this.props);
    return value && !!value.length && (
      <ListFiles key="list-files" value={value} handleDelete={this.handleDelete} />
    );
  }

  render() {
    const { children, multiple, maxSize, minSize, accept, placeHolder, onDrop, ...props } = this.props;
    return (
      <FieldControl {...props}>
        {({ ...restProps }) => {
          const { name } = getInputProps(restProps);
          return ([
            <Dropzone
              name={name}
              onDrop={this.handleDrop}
              styleName="drop-zone"
              multiple={multiple}
              maxSize={maxSize}
              minSize={minSize}
              accept={accept}
              key="drop-zone"
            >
              {
                ({ isDragActive, isDragReject }) => {
                  let dropWording;
                  switch (true) {
                    case isDragReject:
                      dropWording = <Alert type="warning">This file is not authorized</Alert>;
                      break;
                    case isDragActive:
                      dropWording = <Alert type="info">This file is authorized</Alert>;
                      break;
                    default:
                      dropWording = <p styleName="placeholder"> {placeHolder || 'You can drop your file(s) here'}</p>;
                  }

                  return (
                    <div key="files-zone">
                      {dropWording}
                    </div>
                  );
                }
              }
            </Dropzone>,
            children
              ? <div key="children">{children({ ...getInputProps(restProps), handleDelete: this.handleDelete })}</div>
              : this.renderWithoutChild()
          ]);
        }}
      </FieldControl>
    );
  }
}

FileInput.propTypes = propTypes;
FileInput.defaultProps = defaultProps;

FileInput.ListFiles = ListFiles;

export default FileInput;
