/*
 * @Author: 吴文洁 
 * @Date: 2020-06-10 13:54:01 
 * @Last Modified by: 吴文洁
 * @Last Modified time: 2020-07-23 09:33:21
 * @Description：选择备课文件弹窗 
 */

import React from 'react';
import { Modal, Button, Radio, Checkbox, Spin, Upload, message, Tooltip } from 'antd';
import InfiniteScroll from 'react-infinite-scroller';

import User from '@/common/js/user';
import { getEllipsText } from "@/core/util";
import DefaultIcon from '@/modules/common/DefaultIcon';
import UploadProgressModal from './UploadProgressModal';
import NonCompliantFileModal from './NonCompliantFileModal';
import Service from '@/common/js/service';
import _ from 'underscore';
import {
  DEFAULT_SIZE_UNIT, FileTypeIcon, NonCompliantFileMap,
  DISK_LIST, SupportFileType, LocalFileType,FileVerifyMap
} from "@/common/constants/academic/lessonEnum";

import { getFileTypeByName } from '../components/FolderManage';

import './SelectPrepareFileModal.less';

const defaultQuery = {
  size: 10,
  current: 1,
  folderIdType: 'FOLDER'
}

const defaultRootDisk = {
  folderName: '公共文件',
  disk: 'COMMON',
  uploadPower: false
}

const FOLDERLIST_URL_MAP = {
  'MYSELF': 'public/hadesStore/folderList',
  'COMMON': 'public/hadesStore/folderList',
  'EMPLOYEE': 'public/hadesStore/folderList'
};

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

// 合法的文件名后缀
const FILE_SUFFIX_LIST = ['docx', 'doc', 'ppt', 'pptx', 'pdf', 'xlsx', 'xls', 'jpg', 'jpeg', 'png', 'mp3', 'mp4'];
// 禁止选择的文件类型
const DISABLE_FILE_FORMAT = ['text/csv', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];

// 最多可以选择20个文件
const MAX_SELECT_LENGTH = 20;

let count = 0;

class SelectPrepareFileModal extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      targetFolder: {},           // 当前选中的目录
      currentRootDisk: {},        // 当前所在根目录
      uploadFolderPath: {},       // 上传文件的目录，防止中途切换文件夹
      currentFile: null,          // 单选模式下, 当前选择的文件
      currentFileIndex: 0,        // 单选模式下, 当前选择的文件的索引
      folderList: [],             // 文件列表
      folderPathList: [],         // 文件路径列表
      selectedFileList: [],       // 已勾选的文件
      nonCompliantFileList: [],   // 超出限制的文件列表
      query: defaultQuery,        // 初始请求参数
      showUploadModal: false,     // 上传进度弹窗
      showNonCompliantFileModal: false,
    }
  }
  componentDidMount() {
    const { diskList = [],  currentRootDisk} = this.props;
    const _currentRootDisk = diskList[0] || currentRootDisk || defaultRootDisk;
    this.setState({
      query: defaultQuery,
      currentRootDisk: _currentRootDisk,
      folderPathList: [_currentRootDisk],
    }, () => {
      this.handleFetchFolderList();
    });
  }
  componentWillReceiveProps(nextProps) {
    const { diskList = [],  currentRootDisk} = nextProps;
    if (nextProps.isOpen) {
      const _currentRootDisk = diskList[0] || currentRootDisk || defaultRootDisk;
      this.setState({
        query: defaultQuery,
        currentRootDisk: _currentRootDisk,
        folderPathList: [_currentRootDisk],
      }, () => {
        this.handleFetchFolderList();
      });
    }
  }

  // 获取文件列表
  handleFetchFolderList = (params = {}, loadMore = false) => {
    // 根据当前根节点获取文件列表
    const { selectTypeList } = this.props;
    const { query, folderList, currentRootDisk } = this.state;
    const _params = {
      ...query,
      ...params,
      disk: params.disk || currentRootDisk.disk,
      storeId:User.getStoreId(),
      createId:User.getUserId()
    }

    if (selectTypeList) {
      _params.folderFileType = selectTypeList
    }

    Service.Hades(FOLDERLIST_URL_MAP[currentRootDisk.disk], _params).then((res) => {
      const { result = {} } = res;
      const { records = [], total = 0 } = result;
      this.setState({
        folderList: loadMore ? [...folderList, ...records] : records,
        totalCount: Number(total)
      });
    });
  }

  // 修改目录
  handleChangeFolder = (folder) => {
    this.setState({
      query: defaultQuery,
      folderPathList: [folder],
      currentRootDisk: folder,
      selectedFileList: [],          // 切换目录不保存之前已勾选的记录
    }, () => {
      this.handleFetchFolderList({ disk: folder.disk });
    });
  }

  // 选择文件/文件夹
  handleSelect = (folder, index) => {
    // 如果是文件，直接return, 否则进入下一级
    const { operateType = 'select', scene, selectedFileList = [] } = this.props;
    const { folderType, folderName, folderFormat } = folder;
    if (folderType === 'FOLDER') {
      this.handleSelectFolder(folder);
    }

    const suffix = _.last(folderName.split('.')).toLowerCase();

    {/* TODO：麦麦打卡类目申请下来后解开视频入口 */}
    const hiddenVideo = this.props.hiddenVideo && ['mp4','MP4'].includes(suffix);

    // 文件是否已经被关联了
    const hasRelation = _.find(selectedFileList, (item) => item.resourceId === folder.resourceId);
    // 文件禁止点击的情况（移动、直播场景下文件为Excel、文件已经被关联了、文件后缀不合法)
    const disabled = hiddenVideo || operateType === 'move' ||
        (scene === 'liveCourse' && folderFormat === 'EXCEL') ||
        !!hasRelation || !FILE_SUFFIX_LIST.includes(suffix);

    if (folderType === 'FILE' && !disabled) {
      this.handleSelectFile(folder, index);
    }
  }

  // 选择文件夹
  handleSelectFolder = (folder) => {
    const { folderList, folderPathList, currentRootDisk } = this.state;

    // 更新文件路径
    folderPathList.push({
      id: folder.id,
      folderName: folder.folderName
    });

    this.setState({
      query: {
        ...this.state.query,
        current: 1
      },
      folderPathList,
      targetFolder: folder
    }, ()  => {
      // 判断是否是员工文件的根目录
      const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 2;
      // 根据父级目录id获取文件夹列表
      this.handleFetchFolderList({
        parentId: folder.id,
        folderIdType: employeeDisk ? 'USER' : 'FOLDER'
      });
    });
  }

  // 选择文件
  handleSelectFile = (file, index) => {
    const { multiple } = this.props;

    if (multiple) {
       const { selectedFileList } = this.state;
      const index = _.findIndex(selectedFileList, (item) => item.resourceId === file.resourceId);
      // 如果文件没有被勾选，则勾选
      if (index < 0) {
        selectedFileList.push(file);
      } else { // 如果文件已经被勾选了，则取消勾选
        selectedFileList.splice(index, 1);
      }
      this.setState({ selectedFileList });
    } else {
      this.setState({
        currentFile: file,
        currentFileIndex: index
      });
    }
  }

  handleSelectFileDone = () => {
    const { selectedFileList, currentFile } = this.state;
    const {
      multiple,
      selectedFileList: prevSelectedFileList = [],
      maxSelectLength
    } = this.props;

    if (multiple) {
      const currSelectedFileList = [...(prevSelectedFileList || []), ...selectedFileList];
      // 最多选择20个文件，判断是否超出了20个
      if (currSelectedFileList.length >(maxSelectLength?maxSelectLength: MAX_SELECT_LENGTH)) {
        // 最多还可选择的个数 = 总量（20） - 已经选择的个数（prevSelectedFileList）
        message.warning(`最多可选择${maxSelectLength?(maxSelectLength- prevSelectedFileList.length):(MAX_SELECT_LENGTH - prevSelectedFileList.length)}个文件`);
        return;
      }

      const addFolderIds = _.pluck(selectedFileList, 'id');

      this.props.onSelect(addFolderIds, selectedFileList);
      // 上传完成之后将selectedFileList置为空,上传进度弹窗也一起消失
      this.setState({
        selectedFileList: [],
        showUploadModal: false,
      })
    } else {
      this.props.onSelect(currentFile);
      this.setState({
        currentFile: null,
        showUploadModal: false,
      });
    }
  }

  // 前往特定的文件夹
  handleChangeCurrentFolder = (folder, index) => {
    // 请求接口，获取当前folder下所有的文件
    const { folderPathList, currentRootDisk } = this.state;
    if (folderPathList.length === 1) return;

    folderPathList.splice(index+1, folderPathList.length);
    const targetFolder = folderPathList[folderPathList.length - 1];
    const { id = null } = targetFolder;

    // 判断是否是员工文件的根目录
    const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 2;

    this.setState({
      targetFolder,
      folderPathList
    }, () => {
      this.handleFetchFolderList({
        parentId: id,
        disk: currentRootDisk.disk,
        folderIdType: employeeDisk ? 'USER' : 'FOLDER'
      })
    });
  }

  // 移动到此目录
  handleMoveToTargetFolder = () => {
    const { targetFolder } = this.state;
    // 请求接口，完成之后刷新文件列表
    this.props.onMove(targetFolder);
  }

  // 滑动加载更多
  handleScrollEvent = () => {
    const { folderList, totalCount, currentRootDisk, folderPathList } = this.state;
    const hasMore = folderList.length < totalCount;

    const { fileListRef } = this.refs;
    const hasReachBottom = fileListRef.scrollTop + fileListRef.clientHeight === fileListRef.scrollHeight;
    if (!hasReachBottom || !hasMore) return;
    
    const currentFolder = folderPathList[folderPathList.length - 1];
    // 判断是否是员工文件的根目录
    const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 2;
    const query = _.clone(this.state.query);
    
    query.current = query.current + 1;
    this.setState({ query }, () => {
      this.handleFetchFolderList({
        disk: currentRootDisk.disk,
        folderIdType: employeeDisk ? 'USER' : 'FOLDER',
        parentId: currentFolder.id
      }, true);
    })
  }

  // 取消选择
  handleClose = () => {
    this.setState({
      query: defaultQuery,
      selectedFileList: []
    }, () => {
      this.props.onClose();
    })
  }

  handleChooseFile = async () => {
    const dom = document.querySelector('#detailFileInput');
    dom.click();
  }

  // 上传文件
  handleUpload = (event) => {

    const { selectType } = this.props;
    const fileList = event.target.files;
    // 判断文件的大小是否超出了限制
    const nonCompliantFileList = [];
    const _fileList = [...fileList];
    _fileList.map((file, index) => {
      console.log('file',file);
      let { size, type, name } = file;
      if (!type) {
        type = getFileTypeByName(name);
      }
      if (supportFileType.indexOf(type) > -1 && size > FileVerifyMap[type].maxSize * DEFAULT_SIZE_UNIT) {
        nonCompliantFileList.push(file);
        _fileList.splice(index, 1);
      }
      file.key = count++;
    });
    console.log("nonCompliantFileList",nonCompliantFileList);
    // 不符合规则的文件列表
    if (nonCompliantFileList.length > 0) {

      const { confirm } = this.props;
      if (confirm) {
        Modal.info({
          ...confirm,
          icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>
        });
        return;
      }
      this.setState({
        fileList: _fileList,
        nonCompliantFileList,
        showNonCompliantFileModal: true,
      })
    } else {
      this.handleShowUploadModal(_fileList);
    }

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

  // 显示上传进度弹窗
  handleShowUploadModal = async (fileList) => {
    if (fileList.length) {
      const { folderPathList } = this.state;
      this.setState({
        showUploadModal: true,
        localFileList: fileList,
        uploadFolderPath: folderPathList[folderPathList.length - 1]
      });
    }
  }

  handleUploadDone = (file, resourceId) => {
    const { folderList, folderPathList, currentRootDisk, uploadFolderPath } = this.state;
    const { scene } = this.props;
    const currentFolder = folderPathList[folderPathList.length - 1];
    const { id = null } = uploadFolderPath || currentFolder;
    let { size, type, name } = file;

    if (!type) {
      type = getFileTypeByName(name)
    }
    const params = {
      name,
      resourceId,
      folderSize: size,
      folderFormat: type,
      folderTypeEnum: resourceId ? 'FILE' : 'FOLDER',
      disk: currentRootDisk.disk,
      createUser:"STORE_USER",
      parentId: id,
      storeId:User.getStoreId(),
      createId:User.getUserId()
    }
    Service.Hades('public/hadesStore/saveFolder', params).then((res) => {
      const { query, selectedFileList, currentRootDisk } = this.state;
      const _query = _.clone(query);
      {/* TODO：麦麦打卡类目申请下来后解开视频入口 */}
      const suffix = _.last(name.split('.')).toLowerCase();
      const hiddenVideo = this.props.hiddenVideo && ['mp4','MP4'].includes(suffix);
      const _selectedFileList = hiddenVideo ? [...selectedFileList] : [...selectedFileList, res.result];
      _query.current = 1;
      console.log("currentFile", res.result);
      this.setState({
        query: _query,
        selectedFileList: scene === 'liveCourse' ?
          _selectedFileList.filter(item => { return !DISABLE_FILE_FORMAT.includes(item.folderFormat)}) :
          _selectedFileList,
        currentFile:res.result
      }, () => {
      if (resourceId && !_.isEqual(uploadFolderPath, currentFolder)) return;
        // 上传之后根目录不变
        this.handleFetchFolderList({ parentId: id, disk: currentRootDisk.disk });
      });
    });
  }

  // 取消上传
  handleHiddenUploadModal = () => {
    this.setState({
      showUploadModal: false,
      localFileList: []
    });
  }
  renderFooter = () => {
    const { selectedFileList, currentRootDisk } = this.state;
    const {
      operateType,
      selectType,
      multiple,
      accept = ".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls",
      tooltip = '支持文件类型：ppt、word、excel、pdf、jpg、jpeg、png、mp3、mp4'
    } = this.props;

    const selectedFileLength = selectedFileList.length;
    const hasSelect = !!selectedFileLength;
    
    // 是否有上传权限
    return [
      <input
        multiple={multiple}
        type="file"
        style={{ display: 'none' }}
        id="detailFileInput"
        accept={accept}
        onChange={(e) => this.handleUpload(e)}
        maskClosable={false}
      />,
      <div
        key="footerLeft"
        className="footer__left"
        className={`prepare-lesson-upload ${operateType === 'select'? 'visible' : 'hidden'}`}
      >
        <Tooltip title={tooltip}>
          <span
            className="footer__left"
            onClick={this.handleChooseFile}
          >上传文件</span>
        </Tooltip>
      </div>,
      <div className="footer__right" key="footerRight">
        <Button
          onClick={() => {
            this.setState({
              showUploadModal: false,
              selectedFileList: []
            });
            this.props.onClose();
          }}
        >取消</Button>
        {
          operateType === 'select' ?
          <Button
            key="cancel"
            type="primary"
            disabled={!hasSelect && multiple}
            onClick={this.handleSelectFileDone}
          >{`确定${hasSelect && multiple ? `(${selectedFileLength})` : ''}`}</Button> :
          <Button
            type="primary"
            onClick={this.handleMoveToTargetFolder}
          >移动到此目录</Button>
        }
      </div>
    ]
  }

  render() {
    const {
      folderPathList, folderList, selectedFileList,
      currentRootDisk, showUploadModal, localFileList,
      showNonCompliantFileModal, nonCompliantFileList,
      currentFile, currentFileIndex
    } = this.state;
    const {
      scene,
      isOpen,
      multiple = false,
      diskList = [],
      operateType = 'move',
      footer = this.renderFooter(),
      selectedFileList: prevSelectedFileList = [],
    } = this.props;

    const currentFolder = folderPathList[folderPathList.length - 1];
    const title = operateType === 'move' ? '移动到' : '选择文件';
    const currSelectedFileList = [...(prevSelectedFileList || []), ...selectedFileList];

    // 判断是否是员工文件的根目录
    const employeeDisk = currentRootDisk.disk === 'EMPLOYEE' && folderPathList.length === 1;

    return (
      <Modal
        visible={isOpen}
        title={title}
        footer={footer}
        width={680}
        maskClosable={false}
        destroyOnClose={true}
        closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
        onCancel={this.handleClose}
        className="select-prepare-file-modal"
      >
        {
          // 机构可见磁盘大于1且在选择文件的情况下才显示tabs
          operateType === 'select' && diskList.length > 1 && 
          <div className="radio-buttons">
            <Radio.Group
              defaultValue={currentRootDisk.disk}
              value={currentRootDisk.disk}
            >
              {
                diskList.map((item, index) => {
                  return (
                    <Radio.Button
                      value={item.disk}
                      key={`folder-item${index}`}
                      onClick={() => this.handleChangeFolder(item)}
                    >
                      {item.folderName}
                    </Radio.Button>
                  )
                })
              }
            </Radio.Group>
          </div>
        }
       
        <div className="bread-crumbs">
          {
            folderPathList.map((folderPath, index) => {
              return (
                <div
                  className="file-path"
                  key={`file-path${index}`}
                  onClick={() => this.handleChangeCurrentFolder(folderPath, index)}
                >
                  {folderPath.folderName}
                </div>
              )
            })
          }
        </div>
        {
          !_.isEmpty(folderList) ?
           <div>
            <div className="file-list"  
              onScrollCapture={() => this.handleScrollEvent()}
              style={{ height: '320px', overflowY: 'auto' }}
              ref="fileListRef"
            >
              {
                folderList.map((folder, index) => {
                  const { folderType, folderSize, folderFormat, folderName } = folder;
                  const isFolder = folderType === 'FOLDER';

                  let _size = `${(folderSize / DEFAULT_SIZE_UNIT).toFixed(1)}M`;
                  if (folderSize < 0.1 * DEFAULT_SIZE_UNIT) {
                    _size = `${(folderSize / 1024).toFixed(1)}kb`;
                  }
                  
                  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'
                  }

                  const suffix = _.last(folderName.split('.')).toLowerCase();
                  
                    {/* TODO：麦麦打卡类目申请下来后解开视频入口 */}
                  const hiddenVideo = this.props.hiddenVideo && ['mp4','MP4'].includes(suffix);
                 
                  // 判断文件是否被选中了
                  const hasSelect = _.find(currSelectedFileList, (item) => item.resourceId === folder.resourceId);

                  // 判断文件是否已经被关联了
                  const hasRelation = _.find((prevSelectedFileList || []), (item) => item.resourceId === folder.resourceId);

                  // 文件禁止点击的情况（移动、直播场景下文件为Excel、文件已经被关联了、文件不合法)
                  const disabled = hiddenVideo || (!isFolder && operateType === 'move') || (scene === 'liveCourse' && folder.folderFormat === 'EXCEL') || !!hasRelation || (!isFolder && !FILE_SUFFIX_LIST.includes(suffix));
                  // console.log('currentFile',currentFile);
                  // console.log('folder',folder);
                  let currentFileCheck = false;
                  if(currentFile){
                    currentFileCheck = (currentFile.id===folder.id)
                  }
                  return (
                    <div
                      className={`file-item ${!disabled ? 'enable' : 'disable'}`}
                      key={`file-item${index}`}
                      onClick={() => { this.handleSelect(folder, index) }}
                    >
                      <div className="file-item__cover">
                        <img src={imgSrc} alt="file-item__img" width="24" />
                        <span>{getEllipsText(folderName, 20)}</span>
                      </div>
                      {/* 文件夹不显示大小 */}
                      { !isFolder && <div className="file-item__size">{_size}</div> }

                      {/* 当选择文件的时候，显示复选框 */}
                      {
                        !isFolder && operateType === 'select' &&
                        (
                          multiple
                          ? <Checkbox
                            checked={!!hasSelect}
                            disabled={!!hasRelation}
                          />
                          : (
                            currentFileCheck
                            ? <span className="icon iconfont correct">&#xe77d;</span>
                            : <span className="icon iconfont error">&#xe77c;</span>
                          )
                        )
                        
                      }

                      {/* 文件不显示展开的图标 */}
                      {
                        isFolder &&
                        <div className="file-item__expend-icon">
                          <span className="icon iconfont">&#xe71b;</span>
                        </div>
                      }
                    </div>
                  )
                })
              }
            </div>
          </div> :
          <DefaultIcon
            type='student'
            title={<span className="desc">这个文件夹是空的</span>}
          />
        }

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

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

        { this.state.chargeModal }
      </Modal>
    )
  }
}

export default SelectPrepareFileModal;