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

export type FileListType = {
  fileName: string
  thumb?: string
  filePath: string
  id: number
  type: 'model' | 'img' | 'audio' | 'video'
  imgName: string
}

type Props = {
  ref: any //当前自己的ref，给父组件调用
  selecFlag: string //筛选的字符串 模型/图片/音频/视频
  fileCheck: boolean //有没有点击过确定
  dirCode: string //文件的code码
  myUrl: string //请求地址
  isLook?: boolean //是不是查看
  modelSize?: number //模型文件大小限制
  imgSize?: number //图片大小限制
  imgLength?: number //图片数量限制
  audioSize?: number //音频大小限制
  videoSize?: number //视频大小限制
  videoTit?: string //视频上传的提示语
  isTypeShow?: boolean //默认就选中（只有一个类型的时候）
  isUpName?: boolean //是否能修改图片名字
  lastImgTxt?: string //加载最后面的上传提示
  oneIsCover?: boolean //是否将第一张作为封面
}

function ZupTypes(
  {
    selecFlag,
    fileCheck,
    dirCode,
    myUrl,
    isLook = false,
    modelSize = 500,
    imgSize = 5,
    imgLength = 9,
    audioSize = 10,
    videoSize = 500,
    videoTit = '',
    isTypeShow = false,
    isUpName = false,
    lastImgTxt = '',
    oneIsCover = false
  }: Props,
  ref: any
) {
  // 筛选
  const [typeCheck, setTypeCheck] = useState<string[]>([])

  // 筛选数组
  const typeCheckArr = useMemo(() => {
    const arr = [
      { label: '模型', value: 'model' },
      { label: '图片', value: 'img' },
      { label: '音频', value: 'audio' },
      { label: '视频', value: 'video' }
    ]

    const arrRes = arr.filter(v => selecFlag.includes(v.label))
    if (arrRes.length <= 1 && isTypeShow) {
      setTypeCheck([arrRes[0].value])
      // 默认就选中（只有一个类型的时候）
    }

    return arrRes
  }, [isTypeShow, selecFlag])

  // 上传附件的信息
  const [fileList, setFileList] = useState({
    model: {} as FileListType,
    img: [] as FileListType[],
    audio: {} as FileListType,
    video: {} as FileListType
  })

  // 附件信息的校验，不满足返回 true
  const fileCheckFu = useMemo(() => {
    let flag = false
    if (typeCheck.length === 0) flag = true
    if (typeCheck.includes('model') && !fileList.model.id) flag = true
    if (typeCheck.includes('img') && fileList.img.length === 0) flag = true
    if (typeCheck.includes('audio') && !fileList.audio.id) flag = true
    if (typeCheck.includes('video') && !fileList.video.id) flag = true
    return flag
  }, [fileList, typeCheck])

  // 点击上传附件按钮
  const myInput = useRef<HTMLInputElement>(null)

  const [fileOneType, setFileOneType] = useState('')

  useEffect(() => {
    if (fileOneType) myInput.current?.click()
  }, [fileOneType])

  const upFileFu = useCallback((type: string) => {
    setFileOneType('')
    window.setTimeout(() => {
      setFileOneType(type)
    }, 100)
  }, [])

  // 上传附件的处理函数
  const handeUpPhoto2 = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      if (e.target.files) {
        // 拿到files信息
        const filesInfo = e.target.files[0]

        let anType = ['image/jpeg', 'image/png']
        let anTit1 = '只支持png、jpg格式!'
        let anTit2 = `最大支持${imgSize}M!`
        let anSize = imgSize * 1024 * 1024

        if (fileOneType === 'audio') {
          anType = ['audio/mpeg']
          anTit1 = '只支持mp3格式!'
          anTit2 = `最大支持${audioSize}M!`
          anSize = audioSize * 1024 * 1024
        } else if (fileOneType === 'video') {
          anType = ['video/mp4']
          anTit1 = '只支持mp4格式!'
          anTit2 = `最大支持${videoSize}M!`
          anSize = videoSize * 1024 * 1024
        } else if (fileOneType === 'model') {
          anType = ['']
          anTit1 = '只支持4dage格式!'
          anTit2 = `最大支持${modelSize}M!`
          anSize = modelSize * 1024 * 1024
        }

        // 校验格式
        if (fileOneType !== 'model') {
          if (!anType.includes(filesInfo.type)) {
            e.target.value = ''
            return MessageFu.warning(anTit1)
          }
        } else {
          if (!filesInfo.name.includes('.4dage')) {
            e.target.value = ''
            return MessageFu.warning(anTit1)
          }
        }

        // 校验大小
        if (filesInfo.size > anSize) {
          e.target.value = ''
          return MessageFu.warning(anTit2)
        }
        // 创建FormData对象
        const fd = new FormData()
        // 把files添加进FormData对象（‘photo’为后端需要的字段）
        fd.append('type', fileOneType)
        fd.append('dirCode', dirCode)
        fd.append('isDb', 'true')

        //初始图片 fileName为：未命名
        if (isUpName) {
          fd.append('isDefaultName', 'false')
        }

        fd.append('file', filesInfo)

        if (fileOneType === 'img' && filesInfo.size > 1 * 1024 * 1024) {
          // 开启压缩图片
          fd.append('isCompress', 'true')
        }

        e.target.value = ''

        const res = await API_upFile(fd, myUrl)

        try {
          if (res.code === 0) {
            MessageFu.success('上传成功!')
            if (fileOneType === 'img')
              setFileList({
                ...fileList,
                img: [...fileList.img, { ...res.data, imgName: '未命名' }]
              })
            else setFileList({ ...fileList, [fileOneType]: res.data })
          }
          fileDomInitialFu()
        } catch (error) {
          fileDomInitialFu()
        }
      }
    },
    [audioSize, dirCode, fileList, fileOneType, imgSize, isUpName, modelSize, myUrl, videoSize]
  )

  // 附件图片的拖动
  const [dragImg, setDragImg] = useState<any>(null)

  const handleDragOver = useCallback(
    (e: React.DragEvent<HTMLDivElement>, item: FileListType) => {
      if (isLook) return
      e.dataTransfer.dropEffect = 'move'
    },
    [isLook]
  )

  const handleDragEnter = useCallback(
    (e: React.DragEvent<HTMLDivElement>, item: FileListType) => {
      if (isLook) return

      e.dataTransfer.effectAllowed = 'move'
      if (item === dragImg) return
      const newItems = [...fileList.img] //拷贝一份数据进行交换操作。
      const src = newItems.indexOf(dragImg) //获取数组下标
      const dst = newItems.indexOf(item)
      newItems.splice(dst, 0, ...newItems.splice(src, 1)) //交换位置
      setFileList({ ...fileList, img: newItems })
    },
    [dragImg, fileList, isLook]
  )

  // 删除某一张图片
  const delImgListFu = useCallback(
    (id: number) => {
      const newItems = fileList.img.filter(v => v.id !== id)
      setFileList({ ...fileList, img: newItems })
    },
    [fileList]
  )

  // 模型 音频 视频 的 dom
  const resOneDivDom = useCallback(
    (type: 'model' | 'audio' | 'video') => {
      const dom = (
        <div className='ZTbox' hidden={!typeCheck.includes(type)}>
          <div className='ZTbox1'>
            <span> </span>
            {type === 'model' ? '模型' : type === 'audio' ? '音频' : '视频'}：
          </div>
          {fileList[type].id ? (
            <div className='ZTbox2'>
              <div className='ZTbox2Name'>{fileList[type].fileName}</div>

              <div
                className='ZTbox2Look'
                onClick={() =>
                  store.dispatch({
                    type: 'layout/lookDom',
                    payload: { src: fileList[type].filePath, type }
                  })
                }
              >
                <EyeOutlined rev={undefined} />
              </div>

              <a
                href={baseURL + fileList[type].filePath}
                download
                target='_blank'
                className='ZTbox2Down'
                rel='noreferrer'
              >
                <DownloadOutlined rev={undefined} />
              </a>

              <MyPopconfirm
                txtK='删除'
                onConfirm={() => setFileList({ ...fileList, [type]: {} as FileListType })}
                Dom={<CloseCircleOutlined className='ZTbox2X' rev={undefined} />}
              />
            </div>
          ) : (
            <>
              <Button onClick={() => upFileFu(type)} icon={<UploadOutlined rev={undefined} />}>
                上传
              </Button>

              <div className='ZTboxTit'>
                {type === 'model'
                  ? `仅支持4dage格式的模型文件，大小不能超过${modelSize}M。`
                  : type === 'audio'
                  ? `仅支持mp3格式的音频文件，大小不得超过${audioSize}MB。`
                  : `仅支持mp4格式的视频文件，大小不得超过${videoSize}MB。${videoTit}`}
              </div>
            </>
          )}
        </div>
      )
      return dom
    },
    [audioSize, fileList, modelSize, typeCheck, upFileFu, videoSize, videoTit]
  )

  // ------------让父组件调用的 回显
  const setFileComFileFu = useCallback((info: any) => {
    if (info.type) setTypeCheck(info.type.split(','))

    if (info.fileList && info.fileList.length) {
      const data: FileListType[] = info.fileList
      const obj = {
        model: {} as FileListType,
        img: [] as FileListType[],
        audio: {} as FileListType,
        video: {} as FileListType
      }

      data.forEach(v => {
        if (v.type === 'img') {
          obj.img.push({ ...v, imgName: v.fileName })
        } else obj[v.type!] = v
      })
      setFileList(obj)
    }
  }, [])

  // --------------让父组件调用的返回 附件 信息
  const fileComFileResFu = useCallback(() => {
    let coverUrl = ''
    const fileIds = []
    if (fileList.model.id && typeCheck.includes('model')) fileIds.push(fileList.model.id)
    if (fileList.audio.id && typeCheck.includes('audio')) fileIds.push(fileList.audio.id)
    if (fileList.video.id && typeCheck.includes('video')) fileIds.push(fileList.video.id)
    if (typeCheck.includes('img')) {
      fileList.img.forEach((v, i) => {
        if (v.id) {
          fileIds.push(v.id)
          if (oneIsCover && i === 0) {
            // 返回 第一张图的url 作为封面
            coverUrl = v.thumb || v.filePath
          }
        }
      })
    }
    return {
      sonType: typeCheck,
      sonFileIds: fileIds,
      sonIsOk: fileCheckFu,
      coverUrl
    }
  }, [
    fileCheckFu,
    fileList.audio.id,
    fileList.img,
    fileList.model.id,
    fileList.video.id,
    oneIsCover,
    typeCheck
  ])

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

  // 修改图片名称
  const [isNameChange, setIsNameChange] = useState({
    id: 0,
    oldName: '',
    newName: ''
  })

  // 关闭弹窗
  const isNameChangeXFu = useCallback(() => {
    setIsNameChange({ id: 0, oldName: '', newName: '' })
  }, [])

  // 点击图片名字-出来弹窗
  const isNameChangeFu = useCallback(
    (item: FileListType) => {
      if (isLook) return
      setIsNameChange({ id: item.id, oldName: item.imgName, newName: '' })
    },
    [isLook]
  )

  // 修改完这点击 确定修改
  const isNameChangeOkFu = useCallback(async () => {
    // if (!isNameChange.newName) return MessageFu.warning("图片名不能为空!");
    // const res = await A2_APIchangeImgName({
    //   id: isNameChange.id,
    //   fileName: isNameChange.newName,
    // });
    // if (res.code === 0) {
    //   MessageFu.success("修改图片名成功!");
    //   setFileList({
    //     ...fileList,
    //     img: fileList.img.map((v) => ({
    //       ...v,
    //       imgName: v.id === isNameChange.id ? isNameChange.newName : v.imgName,
    //     })),
    //   });
    //   isNameChangeXFu();
    // }
  }, [])
  //

  return (
    <div className={classNames(styles.ZupTypes, isLook ? styles.ZupTypesLook : '')}>
      <input
        id='upInput'
        type='file'
        accept={
          fileOneType === 'img'
            ? '.png,.jpg,.jpeg'
            : fileOneType === 'audio'
            ? '.mp3'
            : fileOneType === 'model'
            ? '.4dage'
            : '.mp4'
        }
        ref={myInput}
        onChange={e => handeUpPhoto2(e)}
      />
      <div hidden={isTypeShow}>
        <Checkbox.Group
          options={typeCheckArr}
          value={typeCheck}
          onChange={e => setTypeCheck(e as string[])}
        />
      </div>

      {/* -----------模型 */}
      {resOneDivDom('model')}

      {/* -----------图片 */}
      <div className='ZTboxImgMain' hidden={!typeCheck.includes('img')}>
        <div className='ZTboxImgBox'>
          <div className='ZTbox1' hidden={isTypeShow}>
            <span> </span> 图片：
          </div>

          <div className='ZTbox1Img' style={{ width: isTypeShow ? '100%' : '' }}>
            <div
              hidden={(!!fileList.img.length && fileList.img.length >= imgLength) || isLook}
              className='ZTbox1ImgIcon'
              onClick={() => upFileFu('img')}
            >
              <PlusOutlined rev={undefined} />
            </div>
            {fileList.img.map((v, i) => (
              <div
                className='ZTbox1ImgRow'
                key={v.id}
                draggable='true'
                onDragStart={() => setDragImg(v)}
                onDragOver={e => handleDragOver(e, v)}
                onDragEnter={e => handleDragEnter(e, v)}
                onDragEnd={() => setDragImg(null)}
              >
                {v.thumb || v.filePath ? (
                  <ImageLazy noLook={true} width={100} height={100} src={v.thumb || v.filePath} />
                ) : null}

                {oneIsCover && i === 0 ? <div className='ZTbox1ImgRowCover'>封面</div> : null}

                {/* 修改图片名字 */}
                {isUpName ? (
                  <div
                    title={v.imgName}
                    className='ZTbox1ImgRowName'
                    onClick={() => isNameChangeFu(v)}
                  >
                    {v.imgName}
                  </div>
                ) : null}

                <div className='ZTbox1ImgRowIcon'>
                  <EyeOutlined
                    onClick={() =>
                      store.dispatch({
                        type: 'layout/lookBigImg',
                        payload: {
                          url: baseURL + v.filePath,
                          show: true
                        }
                      })
                    }
                    rev={undefined}
                  />
                  <a href={baseURL + v.filePath} download target='_blank' rel='noreferrer'>
                    <DownloadOutlined rev={undefined} />
                  </a>
                </div>

                <MyPopconfirm
                  txtK='删除'
                  onConfirm={() => delImgListFu(v.id!)}
                  Dom={<CloseOutlined className='ZTbox1ImgRowX' rev={undefined} />}
                />
              </div>
            ))}
          </div>
        </div>

        <div className='ZTboxTit' hidden={isLook}>
          {fileList.img.length && fileList.img.length >= 2 ? (
            <>
              按住鼠标可拖动图片调整顺序。
              <br />
            </>
          ) : null}
          支持png、jpg的图片格式；最大支持5M；最多支持{imgLength}张。
          {lastImgTxt}
        </div>
      </div>

      {/* -----------音频 */}
      {resOneDivDom('audio')}

      {/* -----------视频 */}
      {resOneDivDom('video')}

      {/* 最后的提示 */}
      <div className={classNames('ZcheckTxt', fileCheck && fileCheckFu ? 'ZcheckTxtAc' : '')}>
        请最少上传一张图片!
      </div>

      {/* 点击修改名字出来的弹窗 */}
      {isNameChange.id ? (
        <Modal
          wrapClassName={styles.ZupTypesMo}
          open={true}
          title='修改展品图片名称'
          footer={
            [] // 设置footer为空，去掉 取消 确定默认按钮
          }
        >
          <br />
          <div className='ZupTypesMoRow'>
            <strong>当前名：</strong>
            {isNameChange.oldName}
          </div>
          <div className='ZupTypesMoRow'>
            <br />
            <strong>修改为：</strong>
            <Input
              style={{ width: 400 }}
              placeholder='请输入图片名'
              maxLength={50}
              showCount
              value={isNameChange.newName}
              onChange={e => {
                setIsNameChange({
                  ...isNameChange,
                  newName: e.target.value.replace(/\s+/g, '')
                })
              }}
            />
          </div>

          <div className='ZupTypesMoBtn'>
            <Button onClick={isNameChangeXFu}>取消</Button>
            &emsp;
            <Button type='primary' onClick={isNameChangeOkFu}>
              修改
            </Button>
          </div>
        </Modal>
      ) : null}
    </div>
  )
}

export default forwardRef(ZupTypes)
