<template>
  <QuestionBase>
    <template #content>
      <div class="stem">
        <RichText v-model="data.stem" :font-size="18" placeholder="输入题干" />

        <RichText
          v-if="isEnable(data.property.is_enable_description)"
          v-model="data.description"
          placeholder="输入提示"
        />
      </div>

      <div class="content-wrapper">
        <div class="content">
          <div
            v-for="({ role, file_id, type, text }, i) in data.option_list"
            :key="i"
            class="option-list"
            :style="{ flexDirection: type === 'input' ? 'row-reverse' : 'row' }"
          >
            <span
              class="avatar"
              :style="{
                backgroundColor: data.property.role_list.find((item) => item.mark === role).color,
              }"
            >
              {{ data.property.role_list.find((item) => item.mark === role).name }}
            </span>

            <div v-if="type === 'text'" class="text">{{ text }}</div>

            <div v-else-if="type === 'image'" class="image">
              <img :src="file_map_list[file_id]" />
            </div>

            <div v-else-if="type === 'audio'" class="audio">
              <AudioPlay
                :file-id="file_id"
                :show-slider="true"
                :show-progress="false"
                :background-color="data.property.role_list.find((item) => item.mark === role).color"
              />
            </div>

            <div v-else-if="type === 'input'">
              <SoundRecordPreview type="small" :disabled="true" />
            </div>

            <div class="content-operation" :style="{ flexDirection: type === 'input' ? 'row-reverse' : 'row' }">
              <div class="up-down">
                <span :style="{ borderBottomColor: i === 0 ? '#c2c2c4' : '#000' }" @click="moveOption('up', i)"></span>
                <span
                  :style="{ borderTopColor: i < data.option_list.length - 1 ? '#000' : '#c2c2c4' }"
                  @click="moveOption('down', i)"
                ></span>
              </div>
              <SvgIcon icon-class="delete" @click="deleteOption(i)" />
            </div>
          </div>
        </div>

        <div class="operation">
          <div class="operation-left">
            <el-select v-model="curRole" placeholder="请选择">
              <el-option
                v-for="(item, i) in data.property.role_list"
                :key="i"
                :label="item.name.length === 0 ? ' ' : item.name"
                :value="item.mark"
              />
            </el-select>
            <SoundRecord @saveWav="saveWav" />
          </div>
          <div class="operation-right">
            <el-upload
              action="no"
              accept="audio/*"
              :show-file-list="false"
              :http-request="handleAudio"
              :before-upload="handleBeforeAudio"
            >
              <SvgIcon icon-class="music" />
              <span>上传音频</span>
            </el-upload>
            <el-upload
              action="no"
              accept="image/*"
              :show-file-list="false"
              :http-request="handleImage"
              :before-upload="handleBeforeImage"
            >
              <SvgIcon icon-class="picture" />
              <span>上传图片</span>
            </el-upload>
            <div class="insert-student" @click="insertStudent">
              <SvgIcon icon-class="add-circle" size="14" />
              <span>插入学生</span>
            </div>
          </div>
        </div>

        <el-input
          v-model="textInput"
          placeholder="输入"
          type="textarea"
          resize="none"
          :autosize="{ minRows: 3 }"
          @keyup.enter.native="handleText"
        />
        <span class="tips">输入对话内容后请按回车上屏</span>
      </div>

      <div v-if="isEnable(data.property.is_enable_reference_answer)" class="reference-answer">
        <div class="reference-title">参考答案：</div>
        <el-input v-model="data.reference_answer" type="textarea" rows="3" placeholder="输入参考答案" />
      </div>

      <div v-if="isEnable(data.property.is_enable_analysis)" class="analysis">
        <div class="analysis-title">解析：</div>
        <RichText v-model="data.analysis" :is-border="true" :font-size="14" placeholder="输入解析" />
      </div>
    </template>

    <template #property>
      <el-form :model="data.property" label-width="72px" label-position="left">
        <el-form-item label="题号">
          <el-input v-model="data.property.question_number" />
        </el-form-item>
        <el-form-item>
          <el-radio
            v-for="{ value, label } in questionNumberTypeList"
            :key="value"
            v-model="data.other.question_number_type"
            :label="value"
          >
            {{ label }}
          </el-radio>
        </el-form-item>
        <el-form-item label="题干题号">
          <el-select v-model="data.property.stem_question_number_font_size">
            <el-option v-for="item in fontSizeList" :key="item" :label="item" :value="item" />
          </el-select>
        </el-form-item>
        <el-form-item label="提示">
          <el-radio
            v-for="{ value, label } in switchOption"
            :key="value"
            v-model="data.property.is_enable_description"
            :label="value"
          >
            {{ label }}
          </el-radio>
        </el-form-item>
        <el-form-item label="参考答案">
          <el-radio
            v-for="{ value, label } in switchOption"
            :key="value"
            v-model="data.property.is_enable_reference_answer"
            :label="value"
          >
            {{ label }}
          </el-radio>
        </el-form-item>
        <el-form-item label="解析">
          <el-radio
            v-for="{ value, label } in switchOption"
            :key="value"
            v-model="data.property.is_enable_analysis"
            :label="value"
          >
            {{ label }}
          </el-radio>
        </el-form-item>
        <el-form-item label="分值">
          <el-radio
            v-for="{ value, label } in scoreTypeList"
            :key="value"
            v-model="data.property.score_type"
            :label="value"
          >
            {{ label }}
          </el-radio>
        </el-form-item>
        <el-form-item>
          <el-input-number
            v-model="data.property.score"
            :min="0"
            :step="data.property.score_type === scoreTypeList[0].value ? 1 : 0.1"
          />
        </el-form-item>
        <el-form-item label="语音作答">
          <el-radio
            v-for="{ value, label } in switchOption"
            :key="value"
            v-model="data.property.is_enable_voice_answer"
            :label="value"
          >
            {{ label }}
          </el-radio>
        </el-form-item>
        <el-form-item label="角色数">
          <el-select v-model="data.property.role_number" placeholder="请选择">
            <el-option v-for="item in 5" :key="item" :label="item" :value="item" />
          </el-select>
        </el-form-item>
        <el-form-item v-for="(item, i) in data.property.role_list" :key="i" :label="`角色 ${i + 1}`" class="role">
          <el-input v-model="item.name" />
          <el-color-picker v-model="item.color" />
        </el-form-item>
      </el-form>
    </template>
  </QuestionBase>
</template>

<script>
import QuestionMixin from '../common/QuestionMixin.js';
import AudioPlay from '../common/AudioPlay.vue';
import SoundRecord from '@/components/common/SoundRecord.vue';
import SoundRecordPreview from '@/views/exercise_questions/preview/components/common/SoundRecordPreview.vue';

import { getRandomNumber } from '@/utils';
import { fileUpload, GetFileURLMap } from '@/api/app';
import { analysisRecognitionDialogueData, getDialogueData, getRole } from '@/views/exercise_questions/data/dialogue';

export default {
  name: 'DialogueQuestion',
  components: {
    AudioPlay,
    SoundRecord,
    SoundRecordPreview,
  },
  mixins: [QuestionMixin],
  data() {
    return {
      curRole: '',
      textInput: '',
      file_id_list: [],
      file_map_list: [],
      data: getDialogueData(),
    };
  },
  watch: {
    'data.property.role_number'(val) {
      if (this.data.property.role_list.length > val) {
        this.data.property.role_list = this.data.property.role_list.slice(0, val);
      } else {
        for (let i = this.data.property.role_list.length; i < val; i++) {
          this.data.property.role_list.push(getRole(i));
        }
      }
    },
    'data.property.role_list': {
      handler(val) {
        // 如果当前角色（curRole）不在角色列表中，将当前角色（curRole）设置为角色列表中的第一个角色
        if (val.find((item) => item.mark === this.curRole) === undefined && val.length > 0) {
          this.curRole = val[0].mark;
        }
      },
      immediate: true,
    },
    'data.option_list': {
      handler(val) {
        let file_id_list = [];
        val.forEach(({ type, file_id }) => {
          if (type === 'image' || type === 'audio') {
            file_id_list.push(file_id);
          }
        });
        // 判断 this.file_id_list 和 file_id_list 两个数组中的内容是否相等，位置可能不同
        if (
          this.file_id_list.length === file_id_list.length &&
          this.file_id_list.every((item) => file_id_list.includes(item))
        ) {
          return;
        }
        this.file_id_list = file_id_list;
        GetFileURLMap({ file_id_list }).then(({ url_map }) => {
          this.file_map_list = url_map;
        });
      },
    },
  },
  methods: {
    /**
     * 智能识别
     * @param {String} text 识别数据
     */
    recognition(text) {
      let arr = this.recognitionCommon(text);
      let obj = analysisRecognitionDialogueData(arr);
      this.recognitionCommonSetObj(obj);
    },
    // 音频上传前处理
    handleBeforeAudio(file) {
      if (this.curRole.length <= 0) {
        this.$message.error('请先选择角色');
        return false;
      }
      // 判断文件是否为音频
      if (!file.type.includes('audio')) {
        this.$message.error('请选择音频文件');
        return false;
      }
    },
    // 图片上传前处理
    handleBeforeImage(file) {
      if (this.curRole.length <= 0) {
        this.$message.error('请先选择角色');
        return false;
      }
      // 判断文件是否为图片
      if (!file.type.includes('image')) {
        this.$message.error('请选择图片文件');
        return false;
      }
    },
    // 音频上传
    handleAudio(file) {
      this.upload('audio', file);
    },
    // 图片上传
    handleImage(file) {
      this.upload('image', file);
    },
    // 上传
    upload(type, file) {
      fileUpload('Mid', file, { isGlobalprogress: true }).then(({ file_info_list }) => {
        if (file_info_list.length > 0) {
          const { file_id } = file_info_list[0];
          this.data.option_list.push({
            role: this.curRole,
            file_id,
            type,
          });
        }
      });
    },
    // 处理输入文本
    handleText() {
      if (this.curRole.length <= 0) {
        return this.$message.error('请先选择角色');
      }

      this.data.option_list.push({
        role: this.curRole,
        text: this.textInput.replace(/\n/, ''),
        file_id: '',
        mark: getRandomNumber(),
        type: 'text',
      });
      this.textInput = '';
    },

    /**
     * 移动选项
     * @param {'up'|'down'} type 类型
     * @param {number} i 索引
     */
    moveOption(type, i) {
      if ((type === 'up' && i === 0) || (type === 'down' && i === this.data.option_list.length - 1)) return;
      const item = this.data.option_list[i];
      this.data.option_list.splice(i, 1);
      this.data.option_list.splice(type === 'up' ? i - 1 : i + 1, 0, item);
    },
    /**
     * 删除选项
     * @param {number} i 索引
     */
    deleteOption(i) {
      this.data.option_list.splice(i, 1);
    },
    // 插入学生
    insertStudent() {
      if (this.curRole.length <= 0) {
        return this.$message.error('请先选择角色');
      }

      this.data.option_list.push({
        mark: getRandomNumber(),
        role: this.curRole,
        file_id: '',
        type: 'input',
      });
    },
    /**
     * 保存音频
     * @param {string} file_id 文件id
     */
    saveWav(file_id) {
      this.data.option_list.push({
        role: this.curRole,
        file_id,
        type: 'audio',
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.content-wrapper {
  display: flex;
  flex-direction: column;
  row-gap: 8px;
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: $border;

  .content {
    display: flex;
    flex-direction: column;
    row-gap: 16px;
    padding: 16px;
    background-color: $fill-color;

    .option-list {
      display: flex;
      column-gap: 8px;

      .avatar {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 40px;
        min-width: 40px;
        height: 40px;
        min-height: 40px;
        margin-right: 8px;
        font-size: 12px;
        color: #fff;
        border-radius: 50%;
      }

      .content-operation {
        display: flex;
        column-gap: 8px;
        align-items: center;

        .up-down {
          display: flex;
          flex-direction: column;
          row-gap: 12px;

          // span 三角形
          :first-child {
            width: 0;
            height: 0;
            cursor: pointer;
            border-color: transparent;
            border-style: solid;
            border-width: 4px;
          }

          :last-child {
            width: 0;
            height: 0;
            cursor: pointer;
            border-color: transparent;
            border-style: solid;
            border-width: 4px;
          }
        }

        .svg-icon {
          cursor: pointer;
        }
      }

      .sound-record-preview {
        padding: 4px;
        background-color: #fff;
        border-radius: 40px;

        :deep .sound-item .sound-item-span {
          color: #1d1d1d;
          background-color: #fff;
        }

        :deep .sound-item-luyin .sound-item-span {
          color: #fff;
          background-color: $light-main-color;
        }
      }

      .text {
        padding: 8px 12px;
        word-break: break-all;
        background-color: #fff;
        border-radius: 8px;
      }

      .image img {
        height: 180px;
        border-radius: 8px;
      }
    }
  }

  .operation {
    display: flex;
    justify-content: space-between;
    font-size: 14px;

    &-left {
      display: flex;
      column-gap: 8px;
      align-items: center;

      .el-select {
        width: 130px;
      }
    }

    &-right {
      display: flex;
      column-gap: 36px;
      align-items: center;
      color: $main-color;

      .insert-student {
        display: flex;
        column-gap: 8px;
        align-items: center;
        cursor: pointer;
      }

      :deep .el-upload {
        display: flex;
        column-gap: 8px;
        align-items: center;
      }
    }
  }

  .tips {
    font-size: 14px;
    color: #e82d2d;
  }
}

.correct-answer {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 8px;
  margin-top: 8px;

  .el-input {
    width: 180px;

    :deep &__prefix {
      display: flex;
      align-items: center;
      color: $text-color;
    }
  }
}

.reference-answer {
  margin-top: 8px;

  .reference-title {
    margin-bottom: 8px;
    font-size: 14px;
  }
}

.el-form {
  .role {
    :deep .el-form-item__content {
      display: flex;
      flex: 1;

      .el-input {
        width: 100px;
        margin-right: 16px;
      }

      .el-color-picker {
        flex: 1;

        &__trigger {
          width: 100%;
          background-color: $fill-color;
        }

        &__color {
          width: 22px;
          height: 22px;
          border-width: 0;
        }

        &__icon {
          left: 88%;
          width: 20px;
          color: $font-color;
        }
      }
    }
  }
}
</style>
