/** @tips: 约定：该控件，获取文件路径字符串或上传了文件（即对应编辑时从接口获取的文件链接和新增时获取的对象），都会将符合要求的对象（上传的文件数据或自行拼接的，必须包含status、type、uid等必要字段）转化为字符串 */
/**
 * @description: 合并老版的文件、可预览文件、录音、视频
 * @params: 接收参数 renderTo: Recording/Video/File
 * @return: {Object} 文件类型返回需要另外处理
 * @date: 2021/12/1
 * @author: ChenLong
 * @待解决问题: 为什么list不直接返回url，而要把file对象变成对象字符串？
 */

/** @tips: 上传业务为：1.通过上传接口，上传文件，获取上传的链接；2.将文件链接存储到服务器，获取存储的地址；3.提交地址 */

/**
 * @description: 完成 1.文件名校验；2.编辑界面的文件加载及显示的能力；3.不同类型文件的判断
 * @date: 2021/12/2
 */

/**
 * @description: 合并图片/可预览图片到文件上传中
 * @date: 2021/12/6
 */

/**
 * @description: 文件类型单独处理。文件类型返回的是文件对象的字符串，使用JSON.parse解析之后，取url值即可，拼成用逗号分割的字符串即可。这部分修改在入口文件内
 * @description: 需要判断值是文件对象的字符串，约定：文件类必须会有 status: 'done'
 * @date: 2021/12/8
 */
/** @tips: 裁剪功能在前端框架内无法正常工作，暂不提供裁剪功能 */
// 自定义Form Render组件
import React, { useState, useEffect } from 'react';
import { Upload, Button, Modal, message } from 'antd';
import { UploadOutlined, DownloadOutlined } from '@ant-design/icons';

import './fileUpload.less';
import { downloadFunc, filenameVerification } from '../../utils/utils';
import { uploadFileUrl, downloadFileUrl } from '../../../api/service/workflow';
const videoTypeArray = ['.mp4'];
const audioTypeArray = ['.mp4'];
const fileTypeArray = [];
const imageTypeArray = ['.bmp', '.gif', '.jpeg', 'tiff', '.png', '.svg', '.jpg'];

const FileUpload = ({ value, onChange, schema }) => {
  const _isRecordingOrVideo = ['Recording', 'Video', 'Image'].includes(schema.renderTo);
  const _isVideo = schema.renderTo === 'Video';
  const _isAudio = schema.renderTo === 'Recording';
  const _isImage = schema.renderTo === 'Image';
  const [previewTitle, setPreviewTitle] = useState('');
  const [previewVisible, setPreviewVisible] = useState(false);
  const [previewUrl, setPreviewUrl] = useState('');
  const [showList, setShowList] = useState('');
  const file = value || schema.default;
  const option = {
    name: 'file',
    action: `${window.location.origin}${uploadFileUrl}`,
    listType: _isRecordingOrVideo ? 'picture-card' : 'picture',
    withCredentials: true,
    beforeUpload(file, fileList) {
      /** @tips: 解决提交文件中存在特殊字符的问题 */
      let _continueUpload = true;
      let _msg = {
        type: 'success',
        content: '上传成功！',
      };
      fileList.forEach((item) => {
        let _msgObject = filenameVerification(item);
        if (_msgObject.type === 'error') {
          _continueUpload = false;
          _msg = {
            type: 'error',
            content: '上传失败！文件名不符合规则！',
          };
        }
      });
      _msg.type === 'error' ? message[_msg.type](_msg.content) : '';
      return _continueUpload;
    },
    onChange: ({ file, fileList, event }) => {
      // 检验名字，名字不通过不允许显示
      if (filenameVerification(file).type === 'error') return false;
      // 返回的链接在file.response内；不设置url，预览图表不可点击
      if (file.status === 'done' && file.response.code === 0) {
        file.url = `${downloadFileUrl}?filePath=${file.response.data}`;
        file.sourcePath = file.response.data;
        message.success('上传成功！');
      } else if (file.status === 'done' && file.response.code !== 0) {
        file.status = 'error';
        message.error('上传失败！');
      }
      onChange((fileList && fileList.length && JSON.stringify(fileList)) || '');
      setShowList(JSON.stringify(fileList));
    },
    onPreview(file) {
      if (_isRecordingOrVideo) {
        setPreviewVisible(true);
        setPreviewUrl(file.url);
      }
    },
    previewFile(file) {},
    onDownload(file) {
      downloadFunc(file.url, file.name, '_self');
    },
  };
  const handleCancel = () => {
    setPreviewVisible(false);
    setPreviewTitle('');
  };
  /**
   * @description: 返回文件类型限定值
   * @params: {Array} typeArray: Video | Recording | File
   * @date: 2021/12/2
   * @author: ChenLong
   */
  const returnFileTypeString = (type) => {
    let _obj = {
      Video: videoTypeArray,
      Recording: audioTypeArray,
      File: fileTypeArray,
      Image: imageTypeArray,
    };
    return _obj[type].join(',');
  };
  useEffect(() => {
    let fileList = [];
    (file || '').split(',').forEach((item, index) => {
      if (item && filenameVerification({ name: item }, true).type !== 'error') {
        // @Tips: 直接过滤掉名字中有异常字符的文件
        let _obj = {
          uid: index + '_' + Math.random(),
          value: item,
          name: item.split('\\').reverse()[0],
          type: schema.renderTo === 'Image' ? 'image' : 'file',
          status: 'done',
          url: `${downloadFileUrl}?filePath=${item}`,
          sourcePath: item,
        };
        if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}`;
        fileList.push(_obj);
      }
    });
    // onChange(fileList.length && JSON.stringify(fileList) || '');
    setShowList(JSON.stringify(fileList));
  }, []);
  useEffect(() => {
    if (value) {
      let fileList = [];
      (file || '').split(',').forEach((item, index) => {
        if (item && filenameVerification({ name: item }, true).type !== 'error') {
          // @Tips: 直接过滤掉名字中有异常字符的文件
          let _obj = {
            uid: index + '_' + Math.random(),
            value: item,
            name: item.split('\\').reverse()[0],
            type: schema.renderTo === 'Image' ? 'image' : 'file',
            status: 'done',
            url: `${downloadFileUrl}?filePath=${item}`,
            sourcePath: item,
          };
          if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}`;
          fileList.push(_obj);
        }
      });
      // onChange(fileList.length && JSON.stringify(fileList) || '');
      setShowList(JSON.stringify(fileList));
    }
  }, [value]);
  return (
    <>
      {/** @tips: 裁剪功能无法正常工作，暂不提供 */}
      {/*      <ImgCrop beforeCrop={(file) => {
        let _returnObj = filenameVerification(file);
        if (_returnObj.type === 'error') {
          message.error(_returnObj.content);
          return false;
        }
        return schema.renderTo === 'Image';
      }} rotate locale={'zh-cn'} modalTitle={'编辑图片'} modalOk={'确定'}
               modalCancel={'取消'}>*/}
      <Upload
        disabled={schema.disabled}
        {...option}
        fileList={showList ? JSON.parse(showList) : []}
        multiple
        style={{ width: '100%' }}
        className={_isRecordingOrVideo ? 'formUploadVideoOrRecording' : 'formUpload'}
        showUploadList={{
          showPreviewIcon: _isRecordingOrVideo,
          showDownloadIcon: true,
          downloadIcon: <DownloadOutlined />,
        }}
        accept={returnFileTypeString(schema.renderTo)}
      >
        {!_isRecordingOrVideo ? (
          <Button disabled={schema.disabled} icon={<UploadOutlined />}>
            Upload
          </Button>
        ) : (
          '+ Upload'
        )}
      </Upload>
      {/*      </ImgCrop>*/}
      <Modal
        style={{ width: '30%' }}
        bodyStyle={{ textAlign: 'center' }}
        visible={previewVisible}
        title={previewTitle}
        footer={null}
        onCancel={handleCancel}
      >
        {_isVideo ? (
          <video width={'100%'} height={'100%'} controls autoPlay src={previewUrl} />
        ) : (
          ''
        )}
        {_isAudio ? <audio controls autoPlay src={previewUrl} /> : ''}
        {_isImage ? <img width={'100%'} height={'100%'} src={previewUrl} alt="缩略图" /> : ''}
      </Modal>
    </>
  );
};

export default FileUpload;
