import React, { useCallback, useMemo, useRef, useState } from 'react'
import styles from './index.module.scss'
import ImageLazy from '@/components/ImageLazy'
import {
  PlusOutlined,
  EyeOutlined,
  CloseOutlined,
  DownloadOutlined,
  UploadOutlined
} from '@ant-design/icons'
import store from '@/store'
import { baseURL } from '@/utils/http'
import classNames from 'classnames'
import { Button } from 'antd'
import { MessageFu } from '@/utils/message'
import { fileDomInitialFu } from '@/utils/domShow'
import { API_upFile } from '@/store/action/layout'
import { forwardRef, useImperativeHandle } from 'react'
import MyPopconfirm from '../MyPopconfirm'

type MyTypeType = 'thumb' | 'video' | 'audio' | 'model' | 'pdf'

// 这个组件 只处理 上传 一张图片或者 视频 音频 模型 pdf 的情况

type Props = {
  fileCheck: boolean //有没有点击过确定
  size: number //上传附件大小（M）
  dirCode: string //文件的code码
  myUrl: string //请求地址
  format: string[] //上传格式 ["image/jpeg", "image/png"] ["video/mp4"] ,application/pdf
  formatTxt: string //上传图片提示
  checkTxt: string
  upTxt: string
  myType: MyTypeType
  isLook?: boolean //是不是查看
  fromData?: any
  ref: any //当前自己的ref，给父组件调用
}

function ZupOne(
  {
    fileCheck,
    size,
    dirCode,
    myUrl,
    format,
    formatTxt,
    checkTxt,
    upTxt,
    myType,
    isLook = false,
    fromData
  }: Props,
  ref: any
) {
  const [fileUrl, setFileUrl] = useState({
    fileName: '',
    filePath: '',
    thumb: ''
  })

  const myInput = useRef<HTMLInputElement>(null)

  // 上传封面图
  const handeUpPhoto = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      if (e.target.files) {
        // 拿到files信息
        const filesInfo = e.target.files[0]
        // console.log("-----", filesInfo.type);

        // 校验格式
        const type = format

        if (myType === 'pdf') {
          if (!filesInfo.type.includes('pdf')) {
            e.target.value = ''
            return MessageFu.warning(`只支持${formatTxt}格式!`)
          }
        } else {
          if (!type.includes(filesInfo.type)) {
            e.target.value = ''
            return MessageFu.warning(`只支持${formatTxt}格式!`)
          }
        }

        // 校验大小
        if (filesInfo.size > size * 1024 * 1024) {
          e.target.value = ''
          return MessageFu.warning(`最大支持${size}M!`)
        }
        // 创建FormData对象
        const fd = new FormData()
        // 把files添加进FormData对象（‘photo’为后端需要的字段）
        let myTypeRes: string = myType
        if (['pdf'].includes(myTypeRes)) myTypeRes = 'doc'
        fd.append('type', myTypeRes)
        fd.append('dirCode', dirCode)
        fd.append('file', filesInfo)

        if (myType === 'thumb') {
          // 开启压缩图片
          fd.append('isCompress', 'true')
        }

        if (fromData) {
          for (const k in fromData) {
            if (fromData[k]) fd.append(k, fromData[k])
          }
        }

        e.target.value = ''

        try {
          const res = await API_upFile(fd, myUrl)
          if (res.code === 0) {
            MessageFu.success('上传成功!')
            setFileUrl(res.data)
          }
          fileDomInitialFu()
        } catch (error) {
          fileDomInitialFu()
        }
      }
    },
    [dirCode, format, formatTxt, fromData, myType, myUrl, size]
  )

  // 让父组件调用的 回显 附件 地址
  const setFileComFileFu = useCallback(
    (valObj: { fileName: string; filePath: string; thumb: string }) => {
      setFileUrl(valObj)
    },
    []
  )

  // 让父组件调用的返回 附件 名字和路径
  const fileComFileResFu = useCallback(() => {
    return fileUrl
  }, [fileUrl])

  // 可以让父组件调用子组件的方法
  useImperativeHandle(ref, () => ({
    setFileComFileFu,
    fileComFileResFu
  }))

  const acceptRes = useMemo(() => {
    let accept = '.png,.jpg,.jpeg'
    if (myType === 'video') accept = '.mp4'
    else if (myType === 'audio') accept = '.mp3'
    else if (myType === 'model') accept = '.4dage'
    else if (myType === 'pdf') accept = '.pdf'
    return accept
  }, [myType])

  // 点击 预览（除了图片）
  const lookFileNoImgFu = useCallback(
    (type: MyTypeType) => {
      if (type === 'pdf' || type === 'thumb') {
        // 新窗口打开
        window.open(baseURL + fileUrl.filePath)
      } else {
        store.dispatch({
          type: 'layout/lookDom',
          payload: { src: fileUrl.filePath, type }
        })
      }

      // if (type === "pdf") {
      // } else {
      // }
    },
    [fileUrl.filePath]
  )

  return (
    <div className={styles.ZupOne}>
      <input
        id='upInput'
        type='file'
        accept={acceptRes}
        ref={myInput}
        onChange={e => handeUpPhoto(e)}
      />
      {myType === 'thumb' ? (
        <div
          hidden={fileUrl.filePath !== ''}
          className='file_upIcon'
          onClick={() => myInput.current?.click()}
        >
          <PlusOutlined rev={undefined} />
        </div>
      ) : (
        <Button
          hidden={fileUrl.filePath !== ''}
          onClick={() => myInput.current?.click()}
          icon={<UploadOutlined rev={undefined} />}
        >
          上传
        </Button>
      )}

      {/* 为图片的情况-------------- */}
      {myType === 'thumb' ? (
        <div className='file_img' hidden={fileUrl.filePath === ''}>
          {fileUrl ? (
            <ImageLazy
              width={100}
              height={100}
              src={fileUrl.thumb || fileUrl.filePath}
              srcBig={fileUrl.filePath || fileUrl.thumb || ''}
              noLook
            />
          ) : null}

          {/* 删除 */}
          <div className='file_closeBox' hidden={isLook}>
            <MyPopconfirm
              txtK='删除'
              onConfirm={() => setFileUrl({ fileName: '', filePath: '', thumb: '' })}
              Dom={<CloseOutlined rev={undefined} />}
            />
          </div>

          {/* 预览 下载 */}
          <div className='file_lookBox'>
            <EyeOutlined
              onClick={() =>
                store.dispatch({
                  type: 'layout/lookBigImg',
                  payload: { url: baseURL + fileUrl.filePath, show: true }
                })
              }
              rev={undefined}
            />
            <a href={baseURL + fileUrl.filePath} download target='_blank' rel='noreferrer'>
              <DownloadOutlined rev={undefined} />
            </a>
          </div>
        </div>
      ) : fileUrl.filePath ? (
        <div className='fileInfo'>
          <div className='upSuccTxt'>{fileUrl.fileName}</div>
          {/* 视频预览 */}
          <div
            className='clearCover'
            hidden={!fileUrl.filePath}
            onClick={() => lookFileNoImgFu(myType)}
          >
            <EyeOutlined rev={undefined} />
          </div>
          {/* 视频下载 */}
          <a
            href={baseURL + fileUrl.filePath}
            download
            target='_blank'
            className='clearCover'
            rel='noreferrer'
          >
            <DownloadOutlined rev={undefined} />
          </a>
          {/* 视频删除 */}

          <MyPopconfirm
            txtK='删除'
            onConfirm={() => setFileUrl({ fileName: '', filePath: '', thumb: '' })}
            Dom={<CloseOutlined className='clearCover' rev={undefined} />}
          />
        </div>
      ) : null}

      <div className='fileBoxRow_r_tit' hidden={isLook}>
        格式要求：支持{formatTxt}格式；最大支持{size}M。{upTxt}
        <br />
        <div
          className={classNames('noUpThumb', !fileUrl.filePath && fileCheck ? 'noUpThumbAc' : '')}
        >
          {checkTxt}
        </div>
      </div>
    </div>
  )
}

export default forwardRef(ZupOne)
