import { memo, useCallback, useRef, useState } from 'react'
import { DeleteOutlined, EyeOutlined, PlusOutlined } from '@ant-design/icons'
import { Modal, Progress, message } from 'antd'
import { uploadRequest } from '@/api/upload'
import utils from '@/utils'
import type { ChangeEvent } from 'react'
import type { FC, ReactNode } from 'react'
interface Iprops {
  children?: ReactNode
  width?: number
  height?: number
  type: 'img' | 'video'
  accept?: string
  fileSize?: number
  value: string | number
  onChange: (e: any) => void
}

const UploadBox: FC<Iprops> = (props) => {
  const { width, height, onChange, value, accept, fileSize = 1 } = props
  const [percent, setPercent] = useState(0)
  const [previewOpen, setPreviewOpen] = useState(false)
  const [currentUrl, setCurrentUrl] = useState(() => {
    if (value) {
      return utils.onlineResource(value as number)
    } else {
      return ''
    }
  })
  const [title, setTitle] = useState('默认标题')
  const [type, setType] = useState('image')
  const InputRef = useRef<HTMLInputElement>(null)
  const handleCancel = useCallback(() => {
    setPreviewOpen(false)
  }, [])
  const openPreview = useCallback(() => {
    setPreviewOpen(true)
  }, [])

  const deleteFile = useCallback(() => {
    InputRef.current!.value = ''
    setCurrentUrl('')
    setPercent(0)
    onChange('')
  }, [onChange])
  const selectFile = () => {
    InputRef.current?.click()
  }

  const onFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files && e.target.files[0]
    const accepts = accept?.split(',')
    const type = file!.type
    const size = file!.size
    if (!accepts?.includes(type)) {
      message.error('您所选择的文件不符合格式！')
      return
    }
    if (size > fileSize * 1024 * 1024) {
      message.error(`您所选择的文件不能大于${fileSize}M！`)
      return
    }
    if (file!.type.indexOf('video') !== -1) {
      setType('video')
    } else {
      setType('image')
    }
    setTitle(file!.name)
    const res = await uploadRequest(file as File, (e) => {
      const progress = e.progress?.toFixed(2)
      const total = (progress as unknown as number) * 100
      setPercent(total === 100 ? 99 : total)
    })
    setCurrentUrl(utils.onlineResource(res.data as number))
    setPercent(100)
    onChange(res.data)
  }

  return (
    <div
      style={{ width: width + 'px', height: height + 'px' }}
      className=" border-dashed border rounded overflow-hidden">
      <input
        type="file"
        accept={accept}
        style={{ display: 'none' }}
        ref={InputRef}
        onChange={onFileChange}
      />

      {currentUrl ? (
        <div className="w-full h-full relative group">
          {type === 'image' ? (
            <img className="w-full h-full absolute" src={currentUrl} alt="" />
          ) : (
            <video className="w-full h-full absolute object-fill" src={currentUrl}></video>
          )}
          <div className=" absolute w-full h-full opacity-30  bg-black hidden group-hover:block justify-center items-center"></div>
          <div className=" absolute hidden group-hover:block left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
            <EyeOutlined
              className=" cursor-pointer mr-2"
              onClick={openPreview}
              style={{ color: 'white', fontSize: 20 }}
            />
            <DeleteOutlined
              className=" cursor-pointer"
              style={{ color: 'white', fontSize: 20 }}
              onClick={deleteFile}
            />
          </div>
        </div>
      ) : percent === 0 ? (
        <div className="w-full h-full flex justify-center items-center">
          <div
            className="flex flex-col justify-center items-center cursor-pointer"
            onClick={selectFile}>
            <PlusOutlined style={{ color: 'black', fontSize: 20 }} />
            <p>上传文件</p>
          </div>
        </div>
      ) : (
        <div className="w-full h-full relative z-10 flex justify-center items-center">
          <Progress percent={percent} type="circle" size={90} />
        </div>
      )}
      <Modal open={previewOpen} title={title} footer={null} onCancel={handleCancel}>
        {type === 'image' ? (
          <img alt="example" style={{ width: '100%' }} src={currentUrl} />
        ) : (
          <video style={{ width: '100%', objectFit: 'fill' }} controls src={currentUrl}></video>
        )}
      </Modal>
    </div>
  )
}

export default memo(UploadBox)
