import React, { Component } from 'react'
import { Element, styled } from '@siteone/system-core'
import get from 'lodash/fp/get'
import UploadDialog from '../UploadDialog'
import { uploadFiles } from '../helpers'
import Context from '../EventsContext'

const StyledZone = styled(Element)`
  opacity: ${({ hightlight }) => (hightlight ? 0.5 : 1)};
  height: 50vh;
  max-height: 540px;
  position: relative;
  overflow: auto;
`

class DropZone extends Component {
  constructor(props) {
    super(props)
    this.state = {
      hightlight: false,
      inProgress: false,
      files: [],
      filesStatus: {}
    }
    this.onDragOver = this.onDragOver.bind(this)
    this.onDragLeave = this.onDragLeave.bind(this)
    this.onDrop = this.onDrop.bind(this)
    this.onConfirm = this.onConfirm.bind(this)
    this.setFileStatus = this.setFileStatus.bind(this)
  }

  static contextType = Context;

  onDragOver(evt) {
    evt.preventDefault()
    if (!get(this.context, 'selectedCat.isEditable')) {
      return
    }
    this.setState({ hightlight: true })
  }

  onDragLeave() {
    this.setState({ hightlight: false })
  }

  onDrop(event) {
    event.preventDefault()

    if (!this.context.selectedCat.isEditable) {
      return
    }
    // files to upload
    const files = event.dataTransfer.files
    // if have POST url for upload
    if (this.context.uploadUrl) {
      // show upload dialog
      this.setState({ inProgress: true, hightlight: false, files })
      // upload files
      uploadFiles(files, this.context.uploadUrl, this.setFileStatus, this.context.uploadExtraData).then(res => {
        // on upload finish call callback onUpload
        if (this.context.onUpload) {
          this.context.onUpload(res, this.context.selectedCat.aplCode, this.context.selectedFolder)
            .catch(() => {
              const files = Object.keys(this.state.filesStatus)
              files.forEach(fileName => this.setFileStatus(fileName, 'status', 'error'))
            })
            .then(() => {
              this.setState({ inProgress: false, done: true })
              // reload image list
              this.context.reset(this.context.selectedCat, 'DATETIME_DESC', this.context.selectedFolder)
            })
        } else {
          this.setState({ inProgress: false, done: true })
        }
      }).catch(e => {
        this.setState({ inProgress: false, done: true })
      })
    }
  }

  /**
   * Set a file info, i.e. uploaded file url or progress status
   * @param {string} fileName 
   * @param {string} key 
   * @param {string} value 
   */
  setFileStatus(fileName, key, value) {
    this.setState({
      ...this.state,
      filesStatus: {
        ...this.state.filesStatus,
        [fileName]: {
          ...this.state.filesStatus[fileName],
          [key]: value
        }
      }
    })
  }

  onConfirm() {
    this.setState({ done: null })
  }

  render() {
    return (
      <div
        onDragOver={this.onDragOver}
        onDragLeave={this.onDragLeave}
        onDrop={this.onDrop}
        style={{ height: '100%' }}
      >
        <StyledZone hightlight={this.state.hightlight}>
          {(this.state.inProgress || this.state.done) && (
            <UploadDialog
              files={this.state.files}
              filesStatus={this.state.filesStatus}
              done={this.state.done}
              onConfirm={this.onConfirm}
            />
          )}
          {this.props.children}
        </StyledZone>
      </div>
    )
  }
}

export default DropZone
