/*
 * @Author: yuananting
 * @Date: 2021-02-25 11:23:47
 * @LastEditors: yuananting
 * @LastEditTime: 2021-06-03 17:12:01
 * @Description: 助学工具-题库-题目列表数据
 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
 */
import React, { Component } from "react";
import {
  Table,
  ConfigProvider,
  Empty,
  Row,
  Input,
  Select,
  Tooltip,
  Space,
  Button,
  Modal,
  message,
  Menu,
  Dropdown,
  DatePicker,
} from "antd";
import _ from "underscore";
import { Route, withRouter } from "react-router-dom";
import { DownOutlined } from '@ant-design/icons';
import { PageControl, XMTable } from '@/components';
import User from '@/common/js/user';
import AidToolService from '@/domains/aid-tool-domain/AidToolService';
import PreviewQuestionModal from '../modal/PreviewQuestionModal';
import BatchImportQuestionModal from '../modal/BatchImportQuestionModal';
import OperateQuestion from '../OperateQuestion';
import Bus from '@/core/bus';
import moment from 'moment';
import Service from '@/common/js/service';
import MoveModal from '../../modal/MoveModal';
import "./QuestionList.less";

const { RangePicker } = DatePicker;
const { Search } = Input;

const questionTypeEnum = {
  SINGLE_CHOICE: '单选题',
  MULTI_CHOICE: '多选题',
  JUDGE: '判断题',
  GAP_FILLING: '填空题',
  INDEFINITE_CHOICE: '不定项选择题',
};

const questionTypeList = [
  {
    label: '单选题',
    value: 'SINGLE_CHOICE',
  },
  {
    label: '多选题',
    value: 'MULTI_CHOICE',
  },
  {
    label: '判断题',
    value: 'JUDGE',
  },
  {
    label: '填空题',
    value: 'GAP_FILLING',
  },
  {
    label: '不定项选择题',
    value: 'INDEFINITE_CHOICE',
  },
];

class QuestionList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      query: {
        current: 1,
        size: 10,
        order: 'UPDATED_DESC', // 排序规则[ ACCURACY_DESC, ACCURACY_ASC, CREATED_DESC, CREATED_ASC, UPDATED_DESC, UPDATED_ASC ]
        categoryId: null, // 当前题库分类Id
        questionName: null, // 题目名称
        questionType: null, // 题目类型
        source: 0,
        tenantId: User.getStoreId(),
        userId: User.getStoreUserId(),
      },
      dataSource: [], // 题库列表
      previewQuestionModal: null, // 题目预览模态框
      batchImportQuestionModal: null, // 批量导入模态框
      selectedRowKeys: [],
    };
  }
  componentDidMount() {
    this.queryQuestionPageList();
    this.queryCategoryTree();
    Bus.bind('queryQuestionPageList', (selectedCategoryId) => {
      selectedCategoryId = selectedCategoryId === 'null' ? null : selectedCategoryId;
      this.clearSelect();
      this.InitSearch(selectedCategoryId);
    });
  }

  componentWillUnmount() {
    Bus.unbind('queryQuestionPageList', this.queryQuestionPageList);
  }

  // 查询分类树
  queryCategoryTree = () => {
    let query = {
      bizType: 'QUESTION',
      count: true,
      source: 0,
      userId: User.getStoreUserId(),
      tenantId: User.getStoreId(),
    };
    AidToolService.queryCategoryTree(query).then((res) => {
      const { categoryList = [] } = res.result;
      let list = this.renderTreeNodes(categoryList);
      this.setState({ questionData: list });
    });
  };

  renderTreeNodes = (data) => {
    let newTreeData = data.map((item) => {
      item.title = item.categoryName;
      item.value = item.id;
      item.key = item.id;
      if (item.sonCategoryList) {
        item.children = this.renderTreeNodes(item.sonCategoryList);
      }
      return item;
    });
    return newTreeData;
  };

  // 初始化列表查询
  InitSearch = (categoryId) => {
    const _query = {
      ...this.state.query,
      categoryId,
      current: 1,
      order: 'UPDATED_DESC', // 排序规则
      questionName: null, // 题目名称
      questionType: null, // 题目类型
    };
    this.setState({ query: _query }, () => {
      this.queryQuestionPageList();
    });
  };

  // 改变搜索条件
  handleChangeQuery = (searchType, value) => {
    this.setState(
      {
        query: {
          ...this.state.query,
          [searchType]: value || null,
          current: 1,
        },
      },
      () => {
        if (searchType === 'questionName') return;
        this.queryQuestionPageList();
      }
    );
  };

  // 重置搜索条件
  handleReset = () => {
    const _query = {
      ...this.state.query,
      current: 1,
      order: 'UPDATED_DESC', // 排序规则
      questionName: null, // 题目名称
      questionType: null, // 题目类型
      updateDateStart: null,
      updateDateEnd: null,
    };
    this.setState({ query: _query }, () => {
      this.queryQuestionPageList();
    });
  };

  // 题库列表查询
  queryQuestionPageList = () => {
    AidToolService.queryQuestionPageList(this.state.query).then((res) => {
      const { records = [], total = 0 } = res.result;
      this.setState({ dataSource: records, total });
    });
  };

  // 排序
  handleChangeTable = (pagination, filters, sorter) => {
    const { columnKey, order } = sorter;
    let sort = null;
    if (columnKey === 'accuracy' && order === 'ascend') {
      sort = 'ACCURACY_ASC';
    }
    if (columnKey === 'accuracy' && order === 'descend') {
      sort = 'ACCURACY_DESC';
    }
    if (columnKey === 'updateTime' && order === 'ascend') {
      sort = 'UPDATED_ASC';
    }
    if (columnKey === 'updateTime' && order === 'descend') {
      sort = 'UPDATED_DESC';
    }
    const _query = this.state.query;
    _query.order = sort || 'UPDATED_DESC';
    this.setState({ query: _query }, () => this.queryQuestionPageList());
  };

  // 表头设置
  parseColumns = () => {
    // 权限判断
    const isPermiss = ['CloudManager', 'StoreManager'].includes(User.getUserRole());
    const columns = [
      {
        title: '题型',
        key: 'questionTypeEnum',
        dataIndex: 'questionTypeEnum',
        width: '16%',
        render: (val) => {
          return questionTypeEnum[val];
        },
      },
      {
        title: '题目',
        key: 'questionStem',
        dataIndex: 'questionStem',
        ellipsis: {
          showTitle: false,
        },
        render: (val) => {
          var handleVal = val;
          handleVal = handleVal.replace(/<(?!img|input).*?>/g, '');
          handleVal = handleVal.replace(/<\s?input[^>]*>/gi, '_、');
          handleVal = handleVal.replace(/\&nbsp\;/gi, ' ');
          handleVal = handleVal.replace(/style\s*?=\s*?([‘"])[\s\S]*?\1/gi, '');
          return (
            <Tooltip
              overlayClassName='aid-tool-list'
              title={
                <div
                  style={{ maxWidth: 700, width: 'auto' }}
                  dangerouslySetInnerHTML={{
                    __html: handleVal,
                  }}
                />
              }
              placement='topLeft'
              overlayStyle={{ maxWidth: 700 }}>
              <div
                className='one-line-text'
                dangerouslySetInnerHTML={{
                  __html: handleVal,
                }}
              />
            </Tooltip>
          );
        },
      },
      {
        title: '正确率',
        key: 'accuracy',
        dataIndex: 'accuracy',
        sorter: true,
        showSorterTooltip: false,
        width: '14%',
        render: (val) => {
          return parseInt(val * 100) + '%';
        },
      },
      {
        title: '更新时间',
        key: 'updateTime',
        dataIndex: 'updateTime',
        sorter: true,
        showSorterTooltip: false,
        width: '24%',
        render: (val) => {
          return formatDate('YYYY-MM-DD H:i:s', val);
        },
      },
      {
        title: '操作',
        key: 'operate',
        dataIndex: 'operate',
        width: '24%',
        render: (val, record) => {
          return (
            <div className='record-operate'>
              <div className='record-operate__item' onClick={() => this.previewQuestion(record.id)}>
                预览
              </div>
              {isPermiss && <span className='record-operate__item split'> | </span>}
              {isPermiss && (
                <div className='record-operate__item' onClick={() => this.editQuestion(record.id, record.questionTypeEnum)}>
                  编辑
                </div>
              )}
              {isPermiss && <span className='record-operate__item split'> | </span>}
              {isPermiss && (
                <div className='record-operate__item' onClick={() => this.delQuestionConfirm(record)}>
                  删除
                </div>
              )}
            </div>
          );
        },
      },
    ];
    return columns;
  };

  // 设置表格每页展示条数
  onShowSizeChange = (current, size) => {
    if (current == size) {
      return;
    }
    let _query = this.state.query;
    _query.size = size;
    this.setState({ query: _query }, () => this.queryQuestionPageList());
  };

  // 预览题目
  previewQuestion = (id) => {
    const m = (
      <PreviewQuestionModal
        id={id}
        close={() => {
          this.setState({
            previewQuestionModal: null,
          });
        }}
      />
    );
    this.setState({ previewQuestionModal: m });
  };

  // 编辑题目
  editQuestion = (id, type) => {
    const { categoryId } = this.state.query;
    const { match } = this.props;
    window.RCHistory.push({
      pathname: `${match.url}/question-operate-page?id=${id}&type=${type}&categoryId=${categoryId}`,
    });
  };

  // 删除题目确认弹窗
  delQuestionConfirm(record) {
    return Modal.confirm({
      title: '提示',
      content: '确定要删除此题目吗？',
      icon: <span className='icon iconfont default-confirm-icon'>&#xe839; </span>,
      okText: '删除',
      cancelText: '取消',
      onOk: () => {
        this.deleteQuestion(record);
      },
    });
  }

  // 删除题目
  deleteQuestion = (record) => {
    let params = {
      id: record.id,
      source: 0,
      tenantId: User.getStoreId(),
      userId: User.getStoreUserId(),
    };
    AidToolService.deleteQuestion(params).then((res) => {
      if (res.success) {
        message.success('删除成功');
        const { query, total, selectedRowKeys } = this.state;
        const { size, current } = query;
        const _query = query;
        let data = {};
        if (total / size < current) {
          if (total % size === 1) {
            _query.current = 1;
          }
        }
        data.query = _query;
        if (selectedRowKeys.includes(record.id)) {
          data.selectedRowKeys = _.reject(selectedRowKeys, (item) => item === record.id);
        }
        this.setState(data, () => {
          this.queryQuestionPageList();
          Bus.trigger('queryCategoryTree', 'remain');
        });
      }
    });
  };

  // 创建题目-跳转新建页
  handleCreateQuestion = () => {
    const { match } = this.props;
    window.RCHistory.push({
      pathname: `${match.url}/question-operate-page?categoryId=${this.state.query.categoryId}`,
    });
  };

  // 批量导入弹窗
  batchImportQuestion = () => {
    const { categoryId } = this.state.query;
    const m = (
      <BatchImportQuestionModal
        close={() => {
          this.setState({ batchImportQuestionModal: null }, () => {
            this.queryQuestionPageList();
            Bus.trigger('queryCategoryTree', 'remain');
          });
        }}
        categoryId={categoryId}
      />
    );
    this.setState({ batchImportQuestionModal: m });
  };

  onSelectChange = (selectedRowKeys) => {
    if (selectedRowKeys.length > 50) {
      const extraLength = selectedRowKeys.length - 50;
      selectedRowKeys.splice(selectedRowKeys.length - extraLength, extraLength);
      message.warning('最多只能选择50个题目');
    }
    this.setState({ selectedRowKeys });
  };

  /**
   * 设置【更多操作】选项
   */
  setMoreOperationOption() {
    return (
      <Menu>
        <Menu.Item key='2'>
          <div
            key='import'
            onClick={() => {
              this.batchMove();
            }}>
            批量移动
          </div>
        </Menu.Item>
        <Menu.Item key='1'>
          <div
            key='import'
            onClick={() => {
              this.batchDelete();
            }}>
            批量删除
          </div>
        </Menu.Item>
      </Menu>
    );
  }

  batchMove = () => {
    const { selectedRowKeys } = this.state;
    if (_.isEmpty(selectedRowKeys)) {
      message.warning('请先选择要移动的题目');
      return null;
    }
    this.setState({ openMoveModal: true });
  };

  batchMoveRemote = (categoryId) => {
    const { selectedRowKeys, query } = this.state;
    const data = {
      categoryId,
      id: selectedRowKeys,
      source: 0,
      tenantId: User.getStoreId(),
      userId: User.getUserId(),
    };
    Service.Hades('public/hades/batchMoveQuestion', data, { reject: true })
      .then((res) => {
        if (res.success) {
          message.success('移动成功');
          Bus.trigger('queryCategoryTree', 'remain');
          this.clearSelect();
          this.setState(
            {
              query: {
                ...query,
                current: 1,
              },
            },
            () => {
              this.queryQuestionPageList();
            }
          );
        } else {
          message.error('移动失败');
        }
      })
      .catch(() => {
        message.error('移动失败');
      });
  };

  batchDelete = () => {
    const { selectedRowKeys, query } = this.state;
    if (_.isEmpty(selectedRowKeys)) {
      message.warning('请先选择要删除的题目');
      return null;
    }
    Modal.confirm({
      title: '确定要删除题目吗？',
      content: '删除后，不可恢复。',
      icon: <span className='icon iconfont default-confirm-icon'>&#xe839; </span>,
      okText: '删除',
      cancelText: '取消',
      onOk: () => {
        const data = {
          id: selectedRowKeys,
          source: 0,
          tenantId: User.getStoreId(),
          userId: User.getUserId(),
        };
        Service.Hades('public/hades/batchDeleteQuestion', data, { reject: true })
          .then((res) => {
            if (res.success) {
              message.success('删除成功');
              Bus.trigger('queryCategoryTree', 'remain');
              this.clearSelect();
              this.setState(
                {
                  query: {
                    ...query,
                    current: 1,
                  },
                },
                () => {
                  this.queryQuestionPageList();
                }
              );
            } else {
              message.error('删除失败');
            }
          })
          .catch(() => {
            message.error('删除失败');
          });
      },
    });
  };

  clearSelect = () => {
    this.setState({ selectedRowKeys: [] });
  };

  render() {
    const { dataSource = [], total, query, previewQuestionModal, batchImportQuestionModal, selectedRowKeys, openMoveModal, questionData } = this.state;
    const { current, size, categoryId, questionName, questionType } = query;
    const { match } = this.props;
    const rowSelection = {
      selectedRowKeys,
      preserveSelectedRowKeys: true,
      onChange: this.onSelectChange,
    };
    return (
      <div className='question-list'>
        <div className='question-list-filter'>
          <Row type='flex' justify='space-between' align='top'>
            <div className='search-condition'>
              <div className='search-condition__item'>
                <span className='search-label'>题目：</span>
                <Search
                  placeholder='搜索题目名称'
                  value={questionName}
                  style={{ width: '100%' }}
                  onChange={(e) => {
                    this.handleChangeQuery('questionName', e.target.value);
                  }}
                  onSearch={() => {
                    this.queryQuestionPageList();
                  }}
                  enterButton={<span className='icon iconfont'>&#xe832;</span>}
                />
              </div>

              <div className='search-condition__item'>
                <span className='search-label'>题型：</span>
                <Select
                  placeholder='请选择题目类型'
                  value={questionType}
                  style={{ width: '100%' }}
                  showSearch
                  allowClear
                  filterOption={(inputVal, option) => option.props.children.includes(inputVal)}
                  onChange={(value) => {
                    if (_.isEmpty(value)) {
                      this.handleChangeQuery('questionType', value);
                    }
                  }}
                  onSelect={(value) => {
                    this.handleChangeQuery('questionType', value);
                  }}>
                  {_.map(questionTypeList, (item, index) => {
                    return (
                      <Select.Option value={item.value} key={item.value}>
                        {item.label}
                      </Select.Option>
                    );
                  })}
                </Select>
              </div>
              <div className='search-condition__item'>
                <span className='search-label'>更新时间：</span>
                <RangePicker
                  value={query.updateDateStart ? [moment(query.updateDateStart), moment(query.updateDateEnd)] : null}
                  style={{ width: '100%' }}
                  format={'YYYY-MM-DD'}
                  onChange={(dates) => {
                    const _query = _.clone(query);
                    _query.updateDateStart = dates ? dates[0].startOf('day').valueOf() : null;
                    _query.updateDateEnd = dates ? dates[1].endOf('day').valueOf() : null;
                    _query.current = 0;
                    this.setState({ query: _query }, () => this.queryQuestionPageList());
                  }}
                />
              </div>
            </div>

            <div className='reset-fold-area'>
              <Tooltip title='清空筛选'>
                <span className='resetBtn iconfont icon' onClick={this.handleReset}>
                  &#xe61b;{' '}
                </span>
              </Tooltip>
            </div>
          </Row>
        </div>
        {['CloudManager', 'StoreManager'].includes(User.getUserRole()) && (
          <Space size={8}>
            {_.isEmpty(selectedRowKeys) ? (
              !!categoryId && [
                <Button key='1' type='primary' onClick={this.handleCreateQuestion}>
                  新建题目
                </Button>,
                <Button key='2' onClick={this.batchImportQuestion}>
                  批量导入
                </Button>,
              ]
            ) : (
              <div className='select-container'>
                <span className='con'>
                  <div>
                    <span className='icon iconfont tip'>&#xe6f2;</span>
                    <span className='text'>已选择{selectedRowKeys.length}项</span>
                  </div>
                  <div>
                    <span className='clear' onClick={this.clearSelect}>
                      清空
                    </span>
                  </div>
                </span>
              </div>
            )}
            {!!categoryId ? (
              <Dropdown overlay={this.setMoreOperationOption()}>
                <Button id='more_operate'>
                  更多操作
                  <DownOutlined />
                </Button>
              </Dropdown>
            ) : (
              <Space size={8}>
                <Button onClick={() => this.batchMove()}>批量移动</Button>
                <Button onClick={() => this.batchDelete()}>批量删除</Button>
              </Space>
            )}
          </Space>
        )}
        <div className='question-list-content'>
          <XMTable
            rowKey={(record) => record.id}
            dataSource={dataSource}
            columns={this.parseColumns()}
            pagination={false}
            bordered
            onChange={this.handleChangeTable}
            rowSelection={rowSelection}
            renderEmpty={{
              description: <span style={{ display: 'block', paddingBottom: 24 }}><span>还没有题目</span>
                {["CloudManager", "StoreManager"].includes(User.getUserRole()) &&
                  categoryId && (
                    <span>
                      ，快去
                      <span
                        className='empty-list-tip'
                        onClick={() => {
                          this.handleCreateQuestion();
                        }}>
                        新建一个
                      </span>
                      吧！
                    </span>
                  )}
                </span>
            }}
          />
          {total > 0 && (
            <div className='box-footer'>
              <PageControl
                current={current - 1}
                pageSize={size}
                total={total}
                toPage={(page) => {
                  const _query = { ...query, current: page + 1 };
                  this.setState({ query: _query }, () => this.queryQuestionPageList());
                }}
                showSizeChanger={true}
                onShowSizeChange={this.onShowSizeChange}
              />
            </div>
          )}
          {previewQuestionModal}
          {batchImportQuestionModal}
          {openMoveModal && (
            <MoveModal
              visible={openMoveModal}
              title='题目'
              data={questionData}
              categoryId={query.categoryId}
              length={selectedRowKeys.length}
              onCancel={() => this.setState({ openMoveModal: false })}
              onOk={(categoryId) => {
                this.batchMoveRemote(categoryId);
                this.setState({ openMoveModal: false });
              }}
            />
          )}
        </div>
        <Route path={`${match.url}/question-operate-page`} component={OperateQuestion} />
      </div>
    );
  }
}

export default withRouter(QuestionList);
