<template>
  <el-row :gutter="20">
    <el-col :span="6">
      <el-card>
        <template #header>
          <div>
            <span>考生信息</span>
          </div>
        </template>
        <p v-for="(userItem, userIndex) in userInfo" :key="userIndex">
          <template v-if="userItem.type === 'datetimerange'">
            <div>
              <span>{{ userItem.label }}:</span>
              <span>{{ _.join(userData[userItem.prop], "——") }}</span>
            </div>
          </template>
          <template v-else-if="userItem.type === 'text'">
            <div>
              <span>{{ userItem.label }}:</span>
              <span>{{ userData[userItem.prop] }}</span>
            </div>
          </template>
          <template v-else-if="userItem.type === 'img'">
            <div>
              <span>{{ userItem.label }}:</span>
              <el-image style="width: 20px; height: 20px;" :src="userData[userItem.prop]"
                v-if="_.trim(userData[userItem.prop])" fit="fill" :preview-src-list="[userData[userItem.prop]]"
                preview-teleported>
              </el-image>
              <span v-else></span>
            </div>
          </template>
        </p>
        <template #footer>
          <el-button type="primary" @click="connectTeacher">联系老师</el-button>
          <el-button type="primary" @click="startExam">考前检测</el-button>
          <el-button type="primary" @click="startCheckExam">开始考试</el-button>
          <el-button type="primary" @click="stopCheckExam">结束考试</el-button>
        </template>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card>
        <template #header>
          <div>
            <span>实时作弊信息</span>
            <!-- <el-button type="primary" @click="getzuobiList">获取作弊信息</el-button> -->
          </div>
        </template>
        <p v-for="(zuobiItem, zuobiIndex) in zuobiPList" :key="zuobiIndex">
          <span>
            {{ zuobiItem.label }}
          </span>:
          <span>
            {{ (zuobiObj[zuobiItem.prop] || []).length }}
          </span>
        </p>
      </el-card>
      <el-card>
        <template #header>
          <div>
            <span>作弊饼状图</span>
            <!-- <el-button type="primary" @click="getzuobiList">获取作弊信息</el-button> -->
          </div>
        </template>
        <div id="studentZuobiEcharts"></div>
      </el-card>
    </el-col>
    <el-col :span="12">
      <video ref="videoEL" class="canvasClass" playsinline></video>
    </el-col>
  </el-row>
</template>
<script>
import * as echarts from 'echarts';
import _ from "lodash";
import {
  getUser, //获取user信息
  startCheck,//开始检测
  stopCheck,//停止检测
  getzuobi,//获取作弊信息
} from "@/api/student";
import { ElMessage, ElMessageBox } from 'element-plus'
import io from 'socket.io-client';
export default {
  name: "student",
  components: {},
  data() {
    return {
      _: _,
      userId: "",
      // 学生姓名、学号,考试类型、考试科目、考试时间段
      userInfo: [
        {
          label: "学校名称",
          prop: "xuexiaomingcheng",
          type: "text"
        },
        {
          label: "学校代号",
          prop: "xuexiaodaihao",
          type: "text"
        },
        {
          label: "专业名称",
          prop: "zhuanyemingcheng",
          type: "text"
        },
        {
          label: "专业代号",
          prop: "zhuanyedaihao",
          type: "text"
        },
        {
          label: "年级",
          prop: "nianji",
          type: "text"
        },
        {
          label: "班级",
          prop: "banji",
          type: "text"
        },
        {
          label: "学生姓名",
          prop: "xueshengxingming",
          type: "text"
        },
        {
          label: "学号",
          prop: "xuehao",
          type: "text"
        },
        {
          label: "考生图片",
          prop: "kaoshengtupian",
          type: "img"
        },
        {
          label: "考试类型",
          prop: "kaoshileixing",
          type: "text"
        },
        {
          label: "考试科目",
          prop: "kaoshikemu",
          type: "text"
        },
        {
          label: "考试时间段",
          prop: "kaoshishijianduan",
          type: "datetimerange"
        },
      ],
      userData: {},
      socket: null,
      zuobiPList: [
        {
          label: "提问次数",
          prop: "qustion"
        },
        {
          label: "回答次数",
          prop: "answer"
        },
        {
          label: "讲话次数",
          prop: "talk"
        },
        {
          label: "举手次数",
          prop: "jushou"
        }
      ],
      zuobiList: [],
      zuobiObj: {},
      zuobiInterval: null,
      studentEcharts: null,
    };
  },
  watch: {},
  computed: {},
  async mounted() {
    this.userId = _.get(this.$route, ["params", "id"], "")
    await this.getUser()
    await this.initWebSocket();
    let echartsDom = document.getElementById('studentZuobiEcharts');
    this.studentEcharts = echarts.init(echartsDom)
    this.zuobiInterval = setInterval(async () => {
      await this.getzuobiList()
    }, 3000);

  },
  methods: {
    async getUser() {
      let res = await getUser({
        id: this.userId
      })
      this.userData = res.list[0]
    },
    async initWebSocket() {
      this.socket = io('http://localhost:5000/ws/video', { query: { id: this.userId, isAdmin: "0" } }); // 替换为你的后端服务器地址
      this.socket.on('connect', () => {
        console.log('Connected to server');
      });
      console.log(78444, `studentMsg${this.userId}`)
      this.socket.on(`studentMsg${this.userId}`, (data) => {
        console.log(78875454477, data)
        let msg = _.get(data, ['data'], "")
        let answer = _.split(msg, "@@@")
        ElMessage({
          message: `老师回答:${answer[1]}`,
          type: "success",
        });
        // 在这里处理接收到的学生端谈话信息
      });
    },
    async connectTeacher() {
      ElMessageBox.prompt(``, `提出疑问`, {
        confirmButtonText: '发送',
        cancelButtonText: '取消'
      })
        .then(({ value }) => {
          this.socket.emit('sendMsg', { userId: this.userId, data: value });
          ElMessage({
            type: 'success',
            message: `已提出疑问:${value}`,
          })
        })
        .catch(() => {
        })
    },
    // 开始检测
    async startCheckExam() {
      startCheck()
    },
    // 考试结束
    async stopCheckExam() {
      stopCheck()
      this.stopVideoStream()
      this.closeWebSocket()
    },
    async startExam() {
      let that = this
      if ('webkitSpeechRecognition' in window) {
        console.log("Speech Recognition Supported");
        // 创建一个新的SpeechRecognition对象
        let recognition = new webkitSpeechRecognition();
        // 设置语言,例如中文('zh-CN')
        recognition.lang = 'zh-CN';
        // 是否连续听写,默认为false, 连续为true
        recognition.continuous = false;
        // 是否在结果中包含中间的识别结果,默认为false
        recognition.interimResults = false;
        // 开始监听语音输入
        recognition.start();
        // 当有语音识别结果时触发此事件
        recognition.onresult = function (event) {
          let result = event.results[event.results.length - 1][0].transcript;
          console.log('用户说了: ' + result);
          ElMessage({
            message: `您正在说说:${result}`,
            type: "error",
          });
          that.socket.emit('talk', { userId: that.userId, data: result });
          // 在这里处理识别到的文字,比如显示在页面上或执行其他操作
        };
        // 如果语音识别服务遇到错误,会触发此事件
        recognition.onerror = function (event) {
          console.error('语音识别错误:', event.error);
        };
        // 用户结束说话后停止监听
        recognition.onend = function () {
          console.log('语音识别已停止');
          // 可根据需要决定是否重新开始监听
          recognition.start();
        };
      }
      try {
        let device = {}
        let devices = await navigator.mediaDevices.enumerateDevices()
        for (let key in devices) {
          if (devices[key].kind === 'videoinput') {
            device = devices[key]
            break
          }
        }
        let stream = await navigator.mediaDevices.getUserMedia({
          audio: false,
          video: {
            sourceId: device.deviceId, // 把对应的 摄像头ID 放到这里
            width: 600,
            height: 600,
          }
        })
        // 摄像头开启成功
        this.$refs['videoEL'].srcObject = stream
        this.$refs['videoEL'].play()
        this.sendVideoFrames();
      } catch (error) {
        ElMessage.error(`摄像头开启失败,请检查摄像头是否可用!${error}`)
      }
    },
    sendVideoFrames() {
      let that = this
      let video = this.$refs['videoEL'];
      let canvas = document.createElement('canvas');
      let ctx = canvas.getContext('2d');
      canvas.width = video.offsetWidth;
      canvas.height = video.offsetHeight;
      let sendFrame = () => {
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        let dataURL = canvas.toDataURL('image/jpeg', 0.3);
        that.socket.emit('video', { userId: this.userId, data: dataURL });
      };
      setInterval(sendFrame, 1000 / 30); // 30 FPS
    },
    stopVideoStream() {
      if (this.videoStream) {
        this.videoStream.getTracks().forEach(track => track.stop());
      }
    },
    closeWebSocket() {
      if (this.socket && this.socket.connected) {
        this.socket.disconnect();
      }
    },
    // 获取作弊信息
    async getzuobiList() {
      let res = await getzuobi()
      this.zuobiList = res.list
      this.zuobiObj = _.groupBy(this.zuobiList, 'type')
      console.log(78444, this.zuobiObj)
      let dataLocal = []
      for (let key in this.zuobiObj) {
        let value = this.zuobiObj[key]
        dataLocal.push({
          value: value.length,
          name: key
        })
      }
      let option = {
        tooltip: {
          trigger: 'item'
        },
        legend: {
          top: '1%',
          left: 'center'
        },
        series: [
          {
            name: '作弊次数',
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
            itemStyle: {
              borderRadius: 10,
              borderColor: '#fff',
              borderWidth: 2
            },
            label: {
              show: false,
              position: 'center'
            },
            emphasis: {
              label: {
                show: true,
                fontSize: 40,
                fontWeight: 'bold'
              }
            },
            labelLine: {
              show: false
            },
            data: dataLocal
          }
        ]
      };
      this.studentEcharts.setOption(option)
    }
  },
  beforeUnmount() {
    this.stopVideoStream();
    this.closeWebSocket();
    clearInterval(this.zuobiInterval)
  },
};
</script>
<style scoped>
.canvasClass {
  position: relative;
  width: 600px;
  height: 600px;
}

#studentZuobiEcharts {
  width: 400px;
  height: 400px;
}
</style>