<template>
  <div class="student-track-record">
    <div v-if="!propData" class="student-track-head box-justify">
      <h2 class="student-track-title">轨迹回放</h2>
      <el-button size="mini" icon="el-icon-arrow-left" @click="goBack"
        >返回列表</el-button
      >
    </div>

    <div class="student-track-info box-justify">
      <div class="student-track-info-left">
        <i class="icon icon-theme"></i>{{ info.examName }}
      </div>
      <div class="student-track-info-list">
        <span class="student-track-info-item">
          <span>姓名：</span>
          <span class="color-primary">{{ info.name }}</span>
        </span>
        <span class="student-track-info-item">
          <span>证件号：</span>
          <span class="color-primary">{{ info.identity }}</span>
        </span>
        <span class="student-track-info-item">
          <span>科目(代码)：</span>
          <span class="color-primary"
            >{{ info.courseName }}({{ info.courseCode }})</span
          >
        </span>
        <span class="student-track-info-item">
          <span>考试时间：</span>
          <span class="color-primary">{{
            info.firstStartTime | datetimeFilter
          }}</span>
        </span>
      </div>
    </div>

    <div class="student-track-body">
      <el-row :gutter="40" type="flex">
        <el-col :span="12">
          <div class="warning-track">
            <h3 class="warning-track-title">
              <i class="icon icon-track"></i>考试轨迹
            </h3>
            <div
              class="warning-track-item"
              v-for="log in examStudentLogList"
              :key="log.id"
            >
              <div
                :class="[
                  'warning-track-type',
                  log.viewType === 'common' ? 'type-common' : 'type-exception',
                ]"
              >
                <i :class="['icon', `icon-track-${log.viewType}`]"></i>
              </div>
              <div class="warning-track-body">
                <div class="warning-track-info">
                  <div class="warning-track-info-title">
                    <template v-if="log.type === 'BREACH_HANDLE'">
                      <span v-if="log.breachLogStatus">已撤销</span>
                    </template>
                    <h3>{{ log.title }}</h3>
                    <b
                      v-if="log.ipChange"
                      :class="{ 'color-danger': log.ipChange }"
                      >[ip变动]</b
                    >
                  </div>
                  <template v-if="log.desc">
                    <template v-if="log.type === 'MESSAGE'">
                      <p v-if="log.msgType === 'AUDIO'">
                        <audio
                          class="qm-audio"
                          :src="log.content"
                          controls
                        ></audio>
                      </p>
                      <template v-else-if="log.msgType === 'MEDIA'">
                        <p v-for="(cont, index) in log.desc" :key="index">
                          {{ cont }}
                        </p>
                      </template>
                      <p v-else>{{ log.desc }}</p>
                    </template>
                    <p v-else>{{ log.desc }}</p>
                    <p v-if="log.formUserName">
                      发送人：{{ log.formUserName }}
                    </p>
                  </template>
                  <p v-if="log.endTime">
                    时间段：
                    <span v-if="log.startTime">{{ log.startTime }} ~ </span>
                    <span>{{ log.endTime }}</span>
                  </p>
                  <p v-if="log.durationTime">
                    持续时长约：{{ log.durationTime }}
                  </p>
                  <p v-if="log.ip" :class="{ 'color-danger': log.ipChange }">
                    ip：{{ log.ip }}，属地：{{ log.province }}{{ log.city }}
                  </p>
                </div>
                <ul class="warning-track-media" v-if="log.photos">
                  <li v-for="(photo, pindex) in log.photos" :key="pindex">
                    <img :src="photo" @click="toViewImg(photo)" />
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </el-col>
        <el-col :span="12">
          <el-form inline>
            <el-form-item>
              <el-select v-model="filter.monitorRecord" placeholder="视频源">
                <el-option
                  v-for="item in monitorRecordList"
                  :key="item.code"
                  :value="item.code"
                  :label="item.name"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="toPage(1)">查询</el-button>
            </el-form-item>
          </el-form>
          <table class="table">
            <tr>
              <th>录制起点</th>
              <th>录制终点</th>
              <th>操作</th>
            </tr>
            <tr v-for="item in videoRocordList" :key="item.videoUrl">
              <td>{{ item.startTime | datetimeFilter }}</td>
              <td>{{ item.endTime | datetimeFilter }}</td>
              <td class="td-link">
                <span @click="toDetail(item)">视频回放</span>
              </td>
            </tr>
          </table>
          <div class="part-page">
            <el-pagination
              background
              layout="prev, pager, next,total,sizes,jumper"
              :current-page="current"
              :total="total"
              :page-size.sync="size"
              @size-change="toPage(1)"
              @current-change="toPage"
            >
            </el-pagination>
          </div>
        </el-col>
      </el-row>
    </div>

    <!-- image-preview -->
    <simple-image-preview
      :cur-image="curImage"
      ref="SimpleImagePreview"
    ></simple-image-preview>
    <!-- StudentMonitorRecordDialog -->
    <student-monitor-record-dialog
      ref="StudentMonitorRecordDialog"
      :videoSource="curVideoSource"
      @video-ended="videoEnded"
    ></student-monitor-record-dialog>
  </div>
</template>

<script>
import { VIDEO_SOURCE_TYPE } from "@/constant/constants";
import { searchStudentTrackRecord } from "@/api/examwork-student";
import SimpleImagePreview from "@/components/imagePreview/SimpleImagePreview";
import StudentMonitorRecordDialog from "./StudentMonitorRecordDialog";
import {
  formatDate,
  timeNumberToText,
  objTypeOf,
  objAssign,
} from "@/utils/utils";

export default {
  name: "StudentTrackRecord",
  components: { SimpleImagePreview, StudentMonitorRecordDialog },
  props: {
    propData: {
      type: Object,
      default: null,
    },
  },
  data() {
    return {
      filter: {
        examRecordId: "",
        monitorRecord: "",
        log: true,
      },
      info: {
        examId: "",
        examName: "",
        examStudentId: "",
        examRecordId: "",
        courseCode: "",
        courseName: "",
        identity: "",
        name: "",
        firstStartTime: null,
      },
      VIDEO_SOURCE_TYPE,
      monitorRecordList: [],
      videoRocordList: [],
      current: 1,
      total: 0,
      size: 24,
      examStudentLogList: [],
      curImage: { imgSrc: "" },
      curVideoSource: {},
    };
  },
  mounted() {
    let studentTrackMonitorRecord = null;
    if (this.propData) {
      this.filter.examRecordId = this.propData.examRecordId;
      studentTrackMonitorRecord = this.propData.monitorRecord;
    } else {
      this.filter.examRecordId = this.$route.params.examRecordId;
      studentTrackMonitorRecord = window.sessionStorage.getItem(
        "studentTrackMonitorRecord"
      );
    }

    if (!studentTrackMonitorRecord) {
      this.$message.error("数据丢失，请退出本页");
      return;
    }
    this.monitorRecordList = studentTrackMonitorRecord
      .split(",")
      .map((item) => {
        return {
          name: VIDEO_SOURCE_TYPE[item],
          code: item,
        };
      });
    this.filter.monitorRecord = this.monitorRecordList[0].code;
    this.initData();
  },
  methods: {
    async initData() {
      await this.getList();
      this.filter.log = false;
    },
    async getList() {
      const datas = {
        ...this.filter,
        pageNumber: this.current,
        pageSize: this.size,
      };

      const res = await searchStudentTrackRecord(datas);
      this.info = objAssign(this.info, res.data.data);

      const { records, total } =
        res.data.data.teStudentExamRecordVideoMessageIPage;
      this.videoRocordList = records;
      this.total = total;

      if (datas.log) {
        this.examStudentLogList = this.parseStudentLogs(
          res.data.data.teExamStudentLogList
        );
      }
    },
    toPage(page) {
      this.current = page;
      this.getList();
    },
    parseStudentLogs(examStudentLogList) {
      const statusTypes = {
        common: [
          "FIRST_START",
          "RESUME_START",
          "IN_PROCESS",
          "PREPARE",
          "ANSWERING",
          "BREAK_OFF",
          "RESUME_PREPARE",
          "FINISHED",
          "FIRST_PREPARE",
        ],
        warning: [
          "FACE_COUNT_ERROR",
          "FACE_COMPARE_ERROR",
          "EYE_CLOSE_ERROR",
          "LIVENESS_ACTION_ERROR",
          "REALNESS",
          "NONE",
          // exception:
          "NET_TIME_OUT",
          "MACHING_STOP",
          "NET_TIME_BREAK",
          "SOFTWARE_STOP",
          "POWER_CUT",
          "BREACH_HANDLE",
          "BREACH_REVOKE",
          "OTHER",
        ],
      };
      const transformInfo = {
        FIRST_START: "身份识别",
        ANSWERING: "进入考试",
        RESUME_START: "身份识别",
      };
      let statusTypeMap = {};
      Object.keys(statusTypes).map((k) => {
        statusTypes[k].map((item) => {
          statusTypeMap[item] = k;
        });
      });
      const dateTimeFormat = "YYYY/MM/DD HH:mm:ss";

      const logs = examStudentLogList.map((item) => {
        let info = { ...item };
        info.endTime = formatDate(dateTimeFormat, new Date(info.createTime));
        info.viewType = statusTypeMap[info.type] || "common";
        // 文字消息提示
        if (info.msgType) {
          info.type = "MESSAGE";
          info.title = info.msgTypeStr;
          if (info.msgType === "MEDIA") {
            info.endTime = null;
            info.desc = info.content.split("\r\n");
          } else {
            info.desc = info.content;
          }
          return info;
        }
        const content = info.info.split(/【|】/);
        if (content.length === 3) {
          info.title = content[1];
          info.desc = content[2];
        } else {
          info.title = transformInfo[info.type] || content[0];
        }
        if (info.title.trim() === "断点续考") {
          info.desc = info.remark;
        }
        if (info.remark && info.remark.includes('{"')) {
          info.remark = JSON.parse(info.remark);
          if (info.remark["MIN_CREATE_TIME"]) {
            info.startTime = formatDate(
              dateTimeFormat,
              new Date(info.remark["MIN_CREATE_TIME"])
            );
            info.durationTime = timeNumberToText(
              info.createTime - info.remark["MIN_CREATE_TIME"]
            );
          }

          let photos = [];
          Object.keys(info.remark).map((key) => {
            if (key.includes("PHOTO")) {
              const kPhotos =
                objTypeOf(info.remark[key]) === "array"
                  ? info.remark[key]
                  : [info.remark[key]];
              photos = [...photos, ...kPhotos];
            }
          });
          info.photos = photos;
        } else if (info.updateTime) {
          info.startTime = formatDate(
            dateTimeFormat,
            new Date(info.createTime)
          );
          info.endTime = formatDate(dateTimeFormat, new Date(info.updateTime));
          info.durationTime = timeNumberToText(
            info.updateTime - info.createTime
          );
        }

        // 撤销违纪的特别处理
        if (item.type === "BREACH_HANDLE" && item.title.includes('{"')) {
          const tinfo = JSON.parse(item.title);
          info.breachLogStatus = tinfo.breachLogStatus;
        }
        return info;
      });
      return logs;
    },
    toViewImg(photo) {
      this.curImage = { imgSrc: photo };
      this.$refs.SimpleImagePreview.open();
    },
    toDetail(row) {
      this.curVideoSource = row;
      this.$refs.StudentMonitorRecordDialog.open();
    },
    videoEnded(videoSource) {
      const pos = this.videoRocordList.findIndex(
        (item) => item.videoUrl === videoSource.videoUrl
      );
      if (pos >= this.videoRocordList.length - 1) return;
      this.curVideoSource = this.videoRocordList[pos + 1];
      this.$message.info("即将播放下一个视频！");
    },
    goBack() {
      window.history.go(-1);
    },
  },
};
</script>
