import './ImageUpload.scss'
import { Button, Row, Upload } from 'antd'
import { UploadFile } from 'antd/lib/upload/interface'
import Progress from 'components/Progress'
import { ReactComponent as AddIcon } from 'icons/dark/add-blue.svg'
import { ReactComponent as CloseIcon } from 'icons/close.svg'
import React, { useEffect, useState } from 'react'
import { MediaUpload } from 'redux/Common/types'
import { resizeFile } from 'utils/file'
import { onBeforeUpload, pushImageToS3 } from 'utils/photo'
import classNames from 'classnames'
import ImageCrop from 'components/ImageCrop'
import { Paragraph } from 'components/Typography'
import config from 'config'

const API_URL = config.api.url

interface Props {
  className?: string
  photoIndex?: number
  photo: MediaUpload
  onUploadSuccess: (file: MediaUpload) => void
  onRemove: (file: MediaUpload) => void
  children?: any
  content?: React.ReactNode
  dropAspect?: number
  hideRemove?: boolean
  hideUpdate?: boolean
  replace?: boolean
}

const DropContainer: React.FC<any> = ({ dropAspect, children }) => {
  return (
    <React.Fragment>
      {dropAspect ? (
        <ImageCrop aspect={dropAspect}>{children}</ImageCrop>
      ) : (
        <React.Fragment>{children}</React.Fragment>
      )}
    </React.Fragment>
  )
}

const ImageUpload: React.FC<Props> = ({
  photoIndex = 1,
  photo,
  className,
  children,
  onUploadSuccess,
  onRemove,
  dropAspect,
  hideRemove,
  content,
  hideUpdate,
  replace
}) => {
  const [isHover, setIsHover] = useState(false)
  const [photoUpload, setPhotoUpload] = useState<MediaUpload>()

  useEffect(() => {
    if (photo) setPhotoUpload(photo)
    return () => {}
  }, [photo])

  const removePhoto = () => {
    onRemove(photoUpload as MediaUpload)
    setPhotoUpload({})
  }

  const handleChange = async (file: UploadFile<any>, index: number) => {
    let photo: MediaUpload = {}

    if (file.status === 'uploading') {
      photo.loading = true
      photo.fileName = file.name
    }

    // TODO: remove status error when integrate with API
    if (file.status === 'done' || file.status === 'error') {
      const transformFile = await resizeFile(file.originFileObj)
      file.originFileObj = transformFile

      const url = await pushImageToS3(file, (value: number) =>
        setPhotoUpload({ percent: value })
      )

      if (!url) {
        photo = {
          id: index,
          fileName: undefined,
          loading: false
        }
      } else {
        photo = {
          id: index,
          fileName: file.name,
          url,
          loading: false
        }
      }
    }
    onUploadSuccess({ ...photoUpload, ...photo })
    setPhotoUpload({ ...photoUpload, ...photo })
  }

  const photoUploadClass = classNames({
    'photo-upload-item': true,
    [className || '']: true
  })

  return (
    <div className={photoUploadClass}>
      <DropContainer dropAspect={dropAspect}>
        <Upload
          className={photoUpload?.url && !replace ? 'ant-upload--has-data' : ''}
          accept={'image/png,image/jpeg,image/webp'}
          listType="picture-card"
          action={API_URL}
          showUploadList={false}
          beforeUpload={file => onBeforeUpload(file)}
          onChange={({ file }) => handleChange(file, photoIndex)}
        >
          {(photoUpload?.loading || (photoUpload?.percent as number) < 100) &&
          !replace ? (
            <Progress value={photoUpload?.percent} />
          ) : photoUpload?.url && !replace ? (
            <div
              onMouseEnter={() => setIsHover(true)}
              onMouseLeave={() => setIsHover(false)}
              className="photo-preview-wrapper"
              data-testid="media-upload--image-card"
            >
              {isHover && !hideUpdate && (
                <Row
                  className="photo-preview-wrapper__hover"
                  align="middle"
                  justify="center"
                >
                  <Paragraph className="uppercase" preset="bold14">
                    Update
                  </Paragraph>
                </Row>
              )}
              {!hideRemove ? (
                <Button
                  data-testid="image-upload--delete"
                  className="btn-delete btn--circle"
                  onClick={() => removePhoto()}
                >
                  <CloseIcon />
                </Button>
              ) : null}
              {
                <img
                  src={photoUpload?.url.toString()}
                  alt="avatar"
                  style={{ width: '100%' }}
                />
              }
            </div>
          ) : children ? (
            children
          ) : (
            content || <AddIcon data-testid="media-upload--add" />
          )}
        </Upload>
      </DropContainer>
    </div>
  )
}

export default ImageUpload
