<template>
  <ele-modal
    :visible.sync="visible"
    :title="dialogTitle"
    width="80vw"
    append-to-body
    :close-on-click-modal="false"
    :maxable="true"
    @close="cancel"
  >
    <!-- 题库头部信息 -->
    <div class="bank-header">
      <el-form
        ref="bankForm"
        :model="bankForm"
        :rules="bankRules"
        inline
        label-width="120px"
        class="bank-form"
      >
        <el-form-item label="题库名称：" prop="name">
          <el-input
            v-model="bankForm.name"
            placeholder="请输入题库名称"
            :disabled="isView"
          />
        </el-form-item>
        <el-form-item label="所属部门：" prop="deptId">
          <dept-select
            v-model="bankForm.deptId"
            placeholder="请选择所属部门"
            :disabled="isView"
            @changeGroup="onDeptChange"
          />
        </el-form-item>
      </el-form>
    </div>

    <div class="maintenance-body">
      <!-- 左侧题号列表 -->
      <div class="left-panel">
        <div class="panel-title">题号</div>
        <div class="panel-search">
          <el-input
            v-model="questionSearch"
            placeholder="输入关键词搜索试题"
            size="small"
          >
            <el-button
              slot="append"
              type="primary"
              size="small"
              @click="handleSearchQuestion"
              >搜索</el-button
            >
          </el-input>
        </div>
        <el-tree
          ref="treeRef"
          :data="questionList"
          node-key="id"
          default-expand-all
          highlight-current
          :props="{ label: 'label', children: 'children' }"
          @node-click="handleQuestionClick"
        >
          <span class="question-node" slot-scope="{ node, data }">
            <span>{{ node.label }}</span>
            <el-tooltip
              v-if="!isView && data.question"
              content="删除试题"
              placement="top"
            >
              <el-button
                type="text"
                class="question-delete"
                icon="el-icon-delete"
                aria-label="删除试题"
                @click.stop="handleDeleteQuestion(data)"
              />
            </el-tooltip>
          </span>
        </el-tree>
      </div>

      <!-- 右侧试题表单 -->
      <div class="right-panel">
        <question-form ref="questionFormRef" v-model="form" :is-view="isView" />
      </div>
    </div>

    <template v-slot:footer>
      <el-button v-if="!isView" @click="handleReset">重置</el-button>
      <el-button
        v-if="!isView"
        type="primary"
        @click="saveNext"
        :loading="loading"
        >保存并进入下一题</el-button
      >
      <el-button v-else @click="cancel">关闭</el-button>
    </template>
  </ele-modal>
</template>

<script>
  import DeptSelect from '@/components/CommomSelect/dept-select.vue';
  import QuestionForm from '../paperManagement/question-form.vue';
  import {
    deleteQuestion,
    edit as updateQuestionBank,
    getById,
    getList,
    save as saveQuestionBank
  } from '@/api/questionBank/questionBank.js';

  const questionTypeMap = {
    1: 'SINGLE',
    2: 'MULTIPLE',
    3: 'JUDGE',
    4: 'QUESTION_ANSWER'
  };

  const questionTypeReverseMap = {
    SINGLE: '1',
    MULTIPLE: '2',
    JUDGE: '3',
    QUESTION_ANSWER: '4'
  };

  const defBankForm = {
    id: '',
    name: '',
    deptId: '',
    deptName: ''
  };

  const defQuestionForm = {
    id: '',
    sort: '',
    content: '',
    type: '1',
    category: '',
    score: '',
    options: [
      { key: 'A', content: '' },
      { key: 'B', content: '' },
      { key: 'C', content: '' },
      { key: 'D', content: '' }
    ],
    rightAnswer: '',
    rightAnswers: [],
    analysis: ''
  };

  const createQuestionList = () => [];

  export default {
    components: {
      DeptSelect,
      QuestionForm
    },
    data() {
      return {
        visible: false,
        loading: false,
        dialogType: 'add',
        questionSearch: '',
        bankForm: JSON.parse(JSON.stringify(defBankForm)),
        bankRules: {
          name: [
            { required: true, message: '请输入题库名称', trigger: 'blur' }
          ],
          deptId: [
            { required: true, message: '请选择所属部门', trigger: 'change' }
          ]
        },
        form: JSON.parse(JSON.stringify(defQuestionForm)),
        questionList: createQuestionList()
      };
    },
    computed: {
      dialogTitle() {
        const titleMap = {
          add: '维护试题',
          edit: '维护试题',
          view: '查看试题'
        };
        return titleMap[this.dialogType] || '维护试题';
      },
      isView() {
        return this.dialogType === 'view';
      }
    },
    methods: {
      async open(row, type = 'add') {
        this.visible = true;
        this.dialogType = type;
        const questionBankId = row && (row.id || row.questionBankId);
        if (questionBankId) {
          this.bankForm = {
            id: questionBankId,
            name: row.questionBankName || row.name || '',
            deptId: row.departmentId || row.deptId || '',
            deptName: row.departmentName || row.deptName || ''
          };
          this.loading = true;
          try {
            await this.loadDetail(questionBankId, type === 'view');
          } catch (error) {
            this.$message.error(error.message || '获取题库详情失败');
            this.cancel();
          } finally {
            this.loading = false;
          }
        } else {
          this.bankForm = JSON.parse(JSON.stringify(defBankForm));
          this.questionList = createQuestionList();
          this.form = JSON.parse(JSON.stringify(defQuestionForm));
          this.$nextTick(() => {
            this.$refs.treeRef && this.$refs.treeRef.setCurrentKey('1');
          });
        }
        this.$nextTick(() => {
          this.$refs.bankForm && this.$refs.bankForm.clearValidate();
          this.$refs.questionFormRef &&
            this.$refs.questionFormRef.clearValidate();
        });
      },
      cancel() {
        this.bankForm = JSON.parse(JSON.stringify(defBankForm));
        this.form = JSON.parse(JSON.stringify(defQuestionForm));
        this.questionList = createQuestionList();
        this.visible = false;
      },
      onDeptChange(deptId, node) {
        this.bankForm.deptName = node ? node.name : '';
      },
      handleSearchQuestion() {
        // TODO: 搜索试题
        console.log('搜索试题', this.questionSearch);
      },
      handleQuestionClick(data) {
        if (!data.question) return;
        this.form = this.mapQuestionToForm(data.question);
        this.$nextTick(() => {
          this.$refs.questionFormRef &&
            this.$refs.questionFormRef.clearValidate();
        });
      },
      async handleDeleteQuestion(data) {
        try {
          await this.$confirm('确认删除该试题吗？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          });
          const message = await deleteQuestion(data.id);
          await this.loadDetail(this.bankForm.id, false);
          this.$message.success(message || '删除成功');
          this.$emit('reload');
        } catch (error) {
          if (error !== 'cancel' && error !== 'close') {
            this.$message.error(error.message || '删除失败');
          }
        }
      },
      mapQuestionToForm(question) {
        const type = questionTypeReverseMap[question.questionType] || '1';
        const options = [...(question.optionList || [])]
          .sort((a, b) => Number(a.sortNo) - Number(b.sortNo))
          .map((option, index) => ({
            key: String.fromCharCode(65 + index),
            content: option.optionContent || ''
          }));
        const correctAnswer = question.correctAnswer || '';
        return {
          id: question.id || '',
          sort: question.sortNo === undefined ? '' : String(question.sortNo),
          content: question.questionContent || '',
          type,
          category:
            question.professionalType === undefined
              ? ''
              : String(question.professionalType),
          score:
            question.questionScore === undefined
              ? ''
              : String(question.questionScore),
          options,
          rightAnswer: type === '2' ? '' : correctAnswer,
          rightAnswers:
            type === '2' ? correctAnswer.split(',').filter((item) => item) : [],
          analysis: question.questionExplanation || ''
        };
      },
      async loadDetail(questionBankId, selectFirstQuestion = true) {
        const detail = await getById(questionBankId);
        this.bankForm = {
          id: detail.id || questionBankId,
          name: detail.questionBankName || '',
          deptId: detail.departmentId || '',
          deptName: detail.departmentName || ''
        };
        const questions = [...(detail.questionList || [])].sort(
          (a, b) => Number(a.sortNo) - Number(b.sortNo)
        );
        this.questionList = questions.map((question, index) => ({
          id: question.id,
          label: `第${question.sortNo || index + 1}题`,
          question
        }));
        this.form =
          selectFirstQuestion && questions.length
            ? this.mapQuestionToForm(questions[0])
            : JSON.parse(JSON.stringify(defQuestionForm));
        this.$nextTick(() => {
          if (selectFirstQuestion && questions.length && this.$refs.treeRef) {
            this.$refs.treeRef.setCurrentKey(questions[0].id);
          } else if (this.$refs.treeRef) {
            this.$refs.treeRef.setCurrentKey(null);
          }
        });
      },
      handleReset() {
        this.form = JSON.parse(JSON.stringify(defQuestionForm));
        this.$refs.questionFormRef &&
          this.$refs.questionFormRef.clearValidate();
      },
      toNumber(value) {
        return value === '' || value === null || value === undefined
          ? undefined
          : Number(value);
      },
      buildSavePayload() {
        const isMultiple = this.form.type === '2';
        return {
          questionBankId: this.bankForm.id || undefined,
          questionBankName: this.bankForm.name,
          departmentId: this.bankForm.deptId,
          departmentName: this.bankForm.deptName,
          question: {
            questionId: this.form.id || undefined,
            sortNo: this.toNumber(this.form.sort),
            questionContent: this.form.content,
            questionType: questionTypeMap[this.form.type],
            professionalType: this.toNumber(this.form.category),
            questionScore: this.toNumber(this.form.score),
            correctAnswer: isMultiple
              ? this.form.rightAnswers.join(',')
              : this.form.rightAnswer,
            questionExplanation: this.form.analysis,
            optionList: this.form.options.map((item, index) => ({
              optionContent: item.content,
              sortNo: index + 1
            }))
          }
        };
      },
      async resolveQuestionBankId(saveResult) {
        if (
          typeof saveResult === 'number' ||
          (typeof saveResult === 'string' && /^\d+$/.test(saveResult))
        ) {
          return saveResult;
        }
        const resultId =
          typeof saveResult === 'object'
            ? saveResult.id || saveResult.questionBankId
            : undefined;
        if (resultId) {
          return resultId;
        }

        const result = await getList({
          questionBankName: this.bankForm.name,
          departmentId: this.bankForm.deptId,
          pageNum: 1,
          size: 20
        });
        const questionBank = (result.list || []).find(
          (item) =>
            item.questionBankName === this.bankForm.name &&
            String(item.departmentId) === String(this.bankForm.deptId)
        );
        if (!questionBank) {
          throw new Error('题库已保存，但未能获取题库ID');
        }
        return questionBank.id;
      },
      saveNext() {
        this.$refs.bankForm.validate((bankValid) => {
          if (!bankValid) return;
          this.$refs.questionFormRef.validate((valid) => {
            if (valid) {
              this.loading = true;
              const payload = this.buildSavePayload();
              const saveRequest = this.bankForm.id
                ? updateQuestionBank
                : saveQuestionBank;
              saveRequest(payload)
                .then(async (saveResult) => {
                  if (!this.bankForm.id) {
                    this.bankForm.id = await this.resolveQuestionBankId(
                      saveResult
                    );
                  }
                  await this.loadDetail(this.bankForm.id, false);
                  this.$message.success('保存成功');
                  this.$emit('reload');
                  this.$nextTick(() => {
                    this.$refs.questionFormRef &&
                      this.$refs.questionFormRef.clearValidate();
                  });
                })
                .catch((error) => {
                  this.$message.error(error.message || '保存失败');
                })
                .finally(() => {
                  this.loading = false;
                });
            }
          });
        });
      }
    }
  };
</script>

<style lang="scss" scoped>
  .bank-header {
    padding: 10px 15px 0;
    background-color: #f5f7fa;
    border-radius: 4px;
    margin-bottom: 15px;

    .bank-form {
      display: flex;
      justify-content: center;
      flex-wrap: wrap;
    }

    ::v-deep .el-form-item {
      margin-bottom: 10px;
    }
  }

  .maintenance-body {
    display: flex;
    max-height: calc(90vh - 260px);
    min-height: 450px;
  }

  .left-panel {
    width: 260px;
    flex-shrink: 0;
    border-right: 1px solid #ebeef5;
    padding-right: 15px;
    margin-right: 15px;

    .panel-title {
      font-size: 14px;
      font-weight: bold;
      text-align: center;
      padding: 8px 0;
      background-color: #409eff;
      color: #fff;
      border-radius: 4px 4px 0 0;
    }

    .panel-search {
      padding: 10px 0;

      ::v-deep .el-input-group__append {
        background-color: #409eff;
        color: #fff;
        border-color: #409eff;
      }
    }

    .question-node {
      display: flex;
      align-items: center;
      justify-content: space-between;
      flex: 1;
      padding-right: 8px;
    }

    .question-delete {
      color: #f56c6c;
    }
  }

  .right-panel {
    flex: 1;
    overflow-y: auto;
    padding-right: 10px;
  }

  .question-form {
    padding-top: 10px;
  }

  .danger-text {
    color: #f56c6c;
  }
</style>
