<template>
  <div class="fx-column" :id="'question_'+question.questionId">
    <div v-html="questionWithSeq" class="answer"></div>
    <div class="fx-column mt30 pl20 pr20">
      <!-- 递归，支持子题 -->
      <template v-if="question['subQuestions']">
        <mx-question-content v-for="(sub, idx) in question['subQuestions']" :key="idx" :options="buildChildOptions(sub)"
                             :deep="deep + 1" class="mb20"></mx-question-content>
      </template>
      <template v-if="optionsVisible">
        <div v-if="useRadioStyle">
          <el-radio-group v-model="radioValue" :disabled="disabled" @change="valueChangedAction"
                          class="fx-column fx-sta-sta answer">
            <el-radio v-for="(opt, i) in optionsWithCode" :key="i" :label="opt.code" class="answer-option"
                      :class="{'answer-error':isWrong(opt.code),'answer-highlight':isHighlight(opt.code)}" border>
              <span style="white-space: normal;" v-html="opt.option"></span>
            </el-radio>
          </el-radio-group>
        </div>
        <div v-else-if="useMultipleStyle">
          <el-checkbox-group v-model="checkboxValue" :disabled="disabled" @change="valueChangedAction"
                             class="fx-column fx-sta-sta answer">
            <el-checkbox v-for="(opt, i) in optionsWithCode" :key="i" :label="opt.code" class="answer-option"
                         :class="{'answer-error':isWrong(opt.code),'answer-highlight':isHighlight(opt.code)}" border>
              <span style="white-space: normal;" v-html="opt.option"></span>
            </el-checkbox>
          </el-checkbox-group>
        </div>
        <div v-else-if="useViewOfLifeValuesPair||useViewOfLifeValuesQuadruplet">
          <div class="fx-column" v-for="(opt,i) in optionsWithCode" :key="i">
            <div class="fx-row fx-sta-cen">
              <el-slider v-model="philosophyForm[opt.code]" :min="0" :max="3" :show-stops="true"
                         :disabled="disabled" :marks="i == optionsWithCode.length -1 ? philosophyDescriptor:null"
                         :format-tooltip="philosophyFormatter"
                         @input="viewOfLifeValuesChanged(i)" style="width: 200px"></el-slider>
              <div v-html="opt.option" class="ml60"></div>
            </div>
          </div>
        </div>
        <div v-else>
          <div class="answer" v-for="(opt, i) in optionsWithCode" :key="i" v-html="opt.option"></div>
        </div>
        <div v-if="enableRememberAnswer" class="mt20">
          <el-divider></el-divider>
          记住回答
          <el-switch v-model="options.paperOptions.initWithAnswerOfPrevQuestion" class="ml10"></el-switch>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
// 1 这个组件只取题的title与options进行试题渲染，然后反馈用户对选项的操作
// 2 答题相关userAnswer、sysAnswer从外面传和操作
import questionMixin from './mx-question-mixin'

export default {
  mixins: [questionMixin],
  name: 'mx-question-content',
  props: {
    deep: {
      type: Number,
      default: 0
    }
  },
  computed: {
    disabled() {
      return !this.allowAnswer
    }
  },
  watch: {
    question: {
      immediate: true,
      handler: function(newVal) {
        // remember answer function
        if (this.enableRememberAnswer && !newVal._answer &&
          this.options.paperOptions?.initWithAnswerOfPrevQuestion &&
          this.options.paperOptions.currentTab > 0) {
          const prevQuestion = this.options.paperOptions.paper.questions[this.options.paperOptions.currentTab - 1]
          newVal._answer = prevQuestion._answer
        }
        // ensure values
        this.radioValue = newVal._answer
        this.checkboxValue = newVal._answer && newVal._answer.split(',') || []
        // 尝试使用上题答案
        let viewOfLifeAnswers = this.checkboxValue
        if (this.useViewOfLifeValuesPair) this.initViewOfLifeValuesPair(viewOfLifeAnswers)
        if (this.useViewOfLifeValuesQuadruplet) this.initViewOfLifeValuesQuadruplet(viewOfLifeAnswers)
      }
    }
  },
  data() {
    return {
      // radio-group, checkbox-group 必需要v-model模式才能正常工作!
      radioValue: '',
      checkboxValue: [],
      philosophyDescriptor: {
        0: '不赞同',
        1: '不太赞同',
        2: '赞同',
        3: { label: '非常赞同', style: {width: '60px'} }
      },
      philosophyForm: { A: 0, B: 0, C: 0, D: 0 }, // 最多只有4个选项
      useMathJax: this.deep == 0
    }
  },
  methods: {
    valueChangedAction(value) {
      // 这里没有直接使用组件结果，为的是保证组件输出类型与API要求一致为string
      let safeVal = value
      if (Array.isArray(safeVal)) {
        // 兼容历史逻辑，保证没有为空的答案和答案顺序
        safeVal = safeVal.filter(i => i)
        safeVal.sort()
      }
      this.question._answer = safeVal.toString()
      this.$emit('change', this.question._answer)
    },
    buildChildOptions(question) {
      return {
        question: question,
        allowAnswer: this.allowAnswer,
        allowScore: this.allowScore,
        examineeType: this.examineeType
      }
    },
    // 人生价值观测评
    initViewOfLifeValuesPair(vals) {
      vals = vals.map(v => isNaN(v) ? 0 : v * 1) // safe convert
      if (vals.length == 2 && vals.sum() == 3) {
        // 这是有效值，直接使用
        this.assignAndTriggerPair(vals, false)
      } else {
        const standardVals = [3, 0]
        this.assignAndTriggerPair(standardVals)
      }
    },
    initViewOfLifeValuesQuadruplet(vals) {
      vals = vals.map(v => isNaN(v) ? 0 : v * 1) // safe convert
      if (vals.length == 4 && vals.sum() == 6) {
        // 这是有效值，直接使用
        this.assignAndTriggerQuadruplet(vals, false)
      } else {
        const standardVals = [3, 2, 1, 0]
        this.assignAndTriggerQuadruplet(standardVals)
      }
    },
    philosophyFormatter(e) {
      const val = e || 0
      const desc = this.philosophyDescriptor[val]
      return typeof desc == 'string' ? desc : desc.label
    },
    viewOfLifeValuesChanged(index) {
      if (this.useViewOfLifeValuesPair) this.viewOfLifeValuesPairAdapter(index)
      if (this.useViewOfLifeValuesQuadruplet) this.viewOfLifeValuesQuadrupletAdapter(index)
    },
    viewOfLifeValuesPairAdapter(index) {
      const standardVals = [
        this.philosophyForm.A,
        this.philosophyForm.B
      ]
      // 只有两个选项，保证它们的和是3即可
      const delta = 3 - standardVals.sum()
      const target = index == 0 ? index + 1 : index - 1
      standardVals[target] = (standardVals[target] || 0) + delta
      this.assignAndTriggerPair(standardVals)
    },
    viewOfLifeValuesQuadrupletAdapter(index) {
      const standardVals = [
        this.philosophyForm.A,
        this.philosophyForm.B,
        this.philosophyForm.C,
        this.philosophyForm.D
      ]
      // 有4个选项，各占0-3，则每次发生变化，会产生两个相同的值，让重复的值对象置换正确值，这样只需要变化一次
      const modified = standardVals[index]
      const conflictIndex = standardVals.findIndex((v, i) => v == modified && i != index)
      const delta = 6 - standardVals.sum()
      standardVals[conflictIndex] = standardVals[conflictIndex] + delta
      this.assignAndTriggerQuadruplet(standardVals)
    },
    assignAndTriggerPair(standardVals, triggerEvent = true) {
      this.philosophyForm.A = standardVals.first()
      this.philosophyForm.B = standardVals.last()
      this.question._answer = standardVals.toString()
      if (triggerEvent) this.$emit('change', this.question._answer)
    },
    assignAndTriggerQuadruplet(standardVals, triggerEvent = true) {
      this.philosophyForm.A = standardVals[0]
      this.philosophyForm.B = standardVals[1]
      this.philosophyForm.C = standardVals[2]
      this.philosophyForm.D = standardVals[3]
      this.question._answer = standardVals.toString()
      if (triggerEvent) this.$emit('change', this.question._answer)
    }
  }
}
</script>
<style scoped>
.answer {
  /*  web端暂时不需要额外的样式  */
  /*  但common中有.answer img控制图片  */
}

.answer-option {
  margin-left: 0 !important;
  margin-bottom: 15px;
  height: auto !important;
  padding-bottom: 8px;
}

.answer-highlight,
/deep/ .answer-highlight .el-checkbox__label,
/deep/ .answer-highlight .el-radio__label {
  border-color: #47c6a2 !important;
  color: #47c6a2 !important;
}

.answer-error,
/deep/ .answer-error .el-checkbox__label,
/deep/ .answer-error .el-radio__label {
  border-color: #f56c6c !important;
  color: #f56c6c !important;
}

</style>
