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

const DEFAULT_ACCEPTED_FORMATS = ['.png', '.jpg', '.jpeg', '.gif']

/**
 * By default is Upload dialog not visible.
 * It is visible only if files are uploading
 */
const FileInputElement = styled(Element)`
  display: none;
`

class UploadButton extends Component {
  constructor(props) {
    super(props)
    this.state = { inProgress: false, files: [], filesStatus: {} }
    this.fileInputRef = React.createRef()
    this.openFileDialog = this.openFileDialog.bind(this)
    this.onFilesAdded = this.onFilesAdded.bind(this)
    this.onConfirm = this.onConfirm.bind(this)
    this.setFileStatus = this.setFileStatus.bind(this)
  }

  static contextType = Context

  openFileDialog() {
    this.fileInputRef.current.click()
  }

  onFilesAdded(evt) {
    // files to upload
    const files = evt.target.files
    // if have url for upload
    if (files.length > 0 && this.context.uploadUrl) {
      this.setState({ inProgress: true, 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, get(this.context, 'selectedCat.aplCode'), get(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(get(this.context, 'selectedCat'), 'DATETIME_DESC', get(this.context, 'selectedFolder'))
              })
          } else {
            this.setState({ inProgress: false, done: true })
          }
        })
        .catch(e => {
          this.setState({ inProgress: false, done: true })
        })
    }
  }

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

  /**
   * 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,
        },
      },
    })
  }

  render() {
    if (!this.context.onUpload) {
      return null
    }

    const accept = (Array.isArray(this.context.accept) ? this.context.accept : DEFAULT_ACCEPTED_FORMATS).join(',')

    return (
      <div>
        <UButton title="Nahrát obrázek" onClick={this.openFileDialog} />
        <FileInputElement>
          <input
            ref={this.fileInputRef}
            className="FileInput"
            type="file"
            multiple
            onChange={this.onFilesAdded}
            accept={accept}
          />
        </FileInputElement>
        {(this.state.inProgress || this.state.done) && (
          <UploadDialog
            files={this.state.files}
            filesStatus={this.state.filesStatus}
            done={this.state.done}
            onConfirm={this.onConfirm}
          />
        )}
      </div>
    )
  }
}

UploadButton.defaultProps = {
  accept: DEFAULT_ACCEPTED_FORMATS,
}

export default UploadButton
