/*
 * @Author: yuananting
 * @Date: 2021-03-27 16:15:13
 * @LastEditors: yuananting
 * @LastEditTime: 2021-06-01 17:07:30
 * @Description: 助学工具-新建/复制/编辑试卷
 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
 */
import React, { Component } from "react";
import {
  Form,
  Button,
  Input,
  Table,
  InputNumber,
  ConfigProvider,
  Empty,
  Tooltip,
  message,
  Modal,
  Spin,
} from "antd";
import Lottie from 'react-lottie';
import { PlusOutlined } from "@ant-design/icons";
import { XMTable } from "@/components";
import ShowTips from "@/components/ShowTips";
import Breadcrumbs from "@/components/Breadcrumbs";
import "./OperatePaper.less";
import SelectQuestionModal from "./modal/SelectQuestionModal";
import PaperPreviewModal from "./modal/PreviewPaperModal";
import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import Bus from "@/core/bus";
import { Route, withRouter } from "react-router-dom";
import * as paperEmpty from '../../lottie/paperEmpty/data.json';
import AddExam from "@/modules/teach-tool/examination-manager/AddExam";

const questionTypeEnum = {
  SINGLE_CHOICE: "单选题",
  MULTI_CHOICE: "多选题",
  JUDGE: "判断题",
  GAP_FILLING: "填空题",
  INDEFINITE_CHOICE: "不定项选择题",
};
class OperatePaper extends Component {
  formRef = React.createRef();
  constructor(props) {
    super(props);
    this.state = {
      formData: {
        categoryId: getParameterByName("categoryId"), // 分类ID
        singleChoiceCnt: 0, // 单选题数量
        multiChoiceCnt: 0, // 多选题数量
        judgeCnt: 0, // 判断题数量
        gapFillingCnt: 0, // 填空题数量
        indefiniteChoiceCnt: 0, // 不定项选择题数量
        singleChoiceScore: 0, // 单选题目总分
        multiChoiceScore: 0, // 多选题目总分
        judgeScore: 0, // 判断题目总分
        gapFillingScore: 0, // 填空题目总分
        indefiniteChoiceScore: 0, //不定项选择总分
        paperName: null, // 试卷名称
        passRate: 60, // 及格线
        passScore: 0, // 及格分
        questionCnt: 0, // 题目数量
        totalScore: 0, // 总分
        questionList: [], // 题目列表
        source: 0,
        tenantId: User.getStoreId(),
        userId: User.getStoreUserId(),
      },
      selectQuestionModal: null,
      paperPreviewModal: null,
      selectQuestionList: [],
      currentOperate: "",
      currentNav: "",
      currentCategoryPapers: [],
      loading: false,
      check: false,
    };
  }

  componentDidMount() {
    this.queryCurrentCategoryPapers();
    switch (getParameterByName("type")) {
      case "new":
        this.setState({ currentOperate: "new", currentNav: "新建试卷" });
        break;
      case "edit":
        this.setState({ currentOperate: "edit", currentNav: "编辑试卷" }, () =>
          this.queryPaperDetail()
        );
        break;
      case "copy":
        this.setState({ currentOperate: "copy", currentNav: "复制试卷" }, () =>
          this.queryPaperDetail()
        );
        break;
    }
  }

  // 获取当前分类下的所有试卷
  queryCurrentCategoryPapers = () => {
    const categoryId = getParameterByName("categoryId");
    let params = {
      current: 1,
      size: 9999,
      categoryId: categoryId === "null" ? null : categoryId,
      paperName: null, // 试卷名称
      source: 0,
      tenantId: User.getStoreId(),
      userId: User.getStoreUserId(),
    };
    AidToolService.queryPaperPageList(params).then((res) => {
      const { records = [] } = res.result;
      this.setState({ currentCategoryPapers: records });
    });
  };

  // 编辑/复制试卷时获取相应试卷详情
  queryPaperDetail = async () => {
    this.setState({ loading: true });
    const { currentOperate } = this.state;
    let query = {
      paperId: getParameterByName("paperId"),
      source: 0,
      userId: User.getStoreUserId(),
      tenantId: User.getStoreId(),
    };
    const res = await AidToolService.queryPaperDetail(query);
    const { result } = res;
    const { paperName, passRate } = result;
    this.setState(
      {
        selectQuestionList: result.questionList,
        formData: {
          ...result,
          paperId: getParameterByName("paperId"),
          paperName:
            currentOperate === "copy" ? paperName + "（复制）" : paperName,
        },
        loading: false,
      },
      () => {
        this.formRef.current.setFieldsValue({
          paperName: this.state.formData.paperName,
          passRate,
        });
        this.setFormData(result.questionList);
      }
    );
  };

  setFormData = (list, sorter) => {
    const { formData } = this.state;
    const _selectQuestionList = [...list];

    // 各类型题目汇总
    const singleQuestion = _.filter(
      _selectQuestionList,
      (item) => item.questionType === "SINGLE_CHOICE"
    );
    const multiQuestion = _.filter(
      _selectQuestionList,
      (item) => item.questionType === "MULTI_CHOICE"
    );
    const judgeQuestion = _.filter(
      _selectQuestionList,
      (item) => item.questionType === "JUDGE"
    );
    const gapQuestion = _.filter(
      _selectQuestionList,
      (item) => item.questionType === "GAP_FILLING"
    );
    const indefiniteQuestion = _.filter(
      _selectQuestionList,
      (item) => item.questionType === "INDEFINITE_CHOICE"
    );

    // 各类型题目总分值
    const singleChoiceScore = singleQuestion.reduce((prev, cur) => {
      return prev + Number(cur.score) || 0;
    }, 0);
    const multiChoiceScore = multiQuestion.reduce((prev, cur) => {
      return prev + Number(cur.score) || 0;
    }, 0);
    const judgeScore = judgeQuestion.reduce((prev, cur) => {
      return prev + Number(cur.score) || 0;
    }, 0);
    const gapFillingScore = gapQuestion.reduce((prev, cur) => {
      return prev + Number(cur.score) || 0;
    }, 0);
    const indefiniteChoiceScore = indefiniteQuestion.reduce((prev, cur) => {
      return prev + Number(cur.score) || 0;
    }, 0);
    const totalScore = _selectQuestionList.reduce((prev, cur) => {
      return prev + Number(cur.score) || 0;
    }, 0);

    const sortedTableData = [
      ...singleQuestion,
      ...multiQuestion,
      ...indefiniteQuestion,
      ...judgeQuestion,
      ...gapQuestion,
    ];
    let currentQuestionList = [];

    switch (sorter) {
      case "ascend":
        currentQuestionList = sortedTableData;
        break;
      case "descend":
        currentQuestionList = sortedTableData.reverse();
        break;
      default:
        currentQuestionList = _selectQuestionList;
        break;
    }

    const passScore = Math.round(totalScore * formData.passRate * 0.01);
    this.setState({
      selectQuestionList: currentQuestionList,
      formData: {
        ...formData,
        singleChoiceCnt: singleQuestion.length,
        multiChoiceCnt: multiQuestion.length,
        judgeCnt: judgeQuestion.length,
        gapFillingCnt: gapQuestion.length,
        indefiniteChoiceCnt: indefiniteQuestion.length,
        singleChoiceScore,
        multiChoiceScore,
        judgeScore,
        gapFillingScore,
        indefiniteChoiceScore,
        passScore,
        questionCnt: _selectQuestionList.length,
        totalScore,
      },
    });
  };

  // 选择题目
  chooseQuestion = () => {
    const m = (
      <SelectQuestionModal
        getSelectedQuestion={this.state.selectQuestionList}
        setSelectedQuestion={(list) => {
          this.setState({ selectQuestionModal: null }, () => {
            this.setFormData(list);
          });
        }}
        close={() => {
          this.setState({
            selectQuestionModal: null,
          });
        }}
      />
    );
    this.setState({ selectQuestionModal: m });
  };

  // 移动已选题目
  handleMoveItem = (index, moveLength) => {
    const { selectQuestionList } = this.state;
    const item = selectQuestionList.splice(index + moveLength, 1);
    selectQuestionList.splice(index, 0, item[0]);
    this.setState({ selectQuestionList }, () =>
      this.setFormData(this.state.selectQuestionList)
    );
  };

  // 移除已选题目
  handleDelItem = (delQuestionId) => {
    const { selectQuestionList } = this.state;
    this.setState(
      {
        selectQuestionList: [...selectQuestionList].filter(
          (item) => item.questionId !== delQuestionId
        ),
      },
      () => this.setFormData(this.state.selectQuestionList)
    );
  };

  // 校验试卷名称是否存在
  checkExist = (paperName) => {
    const { currentCategoryPapers, currentOperate } = this.state;
    var result = null;
    currentCategoryPapers.forEach((item) => {
      if (result != null) {
        return result;
      }
      if (["new", "copy"].includes(currentOperate)) {
        if (item.paperName === paperName) {
          result = item;
        }
      } else if (currentOperate === "edit") {
        if (
          item.paperName === paperName &&
          item.paperId !== getParameterByName("paperId")
        ) {
          result = item;
        }
      }
    });
    return result;
  };

  validatePaperName = (paperName) => {
    if (this.state.check && !paperName) {
      return "请输入试卷名称";
    }

    if (this.checkExist(paperName)) {
      return "该试卷名称已存在";
    }

    if (paperName && paperName.length > 40) {
      return "试卷名称最多40字";
    }
  };

  // 保存试卷
  savePaper = (saveType) => {
    this.setState({ check: true });
    const { selectQuestionList, formData, currentOperate } = this.state;
    const categoryId = getParameterByName("categoryId");
    const { match } = this.props;
    let questionList = [];
    if (
      !formData.passRate ||
      !formData.paperName ||
      this.checkExist(formData.paperName) ||
      (formData.paperName && formData.paperName.length > 40)
    ) {
      return;
    }
    if (selectQuestionList.length === 0) {
      return message.warning("请选择题目");
    }

    selectQuestionList.forEach((item, index) => {
      questionList.push({
        categoryId: item.categoryId,
        portionScore: item.portionScore || 0,
        questionId: item.questionId,
        questionType: item.questionType,
        score: item.score || 2,
        sort: index,
      });
    });
    this.setState(
      {
        formData: {
          ...formData,
          questionList,
        },
      },
      () => {
        if (["new", "copy"].includes(currentOperate)) {
          AidToolService.createPaper(this.state.formData)
            .then((res) => {
              if (res.success) {
                if (saveType === "saveToAddExam") {
                  this.setState({formData:{ ...formData, paperId: res.result}},() => {
                    window.RCHistory.push({
                      pathname: `${match.url}/exam-operate-page`,
                    });
                  })
                } else {
                  message.success(
                    currentOperate === "new" ? "新建成功" : "复制成功"
                  );
                  window.RCHistory.push({
                    pathname: `/paper-manage-index?categoryId=${categoryId}`,
                  });
                  Bus.trigger(
                    "queryPaperPageList",
                    categoryId,
                    selectQuestionList.length
                  );
                  Bus.trigger("queryCategoryTree", "remain");
                }
              }
            })
            .catch((e) => {
              window.RCHistory.push({
                pathname: `/paper-manage-index?categoryId=${categoryId}`,
              });
              Bus.trigger(
                "queryPaperPageList",
                categoryId,
                selectQuestionList.length
              );
              Bus.trigger("queryCategoryTree", "remain");
            });
        } else if (currentOperate === "edit") {
          AidToolService.editPaper({
            ...this.state.formData,
            paperId: getParameterByName("paperId"),
          })
            .then((res) => {
              if (res.success) {
                if (saveType === "saveToAddExam") {
                  window.RCHistory.push({
                    pathname: `${match.url}/exam-operate-page`,
                  });
                } else {
                  message.success("编辑成功");
                  window.RCHistory.push({
                    pathname: `/paper-manage-index?categoryId=${categoryId}`,
                  });
                  Bus.trigger(
                    "queryPaperPageList",
                    categoryId,
                    selectQuestionList.length
                  );
                }
              }
            })
            .catch((e) => {
              window.RCHistory.push({
                pathname: `/paper-manage-index?categoryId=${categoryId}`,
              });
              Bus.trigger(
                "queryPaperPageList",
                categoryId,
                selectQuestionList.length
              );
            });
        }
      }
    );
  };

  // 预览试卷
  previewPaper = () => {
    const { selectQuestionList, formData } = this.state;
    const m = (
      <PaperPreviewModal
        previewPage="paper-operate"
        paperInfo={{ ...formData, questionList: selectQuestionList }}
        close={() => {
          this.setState({
            paperPreviewModal: null,
          });
        }}
      />
    );
    this.setState({ paperPreviewModal: m });
  };

  // 取消/返回
  handleGoBack = () => {
    Modal.confirm({
      title: "确定要返回吗？",
      content: "返回后，本次编辑的内容将不被保存",
      okText: "确认返回",
      cancelText: "留在本页",
      icon: (
        <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>
      ),
      onOk: () => {
        window.RCHistory.push({
          pathname: `/paper-manage-index?categoryId=${getParameterByName(
            "categoryId"
          )}`,
        });
        Bus.trigger("queryCategoryTree", "remain");
        Bus.trigger("queryPaperPageList", getParameterByName("categoryId"), 0);
      },
    });
  };

  // 题型排序
  sortByQuestionType = (pagination, filters, sorter) => {
    const { columnKey, order } = sorter;
    if (columnKey === "questionType") {
      this.setFormData(this.state.selectQuestionList, order);
    }
  };

  // 表头设置
  parseColumns = () => {
    const { selectQuestionList } = this.state;
    const columns = [
      {
        title: "序号",
        dataIndex: "index",
        key: "index",
        width: "10%",
        render: (val, record, index) => {
          return <span>{index + 1}</span>;
        },
      },
      {
        title: "题型",
        dataIndex: "questionType",
        key: "questionType",
        width: "12%",
        sorter: true,
        showSorterTooltip: false,
        filters: [
          {
            text: "单选题",
            value: "SINGLE_CHOICE",
          },
          {
            text: "多选题",
            value: "MULTI_CHOICE",
          },
          {
            text: "判断题",
            value: "JUDGE",
          },
          {
            text: "填空题",
            value: "GAP_FILLING",
          },
          {
            text: "不定项选择题",
            value: "INDEFINITE_CHOICE",
          },
        ],
        filterMultiple: true,
        onFilter: (value, record) => record.questionType.indexOf(value) === 0,
        render: (val) => questionTypeEnum[val],
      },
      {
        title: "题目",
        dataIndex: "questionStem",
        key: "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, " ");
          return (
            <Tooltip
              overlayClassName="aid-tool-list"
              title={
                <div style={{ maxWidth: 700, width: "auto" }}>{handleVal}</div>
              }
              placement="topLeft"
              overlayStyle={{ maxWidth: 700 }}
            >
              {handleVal}
            </Tooltip>
          );
        },
      },
      {
        title: (
          <span>
            分值{" "}
            <Tooltip title="多选题和填空题的漏选/半对得分不能高于题目本身分值">
              <span
                className="icon iconfont"
                style={{ color: "#BFBFBF", fontSize: 14,fontWeight:"400"
              }}
              >
                &#xe7c4;
              </span>
            </Tooltip>
          </span>
        ),
        dataIndex: "score",
        key: "score",
        width: "12%",
        render: (val, record, index) => {
          return (
            <InputNumber
              min={1}
              max={100}
              value={record.score || 2}
              onChange={(value) => {
                const _selectQuestionList = [...selectQuestionList];
                this.setState(
                  {
                    selectQuestionList: _selectQuestionList.map((item) =>
                      item.questionId === record.questionId
                        ? { ...item, score: value }
                        : item
                    ),
                  },
                  () => this.setFormData(this.state.selectQuestionList)
                );
              }}
            />
          );
        },
      },
      {
        dataIndex: "portionScore",
        key: "portionScore",
        width: "18%",
        render: (val, record, index) => {
          return (
            ["MULTI_CHOICE", "GAP_FILLING", "INDEFINITE_CHOICE"].includes(
              record.questionType
            ) && (
              <div>
                {record.questionType === "GAP_FILLING" ? (
                  <span>半对得</span>
                ) : (
                  <span>漏选得</span>
                )}{" "}
                <InputNumber
                  min={0}
                  max={record.score - 1}
                  value={record.portionScore || 0}
                  onChange={(value) => {
                    const _selectQuestionList = [...selectQuestionList];
                    this.setState(
                      {
                        selectQuestionList: _selectQuestionList.map((item) =>
                          item.questionId === record.questionId
                            ? { ...item, portionScore: value }
                            : item
                        ),
                      },
                      () => this.setFormData(this.state.selectQuestionList)
                    );
                  }}
                />
              </div>
            )
          );
        },
      },
      {
        title: "操作",
        dataIndex: "operate",
        key: "operate",
        width: "16%",
        render: (val, record, index) => {
          return (
            <div className="record-operate">
              <div
                className={
                  index > 0 ? "record-operate__item" : "record-operate__ban"
                }
                onClick={() => {
                  this.handleMoveItem(index, -1);
                }}
              >
                上移
              </div>
              <span className="record-operate__item split"> | </span>
              <div
                className={
                  index < selectQuestionList.length - 1
                    ? "record-operate__item"
                    : "record-operate__ban"
                }
                onClick={() => {
                  this.handleMoveItem(index, 1);
                }}
              >
                下移
              </div>
              <span className="record-operate__item split"> | </span>
              <div
                className="record-operate__item"
                onClick={() => {
                  this.handleDelItem(record.questionId);
                }}
              >
                移除
              </div>
            </div>
          );
        },
      },
    ];
    return columns;
  };

  render() {
    const {
      selectQuestionModal,
      paperPreviewModal,
      selectQuestionList,
      currentNav,
      formData,
      loading,
      check,
      currentOperate,
    } = this.state;
    const {
      singleChoiceCnt,
      multiChoiceCnt,
      judgeCnt,
      gapFillingCnt,
      indefiniteChoiceCnt,
      singleChoiceScore,
      multiChoiceScore,
      judgeScore,
      gapFillingScore,
      indefiniteChoiceScore,
      paperName,
      passRate,
      passScore,
      questionCnt,
      totalScore,
    } = formData;
    const { match } = this.props;
    const defaultOptions = {
      loop: true,
      autoplay: true,
      animationData: paperEmpty,
      rendererSettings: {
        preserveAspectRatio: 'xMidYMid slice'
      }
    }
    return (
      <div>
        <div className="page operate-paper-page">
          <Breadcrumbs
            navList={currentNav}
            goBack={() => this.handleGoBack()}
          />
          <Spin spinning={loading}>
            <div className="box">
              <div className="show-tips">
                <ShowTips message="请遵守国家相关规定，切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容，小麦企学院保有依据国家规定及平台规则进行处理的权利" />
              </div>
              <Form ref={this.formRef} style={{ marginTop: 24 }}>
                <Form.Item
                  name="paperName"
                  label="试卷名称："
                  required
                  validateStatus={
                    this.validatePaperName(paperName) ? "error" : ""
                  }
                  help={this.validatePaperName(paperName)}
                >
                  <Input
                    value={paperName}
                    autoComplete="off"
                    maxLength={40}
                    style={{ width: 300 }}
                    placeholder="请输入试卷名称（40字以内）"
                    onChange={(e) => {
                      this.setState({
                        formData: {
                          ...formData,
                          paperName: e.target.value.trim(),
                        },
                      });
                    }}
                  />
                </Form.Item>

                <Form.Item
                  name="passRate"
                  label="及格线："
                  required
                  validateStatus={check && !passRate ? "error" : ""}
                  help={check && !passRate && "请输入及格线"}
                >
                  <div>
                    <InputNumber
                      min={1}
                      max={100}
                      value={passRate}
                      onChange={(value) => {
                        this.setState(
                          {
                            formData: {
                              ...formData,
                              passRate: parseInt(value) || undefined,
                            },
                          },
                          () => this.setFormData(selectQuestionList)
                        );
                      }}
                    />{" "}
                    %
                    <span className="score-info">
                      总分（{Number(totalScore) || 0}）*及格线（
                      {Number(passRate) || 0}
                      %）=及格分数（
                      {Number(passScore) || 0}）
                    </span>
                  </div>
                </Form.Item>

                <Button
                  className="choose-btn"
                  type="primary"
                  icon={<PlusOutlined />}
                  onClick={this.chooseQuestion}
                >
                  自选题目
                </Button>
                {questionCnt > 0 && (
                  <div
                    className="paper-info-tip"
                    style={{ margin: "0 auto 12px" }}
                  >
                    总计<span>{totalScore}</span>分，共
                    <span>{questionCnt}</span>
                    题。{" "}
                    {singleChoiceCnt > 0 &&
                      `单选题${singleChoiceCnt}题，共${singleChoiceScore}分；`}
                    {multiChoiceCnt > 0 &&
                      `多选题${multiChoiceCnt}题，共${multiChoiceScore}分；`}
                    {judgeCnt > 0 && `判断题${judgeCnt}题，共${judgeScore}分，`}
                    {gapFillingCnt > 0 &&
                      `填空题${gapFillingCnt}题，共${gapFillingScore}分，`}
                    {indefiniteChoiceCnt > 0 &&
                      `不定项选择题${indefiniteChoiceCnt}题，共${indefiniteChoiceScore}分`}
                  </div>
                )}

                <XMTable
                  className="table-style"
                  scroll={{ y: 350 }}
                  columns={this.parseColumns()}
                  dataSource={selectQuestionList}
                  pagination={false}
                  onChange={this.sortByQuestionType}
                  renderEmpty={{
                    image: <div style={{ marginTop: 24 }}>
                      <Lottie
                        options={defaultOptions}
                        height={150}
                        width={150}
                        isStopped={false}
                        isPaused={false}
                      />
                    </div>,
                    description: <span style={{ display: 'block', paddingBottom: 24 }}>请在左上角添加题目</span>
                  }}
                />
              </Form>
            </div>
            <div className="footer">
              <Button onClick={this.handleGoBack}>取消</Button>
              <Button onClick={this.previewPaper}>预览</Button>
              <Button onClick={() => this.savePaper("saveToAddExam")}>
                保存并组织考试
              </Button>
              <Button type="primary" onClick={() => this.savePaper()}>
                保存
              </Button>
            </div>
          </Spin>
          {selectQuestionModal}
          {paperPreviewModal}
        </div>
        <Route
          path={`${match.url}/exam-operate-page`}
          render={() => {
            return (
              <AddExam
                paperInfo={formData}
                type={
                  currentOperate === "edit"
                    ? "editPaperToAddExam"
                    : "newPaperToAddExam"
                }
              />
            );
          }}
        />
      </div>
    );
  }
}

export default withRouter(OperatePaper);
