/*
 * @Author: 吴文洁 
 * @Date: 2020-06-09 10:47:51 
 * @Last Modified by: 吴文洁
 * @Last Modified time: 2020-07-23 09:33:09
 * @Description: 文件夹列表
 */

import React from 'react';
import { Table, Menu, Dropdown, Upload, Modal, message, Tooltip, Icon } from 'antd';

import { PageControl } from '@/components';
import DefaultIcon from '@/modules/common/DefaultIcon';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { FileTypeIcon, SupportFileType, DEFAULT_SIZE_UNIT } from "@/common/constants/academic/lessonEnum";

import ScanFileModal from '../modal/ScanFileModal';
import CreateFolderModal from '../modal/CreateFolderModal';
import UploadProgressModal from '../modal/UploadProgressModal';
import SelectPrepareFileModal from '../modal/SelectPrepareFileModal';

const DEL_FOLDER_URL_MAP = {
  'MYSELF': 'public/apollo/delFolder',
  'COMMON': 'public/apollo/delCommonFolder'
}



let count = 0;

class FolderList extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      localFileList: [],              // 本地文件列表（待上传）
      currentFolder: {},              // 当前文件/文件夹（操作列表中的文件/文件夹的时候需要用到）
      uploadFolderPath: {},       // 上传文件的目录，防止中途切换文件夹
      renameModalData: {},            // 重命名弹窗
      scanFileModal: null,            // 预览文件弹窗
      showUploadModal: false,         // 上传进度弹窗，
      nonCompliantFileList: []
    }
  }

  componentWillReceiveProps(nextProps) {
    const { folderPathList } = nextProps
    const currentFolder = folderPathList[folderPathList.length - 1];
    this.setState({
      currentFolder
    })
  }
  //预览文件
  handleSelect = (folder)  => {
    // 只有文件才有预览功能
    if (folder.folderType === 'FOLDER') {
      this.handleSelectFolder(folder);
    } else {
      this.handleScanFile(folder);
    }
  }

  // 预览文件
  handleScanFile =  (folder) => {
    const { folderFormat, folderSize, ossUrl } = folder;
    switch (folderFormat) {
      case 'PDF':
        window.open(ossUrl, "_blank");
        break;
      case "WORD":
      case "DOCX":
      case "DOC":
      case "EXCEL":
      case "PPT":
      case "PPTX":
      case "PDF":
        if ((folderFormat === 'PPT' || folderFormat === 'PPTX' ||
          folderFormat === 'DOCX' || folderFormat === 'WORD' ||
          folderFormat === 'DOC') && folderSize  > 10 * DEFAULT_SIZE_UNIT) {
          Modal.confirm({
            title: '抱歉，不能在线预览',
            content: '由于文件较大，不支持在线预览，请下载后再查看',
            icon:  <QuestionCircleOutlined />,
            okText:"下载",
            onOk:() => {
              const a = document.createElement('a');
              a.href = ossUrl;
              a.click();
            }
          });
          break;
        }
        if (folderFormat === 'EXCEL' && folderSize > 5 * DEFAULT_SIZE_UNIT) {
          Modal.confirm({
            title: '抱歉，不能在线预览',
            content: '由于文件较大，不支持在线预览，请下载后再查看',
            icon:  <QuestionCircleOutlined />,
            okText:"下载",
            onOk:() => {
              const a = document.createElement('a');
              a.href = ossUrl;
              a.click();
            }
          });
          break;
        }
        const prefixUrl = "https://view.officeapps.live.com/op/view.aspx?src=";
        const scanUrl = `${prefixUrl}${encodeURIComponent(ossUrl)}`
        window.open(scanUrl, "_blank");
        break;
      default:
        const scanFileModal = <ScanFileModal
          fileType={folderFormat}
          item={folder}
          close={() => {
            this.setState({ scanFileModal: null })
          }}
        />
        this.setState({ scanFileModal });
        break;
    }
  }

  // 选择文件夹
  handleSelectFolder = (folder) => {
    const { folderPathList, showResultPage, currentRootDisk } = this.props;
    // 判断是否是员工文件的根目录
    const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 1;
    if (showResultPage) {
      folderPathList.pop();
    }
    folderPathList.push({
      id: folder.id,
      folderName: folder.folderName
    });
    this.props.onChangeFolderPath(folderPathList);
    this.props.onRefresh({
      parentId: folder.id,
      folderIdType: employeeDisk ? 'USER' : 'FOLDER'
    });
  }

  // 修改文件路径
  handleChangeFolderPath = (folder) => {
    const { instId } = window.currentUserInstInfo;
    const { id } = folder;
    const { currentRootDisk } = this.props;
    const params = {
      id,
      instId: instId || LS.get('instId'),
      disk: currentRootDisk.disk,
    }

    axios.Apollo('public/apollo/folderPath', params).then((res) => {
      const { result = [] } = res;
      this.props.onChangeFolderPath(result, false);
    })
  }

  parseColumns = () => {
    const { currentRootDisk, showResultPage, folderPathList } = this.props;
    const hasManagementAuthority = currentRootDisk.uploadPower;
    // 判断是否是员工文件的根目录
    const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 1;

    const columns =  [
      {
        title: '名称',
        key: 'folderName',
        dataIndex: 'folderName',
        width: '28%',
        sorter: (employeeDisk || !hasManagementAuthority) ? false : true,
        render: (value, record) => {
          const { folderType, folderFormat } = record;
          const isFolder = folderType === 'FOLDER';

          let imgSrc = !isFolder ?
            FileTypeIcon[folderFormat] :
            'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1594871430788.png';
          
          if (employeeDisk) {
            imgSrc = 'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1594871440736.png'
          }

          return (
            <div
              className="file-name"
              onClick={() => this.handleSelect(record)}
            >
              {
                <img
                  alt="img-src"
                  className="file-name__icon"
                  src={imgSrc}
                />
              }
              <span
                className={`file-name__text ${!isFolder ? 'highlight' : ''}`}
              >
                {value}
              </span>
            </div>
          )
        }
      },
      {
        title: '更新时间',
        key: 'updated',
        dataIndex: 'updated',
        sorter: (employeeDisk || !hasManagementAuthority) ? false : true,
        render: (value) => {
          return <span>{formatDate('YYYY-MM-DD H:i', value)}</span>
        }
      },
      {
        title: '大小',
        key: 'folderSize',
        dataIndex: 'folderSize',
        width: '10%',
        sorter: (employeeDisk || !hasManagementAuthority) ? false : true,
        render: (value, record) => {
          const { folderType } = record;
          const _fileSize = Number(value);
           let _size = `${(_fileSize / DEFAULT_SIZE_UNIT).toFixed(1)}M`;
            if (_fileSize < 0.1 * DEFAULT_SIZE_UNIT) {
              _size = `${(_fileSize / 1024).toFixed(1)}kb`;
            }
          return (
            <span>{folderType === 'FILE' ? _size : '-'}</span>
          )
        }
      },
      {
        title: '操作',
        key: 'operate',
        render: (value, record) => {
          if (!(currentRootDisk.disk === 'EMPLOYEE' && (folderPathList.length === 1 || record.folderType === 'FOLDER')) || 
            hasManagementAuthority) {
             return (
              <Dropdown overlay={this.renderMenu(record)} trigger={['hover']}>
                <span className="icon iconfont">&#xe756;</span>
              </Dropdown>
            )
          }
          return <span>-</span>
        }
      }
    ]

    // 公共文件需要显示创建者
    if (currentRootDisk.disk === 'COMMON') {
      columns.splice(1, 0, {
        title: '创建者',
        key: 'createName',
        dataIndex: 'createName'
      });
    }

    // 搜索结果需要显示所在目录
    if (showResultPage) {
      columns.push({
        title: '所在目录',
        key: 'parentName',
        dataIndex: 'parentName',
        render: (value, record) => {
          return <span
            className="file-path"
            onClick={() => this.handleChangeFolderPath(record)}
          >
            {value || currentRootDisk.folderName}
          </span>
        }
      })
    }
    return columns;
  }

  // 删除文件
  handleDeleteFolder = (folder) => {
    const { currentRootDisk: { disk } } = this.props;
    const { instId } = window.currentUserInstInfo;
    // 判断此文件是否有关联的课次
    axios.Apollo('public/apollo/judgeRelation', {
      folderIds: [folder.id],
      instId: instId || LS.get('instId')
    }).then((res) => {
      // 如果有关联的文件，二次弹窗确认
      const hasRelative = !!res.result;
      Modal.confirm({
        title: '确认删除所选的文件吗？',
        content: hasRelative ? '此文件已关联了课次，删除后，学员将不能查看到此文件。' : '删除后，数据将无法恢复。',
        icon: <span className="icon iconfont default-confirm-icon">&#xe834;</span>,
        onOk: () => {
          const { currentFolder } = this.state;
          axios.Apollo(DEL_FOLDER_URL_MAP[disk], {
            ids: [folder.id],
            instId: instId || LS.get('instId')
          }).then(() => {
            message.success('删除成功');
            this.props.onRefresh({ parentId: currentFolder.id || null });
          })
        }
      });
    })
  }

  // 重命名
  handleRename = (folder) => {
    this.setState({
      renameModalData: {
        visible: true,
        id: folder.id,
        folderName: folder.folderName,
      }
    });
  }

  // 重命名完成或者取消重命名之后隐藏重命名弹窗
  handleRenameDone = (folderName) => {
    const { renameModalData, currentFolder } = this.state;
    
    // 名称未修改不发送请求
    if (folderName === renameModalData.folderName) {
      this.setState({ renameModalData: {} });
      return;
    }

    // 判断是否有同名文件
    this.handleGetSameNameFiles(folderName).then((res) => {
      if (res) {
        message.warning('此目录下已存在同名文件');
        return;
      }

      axios.Apollo('public/apollo/renameFolder', {
        id: renameModalData.id,
        name: folderName
      }).then(() => {
        message.success('重命名成功');
        this.setState({ renameModalData: {} });
        this.props.onRefresh({ parentId: currentFolder.id || null });
      })
    });
  }

  // 获取同名文件
  handleGetSameNameFiles = async (folderName) => {
    const { currentRootDisk, folderPathList } = this.props;
    const currentFolder = folderPathList[folderPathList.length - 1];
    const { instId } = window.currentUserInstInfo;
    const params = {
      name: folderName,
      disk: currentRootDisk.disk,
      parentId: currentFolder.id,
      folderType: 'FOLDER',
      instId: instId || LS.get('instId')
    }

    const res = await axios.Apollo('public/apollo/sameNameFile', params);
    const { result } = res;
    return !!result || result && Object.keys(result).length;
  }

  // 显示移动文件弹窗
  handleShowSelectFileModal = (file) => {
    this.setState({
      currentFile: file,
      showSelectFileModal: true
    });
  }

  getBlob = (url) => {
    return new Promise((resolve) => {
      const xhr = new XMLHttpRequest()

      xhr.open('GET', url, true)
      xhr.responseType = 'blob'
      xhr.onload = () => {
        if (xhr.status === 200) {
          resolve(xhr.response)
        }
      }
      xhr.send()
    })
  }
  
  saveAs = (blob, filename) => {
    if (window.navigator.msSaveOrOpenBlob) {
      navigator.msSaveBlob(blob, filename)
    } else {
      const link = document.createElement('a')
      const body = document.querySelector('body')
      
      // 创建对象url
      link.href = window.URL.createObjectURL(blob) 
      link.download = filename

      body.appendChild(link)

      link.click()
      body.removeChild(link)
      
      // 通过调用 URL.createObjectURL() 创建的 URL 对象
      window.URL.revokeObjectURL(link.href) 
    }
  }
  // 下载文件
  handleDownload = (folder) => {
    this.getBlob(folder.ossUrl).then((blob) => {
      this.saveAs(blob, folder.folderName)
    })
  }

  handleChooseFile = async () => {
    // 判断是否欠费，旗舰版用户不需要校验余额
    const { instId } = window.currentUserInstInfo;
    const ultimateRes = await axios.Business('public/inst/checkInstProduct', {
      instId: instId || LS.get("instId"),
      productCodeList: ['ULTIMATESELL', 'PIP_TO_ULTIMATE', 'HIGH_TO_ULTIMATE']
    });
    const { balance } = this.props;
    if (balance <= 0 && !ultimateRes.result) {
      this.handleShowNoticeModal();
      return;
    }

    const dom = document.querySelector('#detailFileInput');
    dom.click();
  }

  // 准备上传
  handleUpload = (event) => {
    const fileList = event.target.files;
    // 判断文件的大小是否超出了限制
    const nonCompliantFileList = [];
    const _fileList = [...fileList];
    _fileList.map((file, index) => {
      let { size, type, name } = file;
      if (!type) {
        type = getFileTypeByName(name);
      }
      if (type.indexOf('image') > -1 && size > 50 * DEFAULT_SIZE_UNIT) {
        nonCompliantFileList.push(file);
        _fileList.splice(index, 1);
      }
      if (type.indexOf('audio') > -1 && size > 50 * DEFAULT_SIZE_UNIT) {
        nonCompliantFileList.push(file);
        _fileList.splice(index, 1);
      }
      if (type.indexOf('video') > -1 && size > 500 * DEFAULT_SIZE_UNIT) {
        nonCompliantFileList.push(file);
        _fileList.splice(index, 1);
      }
      if (localFileType.indexOf(type) > -1 && size > 100 * DEFAULT_SIZE_UNIT) {
        nonCompliantFileList.push(file);
        _fileList.splice(index, 1);
      }
      file.key = count++;
    });
    // 不符合规则的文件列表
    if (nonCompliantFileList.length > 0) {
      this.setState({
        nonCompliantFileList,
        showNonCompliantFileModal: true,
      })
    } else {
      this.handleShowUploadModal(_fileList);
    }

    // 清空文件，防止第二次无法上传同一个文件
    const dom = document.querySelector('#detailFileInput');
    dom.value = '';
  }

  // 显示上传进度弹窗
  handleShowUploadModal = (fileList) => {
    // 保存当前路径
    const { folderPathList } = this.props;
    if (fileList.length) {
      this.setState({
        showUploadModal: true,
        localFileList: fileList,
        uploadFolderPath: folderPathList[folderPathList.length - 1]
      });
    }
  }

  // 上传成功
  handleUploadDone = (file, resourceId) => {
    this.props.onCreate(file, resourceId);
  }

  // 取消上传
  handleHiddenUploadModal = () => {
    this.setState({
      showUploadModal: false,
      localFileList: []
    });
  }

  // 余额欠费提示弹窗
  handleShowNoticeModal = () => {
    const { balance } = this.props;
    Modal.info({
      title: '无法继续操作',
      content: '直播服务已升级，请联系运营老师。',
      icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>
    })
  }

  // 排序
  handleChangeTable = (pagination, filters, sorter) => {
    const { columnKey, order } = sorter;
    let sort = null;
    if (columnKey === 'folderName' && order === 'ascend') { sort = 'NAME_ASC'; }
    if (columnKey === 'folderName' && order === 'descend') { sort = 'NAME_DESC'; }
    if (columnKey === 'folderSize' && order === 'ascend') { sort = 'SIZE_ASC'; }
    if (columnKey === 'folderSize' && order === 'descend') { sort = 'SIZE_DESC'; }
    if (columnKey === 'updated' && order === 'ascend') { sort = 'UPDATE_ASC'; }
    if (columnKey === 'updated' && order === 'descend') { sort = 'UPDATE_DESC'; }

    const { currentFolder } = this.state;

    this.props.onRefresh({
      sort,
      parentId: currentFolder.id || null
    });
  }

  renderMenu = (record) => {
    const { currentRootDisk } = this.props;
    // 是否有编辑权限
    const hasManagementAuthority = currentRootDisk.uploadPower;
    const { folderType } = record;
    const menu = (
      <Menu>
        {
          folderType === 'FILE' &&
          <Menu.Item key="download">
            <span onClick={() => { this.handleDownload(record) }}>下载</span>
          </Menu.Item>
        }
        {
          hasManagementAuthority &&
          [
            <Menu.Item key="move">
              <span onClick={() => this.handleShowSelectFileModal(record)}>移动</span>
            </Menu.Item>,
            <Menu.Item key="rename">
              <span onClick={() => this.handleRename(record)}>重命名</span>
            </Menu.Item>,
            <Menu.Item key="delete">
              <span onClick={() => this.handleDeleteFolder(record)}>删除</span>
            </Menu.Item>
          ]
        }
      </Menu>
    );
    return menu;
  }

  render()  {

    const {
      currentFolder, showScanFileModal, currentFile, renameModalData,
      showSelectFileModal, showUploadModal, localFileList, currentFolderName
    } = this.state;
    const {
      selectedFileIds, folderList, showResultPage, folderPathList,
      currentRootDisk, balance, query, totalCount
    } = this.props;
    
    // 是否有编辑权限
    const hasManagementAuthority = currentRootDisk.uploadPower;
    
    // 是否已经欠费
    const hasOwnedFee = balance <= 0;
    return (
      <div className="file-list">
        {
         !_.isEmpty(folderList) ?
          [<Table
            key="table"
            rowKey={(record) => record.id}
            columns={this.parseColumns()}
            dataSource={folderList}
            rowSelection={
              hasManagementAuthority ? {
                selectedRowKeys: selectedFileIds,
                onChange: this.props.onChangeRow
              } : null
            }
            pagination={false}
            onChange={this.handleChangeTable}
          />,
          <div className="box-footer" key="pagination">
            <PageControl
              current={query.current - 1}
              pageSize={query.size}
              total={totalCount}
              showSizeChanger={true}
              toPage={(page) => this.props.onChangePage('current', page + 1)}
              onShowSizeChange={(current, size) => this.props.onChangePage('size', size)}
            />
          </div>] :
          <DefaultIcon
            type='student'
            title={
              !showResultPage ?
              <div className="desc">
                <input
                  multiple
                  type="file"
                  style={{ display: 'none' }}
                  id="detailFileInput"
                  accept=".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls"
                  onChange={(e) => this.handleUpload(e)}
                />
          
                {
                  hasManagementAuthority ?
                  <div>你还没有上传文件，点击
                    <Tooltip title="支持文件类型：ppt、word、excel、pdf、jpg、mp3、mp4">
                      <span
                        className="upload-btn"
                        onClick={this.handleChooseFile}
                      >上传文件</span>
                    </Tooltip>
                    按钮
                  </div> :
                  <span>这个文件夹是空的</span>
                }
              </div> :
              <div className="desc">搜索无结果</div>
            }
          />
        }
        
        <CreateFolderModal
          title="重命名"
          folderName={renameModalData.folderName}
          isOpen={renameModalData.visible}
          onClose={() => { this.setState({ renameModalData: {} })}}
          onOk={this.handleRenameDone}
        />

        <UploadProgressModal
          isOpen={showUploadModal}
          currentFolder={currentFolder}
          fileList={localFileList}
          onUpload={this.handleUploadDone}
          onCancel={this.handleHiddenUploadModal}
        />
        
        <SelectPrepareFileModal
          multiple={true}
          isOpen={showSelectFileModal}
          currentRootDisk={currentRootDisk}
          onClose={() => {
            this.setState({ showSelectFileModal: false });
          }}
          onMove={(targetFolder) => {
            this.setState({ showSelectFileModal: false });
            this.props.onMove(targetFolder, [currentFile.id]);
          }}
        />
        
       { this.state.scanFileModal }
       { this.state.chargeModal }
      </div>
    )
  }
}

export default FolderList;