/*
 * @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, Modal, message,Tooltip } from 'antd';
import _ from 'underscore';
// import * as lodash from 'lodash';
import { PageControl, LottieIcon } from 'xiaomai-b-components';

import Service from '@/common/js/service';
import { formatDate } from '@/domains/basic-domain/utils';
import { FILE_TYPE_ICON_MAP, SUPPORT_FILE_TYPE_MAP, DEFAULT_SIZE_UNIT } from '@/domains/resource-disk/constants';
import { getFileTypeByName } from '@/domains/resource-disk/utils';

import UploadProgressModal from '@/bu-components/UploadProgressModal';
import SelectPrepareFileModal from '@/bu-components/SelectPrepareFileModal';
import CopyFileModal from '@/bu-components/CopyFileModal';
import ManagingMembersModal from '@/bu-components/ManagingMembersModal';


import ScanFileModal from '../modal/ScanFileModal';
import CreateFolderModal from '../modal/CreateFolderModal';
import User from '@/common/js/user';


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

// 支持本地上传的文件类型
const loaclFileType = SUPPORT_FILE_TYPE_MAP.join(',');

let count = 0;

class FolderList extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      localFileList: [],              // 本地文件列表（待上传）
      currentFolder: {},              // 当前文件/文件夹（操作列表中的文件/文件夹的时候需要用到）
      uploadFolderPath: {},           // 上传文件的目录，防止中途切换文件夹
      renameModalData: {},            // 重命名弹窗
      scanFileModal: null,            // 预览文件弹窗
      showUploadModal: false,         // 上传进度弹窗
      showCopyFileModal: false,       // 复制文件弹窗
      showManagingModal: false,       // 管理文件查看编辑权限
      nonCompliantFileList: [],       // 不符合上限的文件列表
      parentRights: ''              // 继承父级文件夹权限
    }
  }

  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);
    }
  }

    // 埋点
    handleDataDot = (folderFormat) => {
      switch (folderFormat) {
        case 'PDF':
          window.WEBTRACING('resource_disk_file_preview_pdf', '资料云盘_点击预览_pdf');
          break;
        case 'WORD':
        case 'DOCX':
        case 'DOC':
          window.WEBTRACING('resource_disk_file_preview_word', '资料云盘_点击预览_word');
          break;
        case 'EXCEL':
          window.WEBTRACING('resource_disk_file_preview_excel', '资料云盘_点击预览_excel');
          break;
        case 'PPT':
        case 'PPTX':
          window.WEBTRACING('resource_disk_file_preview_ppt', '资料云盘_点击预览_ppt');
          break;
         default:
          break;
    }
  }

  // 预览文件
  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: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
            okText: "下载",
            onOk: () => {
              const a = document.createElement('a');
              a.href = ossUrl;
              a.click();
            }
          });
          break;
        }
        if (folderFormat === 'EXCEL') {
          Modal.confirm({
            title: '抱歉，不能在线预览',
            content: ' 该文件类型不支持在线预览，请下载后再查看',
            // icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
            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;
    }

      // 预览文件埋点
      this.handleDataDot(folderFormat);
  }

  // 选择文件夹
  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.setState({
      parentRights: folder.rights,
    })
    this.props.onChangeFolderPath(folderPathList);
    this.props.onRefresh({
      parentId: folder.id,
      parentRights: folder.rights,
      folderIdType: employeeDisk ? 'USER' : 'FOLDER'
    });
  }

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

    Service.Hades('public/hadesStore/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 ?
            FILE_TYPE_ICON_MAP[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 === 'COMMON' && (folderPathList.length === 1 || record.folderType === 'FOLDER')) ||
            hasManagementAuthority) {
            return (
              <Dropdown overlay={this.renderMenu(record)} trigger={['hover']}>
                <span className="icon iconfont">&#xe62c;</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;
    Modal.confirm({
      title: '确认删除所选的文件吗？',
      content: '删除后，数据将无法恢复。',
      icon:<span className="icon iconfont default-confirm-icon">&#xe839; </span>,
      okType: 'danger',
      onOk: () => {
        const { currentFolder } = this.state;
        Service.Hades(DEL_FOLDER_URL_MAP[disk], {
          operatorId: User.getUserId(),
          storeId: User.getStoreId(),
          ids: [folder.id],
        }).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) => {
    return new Promise((resolve) => {
      const { renameModalData, currentFolder } = this.state;
      const { folderPathList } = this.props;
      // 名称未修改不发送请求
      if (folderName === renameModalData.folderName) {
        this.setState({ renameModalData: {} });
        return;
      }

      // 判断是否有同名文件
      this.handleGetSameNameFiles(folderName).then((res) => {
        if ((!!res) || (res && Object.keys(res).length)) {
          if (!res.isLook && folderPathList.length === 1) {
            message.warning('此目录下已存在同名文件，有疑问请联系机构校长');
          } else {
            message.warning('此目录下已存在同名文件');
          }
          return;
        }

        Service.Hades('public/hadesStore/renameFolder', {
          id: renameModalData.id,
          name: folderName
        }).then(res2 => {
          if (!res2.success) {
            const errorMessage = '此目录下已存在同名文件';
            message.warning(errorMessage);
            return;
          } else {
            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 = {
      createId:User.getUserId(),
      name: folderName,
      disk: currentRootDisk.disk,
      parentId: currentFolder.id,
      folderType: 'FOLDER',
    }

    const res = await Service.Hades('public/hadesStore/sameNameFile', params);
    const { result } = res;
    return result;
  }

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

  // 显示复制文件弹窗
  handleShowCopyFileModal = (file) => {
    this.setState({
      currentFile: file,
      showCopyFileModal: true
    });
  }

  // 显示管理成员弹窗
  handleShowManagingModal = (file) => {
    this.setState({
      currentFile: file,
      showManagingModal: 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 Service.Business('public/inst/checkInstProduct', {
    //   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 > 2000 * DEFAULT_SIZE_UNIT) {
        nonCompliantFileList.push(file);
        _fileList.splice(index, 1);
      }
      if (loaclFileType.indexOf(type) > -1 && size > 100 * DEFAULT_SIZE_UNIT) {
        nonCompliantFileList.push(file);
        _fileList.splice(index, 1);
      }
      file.key = count++;
      return file;
    });
    // 不符合规则的文件列表
    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 = () => {
    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, rights } = record;
    const menu = (
        <Menu>
          {
            rights === "EDIT" && !record.parentId &&
            [
              <Menu.Item key="administration">
                <span onClick={() => this.handleShowManagingModal(record)}>权限管理</span>
              </Menu.Item>,
              <Menu.Divider key="administration-bottom"/>
            ]
          }
          {
            folderType === 'FILE' && 
            <Menu.Item key="download">
              <span onClick={() => { this.handleDownload(record) }}>下载</span>
            </Menu.Item>
          }
          {
            currentRootDisk.disk === 'COMMON' && 
            <Menu.Item key="copy">
              <span onClick={() => this.handleShowCopyFileModal(record)}>复制到</span>
            </Menu.Item>
          }
          {
            hasManagementAuthority && rights === "EDIT" &&
            [
              <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.Divider key="administration-top"/>,
              <Menu.Item key="delete">
                <span onClick={() => this.handleDeleteFolder(record)}>删除</span>
              </Menu.Item>
            ]
          }
        </Menu>
      );
      return menu;
  
    
  }

  render() {

    const {
      currentFolder, currentFile, renameModalData, showSelectFileModal,
      showUploadModal, localFileList, showCopyFileModal, showManagingModal
    } = this.state;
    const {
      selectedFileIds, folderList, showResultPage,
      currentRootDisk, query, totalCount, folderPathList
    } = this.props;
    const _disk = folderPathList[0].disk;
    // 是否有编辑权限
    const hasManagementAuthority = currentRootDisk.uploadPower;

    return (
      <div className="file-list">
        <Choose>
          <When condition={!_.isEmpty(folderList)}>
            <Table
              key="table"
              rowKey={(record) => record.id}
              columns={this.parseColumns()}
              showSorterTooltip={false}
              dataSource={folderList}
              rowSelection={
                 {
                  selectedRowKeys: selectedFileIds,
                  onChange: this.props.onChangeRow
                } 
              }
              pagination={false}
              onChange={this.handleChangeTable}
            />
            <PageControl
              current={query.current - 1}
              pageSize={query.size}
              total={totalCount}
              showSizeChanger={true}
              toPage={(page) => {
                this.props.onChangePage('current', page + 1);
              }}
              onShowSizeChange={(current, size) => {
                const that = this;
                setTimeout(()=>{
                  this.props.onChangePage('size', size)
                },1000)
              }}
            />
          </When>

          <Otherwise>
            <LottieIcon
              title={
                <Choose>
                  <When condition={!showResultPage}>
                    <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)}
                    />

                    {
                      <Choose>
                        <When condition={hasManagementAuthority}>
                          <div>你还没有上传文件，点击
                            <Tooltip title="支持文件类型：ppt、word、excel、pdf、jpg、mp3、mp4">
                              <span
                                className="upload-btn"
                                onClick={this.handleChooseFile}
                              >上传文件</span>
                            </Tooltip>
                            按钮
                          </div>
                        </When>
                        <Otherwise>
                          <span>这个文件夹是空的</span>
                        </Otherwise>
                      </Choose>
                    }
                  </When>
                  <Otherwise>
                    <div className="desc">搜索无结果</div>
                  </Otherwise>
                </Choose>
              }
            />
          </Otherwise>
        </Choose>
        
        <CreateFolderModal
          title='重命名'
          folderName={renameModalData.folderName}
          folderPathList={folderPathList}
          isOpen={renameModalData.visible}
          onClose={() => {
            this.setState({ renameModalData: {} });
          }}
          onOk={this.handleRenameDone}
        />


        <UploadProgressModal
          isOpen={showUploadModal}
          currentFolder={currentFolder}
          fileList={localFileList}
          onUpload={this.handleUploadDone}
          onCancel={this.handleHiddenUploadModal}
        />

        <SelectPrepareFileModal
          isOpen={showSelectFileModal}
          currentRootDisk={currentRootDisk}
          onClose={() => {
            this.setState({ showSelectFileModal: false });
          }}
          onMove={(query) => {
            this.setState({ showSelectFileModal: false });
            this.props.onMove(query, [currentFile.id]);
          }}
        />
        {
          showCopyFileModal &&
          <CopyFileModal 
            isOpen={showCopyFileModal}
            dataInfo={currentFile}
            currentRootDisk={currentRootDisk}
            onClose={() => {
              this.setState({ showCopyFileModal: false });
            }}
          />
        }
        {
          showManagingModal &&
          <ManagingMembersModal 
            isOpen={showManagingModal}
            dataInfo={currentFile}
            disk={_disk}
            onClose={() => {
              this.setState({ showManagingModal: false });
            }}
          />
        }
        
       { this.state.scanFileModal }
       { this.state.chargeModal }
      </div>
    )
  }
}

export default FolderList;