<template>
  <div class="exam-container">
    <el-card>
      <template #header>
        <page-header>
          <template #actions>
            <el-button @click="fetchExamDetail" :loading="loading.refresh">
              <el-icon><RefreshRight /></el-icon>
            </el-button>
            <el-button
                v-if="(isStudentGroup || isTeacherGroup)"
                @click="jumpToCoderOnlineExam"
            >
              在线自测
            </el-button>
            <el-button
                v-if="isTeacherGroup || isAdmin || isAssistantGroup"
                @click="checkStudentGrade"
            >
              查看学生成绩
            </el-button>
            <el-button
                v-if="isTeacherGroup || isAdmin"
                disabled
                @click="goToDetect()"
            >
              查看查重结果
            </el-button>
            <el-button
                v-if="isTeacherGroup || isAdmin"
                variant="danger"
                @click="dialog.delete = true"
            >
              删除考试
            </el-button>
          </template>
          {{ exam.name }}
        </page-header>
      </template>

      <paper>
        <el-descriptions>
          <el-descriptions-item
              label="编号:"
              label-class-name="label-bold"
          >
            {{ exam.id }}
          </el-descriptions-item>
          <el-descriptions-item
              label="创建者:"
              label-class-name="label-bold"
          >
            {{ exam.creator ? exam.creator.username : '' }}
          </el-descriptions-item>
          <el-descriptions-item
              label="创建时间:"
              label-class-name="label-bold"
          >
            {{ formatTimestamp(exam.created_at) }}
          </el-descriptions-item>
          <el-descriptions-item
              v-if="(isStudentGroup || isTeacherGroup) && exam.joined"
              :label="`${isTeacherGroup ? '自测' : ''}成绩`"
              label-class-name="label-bold"
          >
            {{ result.score }}
          </el-descriptions-item>
          <el-descriptions-item
              label="状态:"
              label-class-name="label-bold"
          >
            <el-tag size="mini" :type="statusTagType">
              {{ statusTagContent }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item
              label="起止时间:"
              :span="2"
              label-class-name="label-bold"
          >
            {{ formatTimestamp(exam.startAt) }} 至 {{ formatTimestamp(exam.endAt) }}
            <a
                v-if="isTeacherGroup || isAdmin"
                class="changeable"
                @click="dialog.update = true"
            >
              修改
            </a>
          </el-descriptions-item>
          <el-descriptions-item
              label="试卷地址:"
              :span="3"
              label-class-name="label-bold"
          >
          <span id="exam-url">
          {{ exam.url ? exam.url : '不可用' }}
        </span>
            <a
                v-if="exam.url"
                id="copy-btn"
                class="changeable"
                data-clipboard-target="#exam-url"
                @click="copyAddress"
            >
              复制
            </a>
          </el-descriptions-item>
          <el-descriptions-item
              v-if="isTeacherGroup || isAdmin"
              label="是否允许学生查看控制台:"
              :span="2"
              label-class-name="label-bold"
          >
            <span>{{ isConsoleOutputShownForStu ? "允许" : "不允许" }}</span>
            <a class="changeable" @click="dialog.console = true">
              修改
            </a>
          </el-descriptions-item>
        </el-descriptions>
      </paper>

      <el-tabs
          class="top-divide exam-detail-tabs"
          v-model="tabValue"
      >
        <el-tab-pane v-if="exam.joined" label="提交记录" name="commits">
          <el-table v-if="exam.joined" :data="result.commits">
            <el-table-column prop="id" label="#" width="80" />
            <el-table-column label="提交时间">
              <template #default="scope">
                <span>{{ formatTimestamp(scope.row.created_at) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="状态" width="180">
              <template #default="scope">
              <span>
                {{ scope.row.finished ? '运行结束' : '等待或运行中' }}
              </span>
              </template>
            </el-table-column>
            <el-table-column prop="score" label="成绩" width="120" />
            <el-table-column label="操作" width="120">
              <template #default="scope">
                <el-button
                    type="primary"
                    size="mini"
                    @click="
                    $router.push(
                    {
                      path: `/exam/${$route.params.examId}/commit/${scope.row.id}`
                    })
                "
                >
                  详情
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane
            v-if="exam.problems && exam.problems.length"
            class="problems-tab-pane"
            label="题目列表"
            name="problems"
        >
          <el-collapse accordion>
            <el-collapse-item
                v-for="problem in exam.problems"
                :key="problem.id"
                :name="problem.id"
            >
              <template #title>
                {{ problem.name }}
                <el-tag class="problem-tag">
                  {{ problemTypeToTagContent(problem.type) }}
                </el-tag>
              </template>
              <div style="display: inline;margin-right: 40px">{{ problem.description }}</div>
              <el-button
                  v-if="isTeacherGroup || isAdmin"
                  @click="jumpToProblemDetail(problem.id)"
                  style="float: right;margin-right: 40px"
                  size="small"
              >预览题目</el-button>
            </el-collapse-item>
          </el-collapse>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <el-dialog title="确认删除考试吗？" v-model="dialog.delete">
      <el-alert
          style="margin-bottom: 20px"
          title="注意：所有与该场考试有关的提交数据都将被删除！"
          type="error"
          :closable="false"
      ></el-alert>
      <el-descriptions>
        <el-descriptions-item label="考试ID：">{{ exam.id }}</el-descriptions-item>
        <el-descriptions-item label="考试名称：">{{ exam.name }}</el-descriptions-item>
      </el-descriptions>

      <template #footer class="dialog-footer">
        <el-button @click="dialog.delete = false">取消</el-button>
        <el-button
            type="danger"
            :loading="loading.delete"
            @click="deleteExam"
        >确定</el-button>
      </template>
    </el-dialog>
    <el-dialog title="修改起止时间" v-model="dialog.update" width="960px">
      <el-descriptions>
        <el-descriptions-item label="原起止时间：" :span="2">
          {{ formatTimestamp(exam.startAt) }} 至 {{ formatTimestamp(exam.endAt) }}
        </el-descriptions-item>
        <el-descriptions-item label="新起止时间：" :span="2">
          <el-date-picker
              v-model="range"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
          />
        </el-descriptions-item>
      </el-descriptions>
      <el-alert title="注意" type="warning" style="margin-top: 20px">
        <p>开始时间早于当前时间考试将立即开始</p>
        <p>开始时间晚于当前时间考试将回归未开始状态</p>
        <p>结束时间早于当前时间考试将立即结束并关闭</p>
        <p>考试关闭后将无法恢复</p>
      </el-alert>

      <template #footer class="dialog-footer">
        <el-button @click="dialog.update = false">取消</el-button>
        <el-button
            variant="primary"
            :loading="loading.update"
            :disabled="range.length !== 2"
            @click="updateExam"
        >
          确定
        </el-button>
      </template>
    </el-dialog>
    <el-dialog title="修改学生查看控制台权限" v-model="dialog.console">
      <el-descriptions>
        <el-descriptions-item label="考试ID：">{{ exam.id }}</el-descriptions-item>
        <el-descriptions-item label="考试名称：">{{ exam.name }}</el-descriptions-item>
        <el-descriptions-item label="当前控制台权限：">{{isConsoleOutputShownForStu?"":"不"}}允许学生查看控制台输出</el-descriptions-item>
      </el-descriptions>
      <template #footer class="dialog-footer">
        <el-button @click="dialog.console = false">取消</el-button>
        <el-button
            variant="primary"
            :loading="loading.console"
            @click="changeShowConsoleForStu"
        >
          确定
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import {examStatusToTagContent, examStatusToTagType, formatTimestamp, problemTypeToTagContent} from "@/utils/coder-utils";
import {mapGetters} from "vuex";
import Paper from "@/views/ProblemPage/components/Paper";
import PageHeader from "../../components/PageHeader";
import {ElMessage} from "element-plus";
import Clipboard from "clipboard";

export default {
  name: "ExamDetail",
  components: {
    Paper,
    PageHeader,
  },
  props: {
  },
  data() {
    return {
      exam: { joined: true },
      result: {},
      isConsoleOutputShownForStu: false,

      dialog: {
        update: false,
        delete: false,
        console: false
      },

      loading: {
        join: false,
        update: false,
        delete: false,
        console: false,
        refresh: false
      },

      range: [],
    };
  },
  computed: {
    ...mapGetters([
      "isStudentGroup",
      "isTeacherGroup",
      "isAdmin",
      "isAssistantGroup"
    ]),
    statusTagType(){
      return examStatusToTagType(this.exam.status);
    },
    statusTagContent(){
      return examStatusToTagContent(this.exam.status);
    },
    joinDisabled() {
      return (
          this.exam.status === "UNAVAILABLE" ||
          this.exam.status === "FINISHED" ||
          this.exam.status === "CLOSED"
      );
    },
    tabValue() {
      return this.exam.joined? "commits": "problems";
    }
  },
  mounted() {
    this.fetchExamDetail();
  },
  methods: {
    /**
     * 获取当前考试信息
     */
    fetchExamDetail() {
      this.loading.refresh = true;
      const { examId } = this.$route.params;
      this.$apis.getCoderExamByExamId(examId)
          .then(_res => {
            this.exam = _res.data.res;
            if (!this.isAdmin && this.exam.joined) {
              this.fetchResult();
            }
          }).catch(_err => {
            ElMessage.error("当前考试不存在！跳转到管理页面！");
            this.$router.push("/manage");
      });
      if (this.isTeacherGroup) {
        this.$apis.getExamIsShownForStu(examId)
            .then(_res => {
              this.isConsoleOutputShownForStu = _res.data.res ?? false;
              this.loading.refresh = false;
            }).catch(_err => {
              ElMessage.error(_err);
        });
      }
    },
    fetchResult() {
      this.$apis.getResultByResultId(this.exam.result?.id)
          .then(_res => {
            this.result = _res.data.res ?? {};
          }).catch(_err => {
            ElMessage.error(_err);
      });
    },
    formatTimestamp,
    problemTypeToTagContent,
    jumpToCoderOnlineExam() {
      ElMessage.info("跳转到coder进行在线考试");
      let nextURL = "https://coder.seec.seecoder.cn/exam/" + this.exam.id + "?id_token=" + this.$store.state.user.token;
      window.open(nextURL);
      //TODO 在Coder中设置路由拦截器，进行token解析
    },
    goToDetect() {
      // ElMessage.error("暂不支持查看查重结果");
    },
    checkStudentGrade() {
      this.$router.push(this.$route.path+"/result");
    },
    deleteExam() {
      this.loading.delete = true;
      const { examId } = this.$route.params;
      this.$apis.deleteCoderExam(examId)
          .then(_res => {
            ElMessage.success("删除考试成功");
            this.dialog.delete = false;
            this.$router.push("/manage");
          }).catch(_err => {
        ElMessage.error("删除考试失败");
      }).finally(() => {
        this.loading.delete = false;
      });
    },
    updateExam() {
      this.loading.update = true;
      const { examId } = this.$route.params;

      this.$apis.updateCoderExam(examId, {
        course: this.exam.courseId,
        startAt: this.range[0].getTime() / 1000,
        endAt: this.range[1].getTime() / 1000
      }).then(_res => {
        console.log(_res);
        this.exam = _res.data.res ?? {};
        ElMessage.success({
          message: "更新考试时间段成功！",
          center: true
        });
        this.dialog.update = false;
      }).catch(_err => {
        ElMessage.error({
          message: "更新考试时间段失败！",
          center: true
        });
      }).finally(() => {
        this.loading.update = false;
        this.range = [];
      });
    },
    copyAddress() {
      const cb = new Clipboard("#copy-btn");
      cb.on("success", (e) => {
        ElMessage.success({
          message: "已复制到剪切板！",
          center: true
        });
        e.clearSelection();
      });
      cb.on("error", (e) => {
        ElMessage.error({
          message: "浏览器不支持复制到剪贴板！",
          center: true
        });
        e.clearSelection();
      });
    },
    changeShowConsoleForStu() {
      this.loading.console = true;
      const { examId } = this.$route.params;
      const showConsoleForStu = !this.isConsoleOutputShownForStu;

      this.$apis.changeExamIsShownForStu(examId, showConsoleForStu)
          .then(_res => {
            this.isConsoleOutputShownForStu = _res.data.res ?? false;
            ElMessage.success("修改控制台权限成功！");
          }).catch(_err => {
        console.log(_err);
        ElMessage.success("修改控制台权限失败！");
      }).finally(() => {
        this.dialog.console = false;
      });
    },
    jumpToProblemDetail(problemId) {
      this.$router.push("/problem/"+problemId);
    }
  }
};
</script>

<style lang="scss" scoped>
.exam-container {
  margin: 40px 10vw 80px 10vw;
  min-height: calc(100vh - 100px);
}
.changeable {
  color: blue;
  cursor: pointer;
}

</style>
