/*
 * @Author: 吴文洁 
 * @Date: 2020-06-09 09:59:27 
 * @Last Modified by: 吴文洁
 * @Last Modified time: 2020-07-23 09:33:15
 * @Description: 文件夹操作区
 */

import React from 'react';
import { Button, Upload, Modal, message, Tooltip } from 'antd';

import Bus from '@/core/bus';
import { getEllipsText } from "@/core/util";
import { SearchBar } from '@/components';

import { DEFAULT_SIZE_UNIT, SupportFileType, LocalFileType } from "@/common/constants/academic/lessonEnum";
import CreateFolderModal from '../modal/CreateFolderModal';
import UploadProgressModal from '../modal/UploadProgressModal';
import SelectPrepareFileModal from '../modal/SelectPrepareFileModal';
import NonCompliantFileModal from '../modal/NonCompliantFileModal';

import { getFileTypeByName } from './FolderManage';

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

// 支持本地上传的文件类型
const supportFileType = SupportFileType.join(',');
const localFileType = LocalFileType.join(',');

let count = 0;

class OperateArea extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      fileList: [],
      localFileList: [],              // 本地文件列表（待上传）
      folderPathList: [],
      nonCompliantFileList: [],       // 超出大小的文件列表
      uploadFolderPath: {},           // 上传文件的目录，防止中途切换文件夹
      showUploadModal: false,         // 上传进度弹窗
      showSelectFileModal: false,     // 移动文件弹窗
      showCreateFolderModal: false,   // 创建文件夹弹窗
      showNonCompliantFileModal: false,  // 文件超出大小限制弹窗
    }
  }

  componentWillReceiveProps(nextProps) {

    // 切换磁盘的时候需要清空搜索条件
    if (!_.isEqual(nextProps.currentRootDisk, this.props.currentRootDisk)) {
      Bus.trigger('resetSearchBar');
    }
  }
  
  // 显示创建文件夹弹窗
  handleToggleCreateFolderModal = 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']
    });
    // 校验余额，旗舰版用户不需要校验余额
    if (this.props.balance <= 0 && !ultimateRes.result) {
      this.handleShowNoticeModal();
      return;
    }
    // 判断当前目录是否在第10层，如果是的话提示最多只能创建10层文件夹
    const { folderPathList } = this.props;

    if (folderPathList.length > 10) {
      message.warning('最多只能创建10层文件夹');
      return;
    }
    this.setState({
      showCreateFolderModal: !this.state.showCreateFolderModal
    });
  }

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

        this.props.onCreate({ name: folderName });
        this.handleToggleCreateFolderModal();
        resolve(true);
      });
    })
  }

  // 获取同名文件
  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;
  }

  // 准备上传
  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({
        fileList: _fileList,
        nonCompliantFileList,
        showNonCompliantFileModal: true,
      })
    } else {
      this.handleShowUploadModal(_fileList);
    }

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

  handleChooseFile = async () => {
    // 判断是否欠费，旗舰版用户不需要校验余额
    const { balance } = this.props;
    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']
    });

    if (balance <= 0 && !ultimateRes.result) {
      this.handleShowNoticeModal();
      return;
    }

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

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

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

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

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

  // 格式化文件路径
  handleFormatFilePath = (folderPathList) => {
    let currentIndex = folderPathList.length - 1;
    if (currentIndex >= 4) {
      const _currentIndex = currentIndex - 3;
      const _folderPathList = [...folderPathList];
      _folderPathList.splice(1, _currentIndex, {
        folderName: '...',
        key: 'ellipses'
      });
      return _folderPathList;
    }

    return folderPathList;
  }

  // 切换当前显示的文件夹
  handleChangeCurrentFolder = (folderPath) => {
    // 点击中间的省略号或者搜索的关键字，不请求数据
    const { folderPathList } = this.props;
    const index = _.findIndex(folderPathList, (item) => item.id === folderPath.id);

    if (folderPath.key === 'ellipses' ||
      index === folderPathList.length - 1 ||
      (!folderPath.key && !folderPath.disk && !folderPath.id)) return;
    
    folderPathList.splice(index+1, folderPathList.length);
    const currentFolder = folderPathList[folderPathList.length - 1];

    this.props.onChangeFolderPath(folderPathList);
  }

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

  render() {
    
    const {
      showCreateFolderModal, showUploadModal, showSelectFileModal,
      localFileList, nonCompliantFileList, showNonCompliantFileModal
    } = this.state;

    const {
      selectedFileIds, searchKey, showResultPage,
      currentRootDisk, folderPathList,
    } = this.props;
    
    // 是否有编辑权限
    const hasManagementAuthority = currentRootDisk.uploadPower;
    //  是否有文件被选择了
    const hasSelectedFile = !!selectedFileIds.length;
    const _folderPathList = this.handleFormatFilePath(folderPathList);
    const currentFolder = _folderPathList[_folderPathList.length - 1];

    return (
      <div className="operate-area">
        
        <div className={`operate-area__opt ${hasManagementAuthority ? 'visible' : 'hidden'}`}>
          <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)}
          />
          <Tooltip title="支持文件类型：ppt、word、excel、pdf、jpg、mp3、mp4">
            <Button
              type={!showResultPage?"primary":""}
              disabled={showResultPage}
              onClick={this.handleChooseFile}
            >
              <span className="icon iconfont">&#xe7a0;</span>
              上传文件
            </Button>
          </Tooltip>

          <Button
            onClick={this.handleToggleCreateFolderModal}
            disabled={showResultPage}
          >
            <span className="icon iconfont">&#xe7a2;</span>
            新建文件夹
          </Button>

          { hasSelectedFile && <Button onClick={this.handleShowSelectFileModal}>移动</Button> }
          { hasSelectedFile && <Button onClick={this.handleDeleteFile}>删除</Button> }
        </div>

        <div className="operate-area__search">
           <SearchBar
            placeholder='搜索文件/文件夹'
            value={searchKey}
            onSearch={this.props.onSearch}
            style={{width: '245px'}}
          />
        </div>

        <div className="operate-area__bottom">
          <div className="bread-crumbs">
            {
              _folderPathList.map((folderPath, index) => {
                return (
                  <div
                    title={folderPath.folderName}
                    className="file-path"
                    key={`file-path${index}`}
                    onClick={() => this.handleChangeCurrentFolder(folderPath, index)}
                  >{getEllipsText(folderPath.folderName, 10)}</div>
                )
              })
            }
          </div>
        </div>

        <CreateFolderModal
          isOpen={showCreateFolderModal}
          onClose={this.handleToggleCreateFolderModal}
          onOk={this.handleCreateFolderDone}
        />

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

        <SelectPrepareFileModal
          isOpen={showSelectFileModal}
          currentRootDisk={currentRootDisk}
          onClose={() => {
            this.setState({ showSelectFileModal: false });
          }}
          onMove={(targetFolder) => {
            this.setState({ showSelectFileModal: false });
            this.props.onMove(targetFolder);
          }}
        />

        <NonCompliantFileModal
          isOpen={showNonCompliantFileModal}
          fileList={nonCompliantFileList}
          onClose={() => {
            this.setState({ showNonCompliantFileModal: false });
          }}
          onOk={() => {
            this.setState({ showNonCompliantFileModal: false  });
            this.handleShowUploadModal(this.state.fileList)
          }}
        />
        { this.state.chargeModal }
      </div>
    )
  }
}

export default OperateArea;