<template>
  <div v-if="isSyncState" :key="answerDivKey" class="question-view">
    <question-body
      :question-body="question.body"
      :exam-question="examQuestion"
    ></question-body>
    <div class="ops">
      <div class="score">({{ examQuestion.questionScore }}分)</div>
    </div>
    <div class="option">
      <!-- <textarea v-model="studentAnswer" maxlength="5000" type="text" /> -->

      <div v-if="!isAudioAnswerType">
        <div class="menu">
          <i-button type="info" class="text-ops" size="small" @click="textCopy">
            复制
          </i-button>
          <i-button type="info" class="text-ops" size="small" @click="textCut">
            剪切
          </i-button>
          <i-button
            type="info"
            class="text-ops"
            size="small"
            @click="textPaste"
          >
            粘贴
          </i-button>
          <i-button type="info" class="text-ops" size="small" @click="textSup">
            上标
          </i-button>
          <i-button
            type="info"
            class="text-ops"
            size="small"
            @click="undoTextSup"
          >
            取消上标
          </i-button>
          <i-button type="info" class="text-ops" size="small" @click="textSub">
            下标
          </i-button>
          <i-button
            type="info"
            class="text-ops"
            size="small"
            @click="undoTextSup"
          >
            取消下标
          </i-button>
        </div>
        <div
          ref="answerDiv"
          ondragstart="return false"
          ondrop="return false"
          :contenteditable="true"
          class="stu-answer"
          @keydown="disableCtrl"
          @input="($event) => textInput($event)"
          @blur="($event) => textInput($event)"
          v-html="originalStudentAnswer"
        ></div>
        <div
          style="
            margin-top: -25px;
            margin-bottom: 25px;
            width: 100%;
            max-width: 500px;
          "
        >
          <div style="float: right; margin-right: 10px">
            {{ answerWordCount }}
          </div>
        </div>
      </div>
      <div v-if="shouldFetchQrCode && isAudioAnswerType">
        <div>
          <div v-if="qrValue" style="display: flex">
            <qrcode
              :value="qrValue"
              :options="{ width: 200 }"
              style="margin-left: -10px"
            ></qrcode>
            <div style="margin-top: 10px">
              <div>
                请使用<span style="font-weight: 900; color: #1e90ff">微信</span
                >扫描二维码后，在微信小程序上{{
                  isAudioAnswerType ? "录音" : "拍照"
                }}，并上传文件。
              </div>
              <div v-if="qrScanned" style="margin-top: 30px; font-size: 30px">
                {{ examQuestion.studentAnswer ? "已上传" : "已扫描" }}
                <Icon type="md-checkmark" />
              </div>
            </div>
          </div>
          <div v-else>正在获取二维码...</div>
        </div>

        <div
          class="audio-answer audio-answer-line-height"
          style="margin-top: 20px"
        >
          <span class="audio-answer-line-height">答案：</span>
          <audio
            v-if="examQuestion.studentAnswer"
            class="audio-answer-line-height"
            controls
            controlsList="nodownload"
            :src="examQuestion.studentAnswer"
          />
          <span v-else class="audio-answer-line-height">未上传文件</span>
        </div>
      </div>

      <div v-if="canAttachPhotos" style="padding-top: 1px">
        <UploadPhotos
          :default-list="
            photoAnswers.map((v) => {
              return v;
            })
          "
          :qr-value="qrValue"
          :exam-question="examQuestion"
          style="margin-top: 20px; width: 350px"
          @on-photo-added="photoAdded"
          @on-photo-removed="photoRemoved"
          @on-photos-reseted="photosReseted"
        />
      </div>
      <div class="reset" style="padding-top: 20px">
        <!-- <i-button type="warning" size="large" @click="resetAnswer">
          重置答案
        </i-button> -->
        <span v-if="examShouldShowAnswer()">
          &nbsp;&nbsp;&nbsp;<i-button
            type="info"
            size="large"
            @click="showAnswer"
          >
            显示答案
          </i-button>
        </span>
        <div v-if="examShouldShowAnswer() && isShowAnswer">
          正确答案：
          <div v-html="rightAnswerTransform"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import QuestionBody from "./QuestionBody";
import { createNamespacedHelpers } from "vuex";
const { mapMutations, mapGetters, mapState } =
  createNamespacedHelpers("examingHomeModule");
import VueQrcode from "@chenfengyuan/vue-qrcode";
import UploadPhotos from "./UploadPhotos";

export default {
  name: "TextQuestionView",
  components: {
    QuestionBody,
    UploadPhotos,
    qrcode: VueQrcode,
  },
  props: {
    question: {
      type: Object,
      default() {
        return {};
      },
    },
    examQuestion: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      studentAnswer: this.examQuestion.studentAnswer,
      originalStudentAnswer: this.examQuestion.studentAnswer,
      isShowAnswer: false,
      answerDivKey: Math.random(),
      qrValue: "",
      qrScanned: false,
    };
  },
  computed: {
    ...mapState(["exam", "questionQrCode", "questionQrCodeScanned"]),
    isSyncState() {
      return this.examQuestion.order == this.$route.params.order;
    },
    rightAnswerTransform() {
      return this.question.rightAnswer.join("");
    },
    answerWordCount() {
      if (this.studentAnswer && this.$refs.answerDiv) {
        return this.$refs.answerDiv.innerText.replace(/\s+/g, "").length;
      } else {
        const ele = document.createElement("div");
        ele.innerHTML = this.studentAnswer;

        return ele.innerText.replace(/\s+/g, "").length;
      }
    },
    isAudioAnswerType() {
      return this.examQuestion.answerType === "SINGLE_AUDIO";
    },
    shouldFetchQrCode() {
      const shouldFetch = this.exam.WEIXIN_ANSWER_ENABLED;

      return shouldFetch;
    },
    canAttachPhotos() {
      return this.exam.WEIXIN_ANSWER_ENABLED && !this.isAudioAnswerType;
    },
    photoAnswers: {
      get() {
        if (!this.studentAnswer) return [];
        const ele = document.createElement("div");
        ele.innerHTML = this.studentAnswer;
        const imgs = ele.querySelectorAll(".photo-answer");
        // if()
        return [...imgs].map((e) =>
          e.src.replace("?x-oss-process=image/resize,m_lfit,h_200,w_200", "")
        );
      },
      set(pSrcs) {
        let imageStr = pSrcs.map(
          (v) =>
            `<a href='${v}' target='_blank' ><img class='photo-answer' src='${
              v + "?x-oss-process=image/resize,m_lfit,h_200,w_200"
            }' /></a>`
        );
        const ele = document.createElement("div");
        ele.innerHTML = this.studentAnswer || "";
        const pEle = ele.querySelectorAll(".photo-answers-block");
        if (pEle) [...pEle].forEach((v) => v.remove());
        // console.log(ele.innerHTML);

        if (!ele.innerHTML && pSrcs.length === 0) {
          // 完全为空则重置答案
          this.studentAnswer = null;
          // 更新answerDiv的内容
          this.originalStudentAnswer = null;
        } else {
          this.studentAnswer =
            ele.innerHTML +
            `<div class='photo-answers-block'>${imageStr.join("")}</div>`;
          // 更新answerDiv的内容
          this.originalStudentAnswer = this.studentAnswer;
        }
      },
    },
  },
  watch: {
    examQuestion() {
      // console.log(this.examQuestion.studentAnswer);
      this.studentAnswer = this.examQuestion.studentAnswer;
    },
    questionQrCode(value) {
      // console.log(this.examQuestion.studentAnswer);
      // console.log("watch", value);
      if (value.order === this.examQuestion.order) {
        this.qrValue = value.qrCode;
      }
    },
    questionQrCodeScanned(value) {
      // console.log(this.examQuestion.studentAnswer);
      // console.log("watch", value);
      if (value.order === this.examQuestion.order) {
        this.qrScanned = true;
      }
    },
    studentAnswer() {
      let realAnswer = null;
      if (this.studentAnswer) {
        // 如果有实际内容
        realAnswer = this.studentAnswer
          .replace(/<sup><\/sup>/gi, "")
          .replace(/<sub><\/sub>/gi, "")
          .replace(/<script/gi, "&lt;script")
          .replace(/script>/gi, "script&gt;");
        // .replace(/</gi, "&lt;")
        // .replace(/>/gi, "&gt;")
        // .replace(/&lt;div&gt;&lt;br&gt;&lt;\/div&gt;/gi, "<div><br></div>");
      }
      if (realAnswer !== this.examQuestion.studentAnswer) {
        this.updateExamQuestion({
          order: this.examQuestion.order,
          studentAnswer: realAnswer,
        });
      }
    },
  },
  created() {
    this.fetchQRCode();

    this.fetchQRCodeInterval = setInterval(() => {
      if (!this.qrValue) {
        this.fetchQRCode();
      } else {
        clearInterval(this.fetchQRCodeInterval);
      }
    }, 6 * 1000);
  },
  beforeDestroy() {
    clearInterval(this.fetchQRCodeInterval);
  },
  methods: {
    ...mapMutations(["updateExamQuestion"]),
    ...mapGetters(["examShouldShowAnswer"]),
    disableCtrl(e) {
      if (e.ctrlKey || e.metaKey || e.altKey) {
        // .ctrlKey tells that ctrl key was pressed.
        e.preventDefault();
        return false;
      }
      return true;
    },
    textCopy() {
      var selElm = getSelection();
      var selRange = selElm.getRangeAt(0);
      this.copyNode = selRange.cloneContents();
    },
    textCut() {
      var selElm = getSelection();
      var selRange = selElm.getRangeAt(0);
      this.copyNode = selRange.extractContents();
      this.studentAnswer = this.$refs.answerDiv.innerHTML;
    },
    textPaste() {
      var selElm = getSelection();
      var selRange = selElm.getRangeAt(0);
      selRange.deleteContents();
      selRange.insertNode(this.copyNode.cloneNode(true));
      this.studentAnswer = this.$refs.answerDiv.innerHTML;
    },
    textSup() {
      const origHMTL = this.$refs.answerDiv.innerHTML + "";
      getSelection()
        .getRangeAt(0)
        .surroundContents(document.createElement("sup"));
      if (
        this.$refs.answerDiv.querySelector("sup sup, sub sub, sup sub, sub sup")
      ) {
        console.log("不允许多层上标下标");
        this.$refs.answerDiv.innerHTML = origHMTL;
      } else {
        this.studentAnswer = this.$refs.answerDiv.innerHTML;
      }
    },
    undoTextSup() {
      // 取消上标时，必须选择之前的文字，才能实现
      getSelection().modify("extend", "left", "character");
      let selRange = getSelection().getRangeAt(0);
      var documentFragment = selRange.extractContents();
      var text = new Text(documentFragment.textContent);
      selRange.insertNode(text);
      this.studentAnswer = this.$refs.answerDiv.innerHTML;
    },
    textSub() {
      const origHMTL = this.$refs.answerDiv.innerHTML + "";
      getSelection()
        .getRangeAt(0)
        .surroundContents(document.createElement("sub"));
      if (
        this.$refs.answerDiv.querySelector("sup sup, sub sub, sup sub, sub sup")
      ) {
        console.log("不允许多层上标下标");
        this.$refs.answerDiv.innerHTML = origHMTL;
      } else {
        this.studentAnswer = this.$refs.answerDiv.innerHTML;
      }
    },
    textInput($event) {
      // console.log($event.target.innerHTML);
      this.studentAnswer = $event.target.innerHTML;
    },
    showAnswer() {
      this.isShowAnswer = !this.isShowAnswer;
    },
    resetAnswer() {
      this.studentAnswer = null;
      this.originalStudentAnswer = null;
      // this.$nextTick(() => {
      //   // Object.assign(this.$data, this.$options.data());
      //   // this.$refs.answerDiv.$forceUpdate();
      //   this.answerDivKey = Math.random();
      // });
      this.answerDivKey = Math.random();
    },
    async fetchQRCode() {
      if (this.shouldFetchQrCode) {
        const transferFileType =
          this.examQuestion.answerType === "SINGLE_AUDIO" ? "AUDIO" : "PIC";
        const examRecordDataId = this.$route.params.examRecordDataId;
        const response = await this.$http.post(
          "/api/ecs_oe_student/examControl/getQrCode",
          {
            examRecordDataId,
            order: +this.examQuestion.order,
            transferFileType,
            testEnv: false,
          }
        );
        let origin = window.location.origin;
        if (process.env.NODE_ENV === "development") {
          origin = process.env.VUE_APP_API_SERVER;
        }
        this.qrValue =
          response.data + encodeURIComponent("&apiServer=" + origin);
      }
    },
    photoAdded(url) {
      // console.log(url);
      this.photoAnswers = [...this.photoAnswers, url];
    },
    photoRemoved(url) {
      // console.log("to remove: ", url, " from: ", this.photoAnswers);
      // console.log(
      //   "this.photoAnswers.filter(v => v !== url)",
      //   this.photoAnswers.filter(v => v !== url)
      // );
      this.photoAnswers = this.photoAnswers.filter((v) => v !== url);
      // console.log(this.photoAnswers);
    },
    photosReseted(urls) {
      this.photoAnswers = [...urls];
    },
  },
};
</script>

<style scoped>
.question-view {
  display: grid;
  grid-row-gap: 10px;
}

.question-body {
  font-size: 18px;
  /* margin-bottom: 10px; */
}

.ops {
  display: flex;
  align-items: flex-end;
}

.text-ops {
  margin: 0 5px 5px 0;
}

.stu-answer {
  width: 100%;
  max-width: 500px;
  min-height: 300px;
  border: 1px solid grey;
  padding: 2px;
}

.audio-answer {
  font-size: 24px;
  line-height: 54px;
}
.audio-answer-line-height {
  line-height: 54px;
  vertical-align: text-bottom;
}
</style>
<style>
.photo-answers-block {
  display: none;
}
</style>
