<template>
  <div>
    <Header @confirmExit="confirmExit"></Header>
    <Transition :enter-active-class="proxy?.animate.dialog.enter" :leave-active-class="proxy?.animate.dialog.leave">
      <div class="time" v-show="[42].includes(examState)">
        {{
          countdownNumFormat
        }}
      </div>
    </Transition>
    <div class="main">
      <template v-if="isLongRun">
        <!--长跑-->
        <swiper :slides-per-view="testListArr.length >= 2 ? 2 : 1" :slides-per-group="testListArr.length >= 2 ? 2 : 1"
          :space-between="20" :speed="1200" :modules="[Navigation]"
          :navigation="{ prevEl: '.swiper-button-prev', nextEl: ' .swiper-button-next' }">
          <swiper-slide v-for="(items, indexs) in testListArr" :key="indexs">
            <div class="main-left main-left2">
              <div class="trackItem">
                <TransitionGroup :enter-active-class="proxy?.animate.run.enter">
                  <div v-for="(item, index) in items" :key="indexs + '_' + index" class="li">
                    <div class="left">
                      <div class="track">{{ (index + 1) + (8 * indexs) }}</div>
                      <div class="userInfo" @click="getChooseStudent(item.track)">
                        <div class="pic pic2" v-if="item.student_id"><img :src="item.face_pic || item.logo_url" /></div>
                        <div class="pic" v-else>
                          <img src="@/assets/images/test/profilePicture.png" />
                        </div>
                        <div class="nameBox">
                          <div class="name">{{ item.student_name || "未检录" }}</div>
                        </div>
                      </div>
                    </div>
                    <div class="scoreBox">
                      <div v-if="item.timeStr" class="score">
                        {{ item.timeStr || "-" }}
                      </div>
                      <div v-if="item.student_id && [3, 42].includes(examState)" class="turns">
                        <span><i>{{ item.times !=
                          undefined ?
                          item.times.length : 0 }}</i></span>圈
                      </div>
                    </div>
                    <div class="menuBtn menuBtn2" v-if="examState == 43 && item.student_id">等待开始测试</div>
                    <div class="menuBtn menuBtn2" v-if="examState == 42 && item.student_id && !item.isfinish">正在测试</div>
                    <div class="menuBtn" v-if="examState == 3 && !item.timeStr && item.isfinish && item.student_id">异常
                    </div>
                    <div class="close" @click="close(item)" v-if="examState == 41"></div>
                  </div>
                </TransitionGroup>
              </div>
            </div>
          </swiper-slide>
        </swiper>
        <!-- 如果需要导航按钮 -->
        <div v-show="testListArr.length > 2" class="swiper-button-prev swiper-btn swiper-btn-left" slot="button-prev">
        </div>
        <div v-show="testListArr.length > 2" class="swiper-button-next swiper-btn swiper-btn-right" slot="button-next">
        </div>
      </template>
      <template v-else>
        <!--短跑-->
        <div class="main-left">
          <div class="trackItem">
            <TransitionGroup :enter-active-class="proxy?.animate.run.enter">
              <div v-for="(item, index) in faceStudentList" :key="index" class="li">
                <div class="left">
                  <div class="track">{{ item.track }}</div>
                  <div class="userInfo" @click="getChooseStudent(item.track)">
                    <div class="pic pic2" v-if="item.student_id"><img :src="item.face_pic || item.logo_url" /></div>
                    <div class="pic" v-else>
                      <img src="@/assets/images/test/profilePicture.png" />
                    </div>
                    <div class="nameBox">
                      <div class="name">{{ item.student_name || "未检录" }}</div>
                    </div>
                  </div>
                </div>
                <div class="scoreBox">
                  <div v-if="item.timeStr" class="score">
                    {{ item.timeStr || "-" }}
                  </div>
                  <div v-if="isBackRun && item.student_id" class="turns">
                    往返次数:<span><i>{{ item.turns || "0"
                    }}</i></span>
                  </div>
                </div>
                <div class="menuBtn" v-if="(examState == 41 || examState == 43) && !item.student_id"
                  @click="getChooseStudent(item.track)">检录</div>
                <div class="menuBtn" v-if="(examState == 41 || examState == 43) && item.student_id"
                  @click="getRetestTrackFace(item.track)">
                  重新识别
                </div>
                <div class="menuBtn menuBtn2" v-if="examState == 43 && item.student_id">等待开始测试</div>
                <div class="menuBtn menuBtn2" v-if="examState == 42 && item.student_id">正在测试</div>
                <div class="menuBtn" v-if="examState == 3 && !item.timeStr && item.isfinish && item.student_id">异常</div>
              </div>
            </TransitionGroup>
          </div>
        </div>
        <div class="main-right">
          <ReportList ref="reportListRef" :parameter="parameter" :showQRCode="true" />
        </div>
      </template>
    </div>
    <!-- <div>当前状态：({{ examState == 3 ? "初始化完成" : examState == 40 ? "创建测试" : examState == 41 ? "正在人脸识别":examState ==43 ? "停止人脸识别" : examState == 42 ? "正在测试" : "请初始化" }})</div> -->
    <div class="footerBtn">
      <template v-if="needStart">
        <div class="btn" @click="getChooseStudent()" v-if="examState == 41 && isLongRun">检录</div>
        <!-- <div class="btn" @click="getStopFace" v-if="examState == 41">停止识别</div> -->
        <!-- <div class="btn startBtn" @click="getStartOneTest" v-if="examState == 43">开始测试</div> -->
      </template>
      <template v-else> </template>
      <div class="btn startBtn" @click="getStopFaceStartOneTest" v-if="examState == 41 || examState == 43">开始测试</div>
      <div class="btn" @click="getOpenOneTestAndStartFace" v-if="(examState == 3 || examState == 40) && resultId">下一组
      </div>
      <div class="btn" @click="getConfirmEnd" v-if="examState == 42">结 束</div>
      <div class="btn" @click="getAgain" v-if="showTestAgain">再测一次</div>
      <div class="btn" @click="getRetestFace" v-if="examState == 43">重新识别</div>
      <div class="btn exitBtn" @click="confirmExit" v-if="examState != 0">退 出</div>
    </div>
    <ChooseStudent ref="chooseStudentRef" :selectType="isLongRun ? 'multiple' : 'single'" @returnData="returnStudent" />
  </div>
</template>

<script setup name="TrainTest" lang="ts">
import { clearInterval, clearTimeout, setInterval, setTimeout } from 'worker-timers';
import { useWs } from '@/utils/trainWs';
import { initSpeech, speckText, playMusic, controlMusic, speckCancel, chineseNumber } from '@/utils/speech';
import dayjs from 'dayjs';
import dataDictionary from '@/utils/dataDictionary';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Navigation } from 'swiper/modules';
import 'swiper/css';
import 'swiper/scss/navigation';
const {
  initWs,
  examEnds,
  openOneTest,
  startFace,
  stopFace,
  faceConfirmOnly,
  startOneTest,
  finishOneTest,
  closeOneTest,
  suspendFaceRecognitionChannels,
  resumeFaceRecognitionChannels
} = useWs();
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const chooseStudentRef = ref();
const reportListRef = ref();
const data = reactive<any>({
  timerManager: {}, //计时器管理
  parameter: {}, //参数
  time: {
    testTime: 0, //时长
    countdownNum: 0 //计时
  },
  userInfo: {}, //用户信息
  examState: 0, //当前状态
  resultId: null, //测试ID
  unit: '', //单位
  needStart: false, //是否需要按钮
  faceStudentList: [], //跑道和人信息
  currentTrack: null, //当前跑道
  showTestAgain: false, //再测一次按钮
  isLongRun: false, //是否为长跑项目
  isBackRun: false, //是否为折返跑项目
  sid: null //WS的id
});
const {
  timerManager,
  parameter,
  time,
  userInfo,
  examState,
  resultId,
  faceStudentList,
  currentTrack,
  unit,
  needStart,
  showTestAgain,
  isLongRun,
  isBackRun,
  sid
} = toRefs(data);

/**
 * 接收消息
 */
const getMessage = (e: any) => {
  //console.log("WS响应：", e)
  //获取sid
  if (e.cmd === 'mySid') {
    console.log('e.data.sid', e.data.sid);
    sid.value = e.data.sid;
  }
  //实时状态
  if (e.cmd === 'exam_status') {
    examState.value = e.data;
  }
  //工作站状态
  if (e.cmd === 'init_result') {
    // if (isLongRun.value) {
    //   let num = 80;
    //   let list: any = [];
    //   for (let i = 1; i <= num; i++) {
    //     list.push({ track: i });
    //   }
    //   faceStudentList.value = list
    // }
  }

  //获取跑道配置
  if (e.cmd === 'exam_config') {
    if (isLongRun.value) {
      return false;
    }
    let num = e.data.num_of_tracks;
    let list: any = [];
    for (let i = 1; i <= num; i++) {
      list.push({ track: i });
    }
    faceStudentList.value = list;
  }

  //测试违规
  if (e.cmd === 'warning_result') {
  }
  //后端播报语音
  if (e.cmd === 'return_audio_msg') {
  }
  //错误提示
  if (e.cmd === 'info_result') {
    proxy?.$modal.msgError(e.data.message);
  }
  //错误提示
  if (e.cmd === 'error_result') {
    proxy?.$modal.msgError(e.data.message);
  }
  //测试中违规提示
  if (e.cmd === 'warning_notify') {
  }
  //断线状态
  if (e.cmd === 'disconnect_request') {
    let message = e.data.message;
    if (message) {
      proxy?.$modal.msgError(`${message}`);
      speckText(message);
    }
    getExit();
  }
  //状态变更
  if (e.cmd === 'set_exam_state') {
    examState.value = e.data;
    if (e.data === 3) {
      initProject();
      if (!isLongRun.value && showTestAgain.value) {
        reportListRef.value.getIniReportList();
      }
    }
    if (e.data === 40) {
      cleanData();
    }
    if (e.data == 41) {
    }
    if (e.data == 43) {
    }
    if (e.data == 42) {
    }
  }
  //新建测试后返回信息，获取result_id
  if (e.cmd === 'open_one_test_ack') {
    resultId.value = e.data.result_id;
  }
  //人脸识别状态
  if (e.cmd === 'face_check_result') {
    let obj = e.data[0];
    currentTrack.value = obj.track;
    returnStudent(obj);
  }
  //测试结束结果
  if (e.cmd === 'oneresult') {
    if (e?.data) {
      let data = e.data;
      getAchievement(data);
    }
  }
  //结果生成完成（视频图片）
  if (e.cmd === 'static_urls_finished') {
  }
  //选择学生或测试结束后返回的数据
  if (e.cmd === 'result_info') {
  }
};

/**
 * 开始识别
 */
const getOpenOneTestAndStartFace = async () => {
  showTestAgain.value = false;
  if (examState.value > 3) {
    await closeOneTest();
  }
  await openOneTest();
  await startFace();
};

/**
 * 停止人脸识别
 */
const getStopFace = async () => {
  if (examState.value != 41) {
    return false;
  }
  let list = faceStudentList.value.filter((item: any) => {
    return item.student_id;
  });
  if (!list.length) {
    proxy?.$modal.msgWarning('请选择人员！');
    return false;
  }
  await stopFace();
  await getFaceConfirmOnly();
};

/**
 * 确定人脸信息
 */
const getFaceConfirmOnly = (data?: any) => {
  let list = [];
  if (data) {
    faceStudentList.value = data;
    list = data.filter((item: any) => {
      return item.student_id;
    });
  } else {
    list = faceStudentList.value.filter((item: any) => {
      return item.student_id;
    });
  }
  //短跑播报跑道
  if (data && !isLongRun.value) {
    let speechList = list
      .map((item: any) => {
        return `第${item.track == 2 ? '二' : item.track}道, ${item.student_name}`;
      })
      .join();
    speckText(speechList);
  }
  //长跑自动拼接跑道
  if (isLongRun.value) {
    list = list.map((item: any, index: any) => {
      item.track = index + 1;
      return item;
    });
  }
  //重组数据
  list = list.map((item: any) => {
    let obj = {
      result_id: item.result_id,
      student_id: item.student_id,
      student_name: item.student_name,
      gender: item.gender,
      track: item.track
    };
    return obj;
  });
  faceConfirmOnly(list, () => { });
  return new Promise((resolve) => setTimeout(resolve, 200));
};

/**
 * 重新识别
 */
const getRetestFace = () => {
  proxy?.$modal
    .confirm('确定重新识别吗？')
    .then(() => {
      if (needStart.value == false) {
        // //自动流程项目重新识别直接返回3
        // closeOneTest();
        cleanData();
        startFace();
      } else {
        //手动流程项目重新识别43返回41,42返回3
        if (examState.value == 43) {
          cleanData();
          startFace();
        } else {
          closeOneTest();
        }
      }
    })
    .finally(() => { });
};

/**
 * 停止人脸并开始测试
 */
const getStopFaceStartOneTest = async () => {
  if (examState.value == 41) {
    await getStopFace();
    await getStartOneTest();
  } else {
    await getStartOneTest();
  }
};

/**
 * 开始测试
 */
const getStartOneTest = () => {
  if (examState.value != 43) {
    return false;
  }
  let list = faceStudentList.value.filter((item: any) => {
    return item.student_id;
  });
  if (!list.length) {
    proxy?.$modal.msgWarning('请选择人员！');
    return false;
  }
  //停止播报;
  speckCancel();
  //和工作站搭配时差版
  let advanceTime = 0; //提前发送开始的时间
  let myTime = 0; //枪声时间
  let myText = ''; //提示框内容
  if (isLongRun.value) {
    //音频时长5668毫秒,4480毫秒是播枪声
    advanceTime = 1000;
    myTime = 4480;
    myText = '各就位!';
  } else {
    //音频时长7010毫秒,5260毫秒是播枪声
    advanceTime = 1000;
    myTime = 5260;
    myText = '各就位，预备!';
  }
  let loading = ElLoading.service({ text: myText, background: 'rgba(0, 0, 0, 0.8)', customClass: `sports ${parameter.value.project}` });
  speckText(myText);
  setTimeout(() => {
    startOneTest(data == null, () => { });
    loading?.close();
  }, advanceTime);
  setTimeout(() => {
    //显示再测一次按钮
    showTestAgain.value = true;
    //计时项目才开
    if (needStart.value == true) {
    }
    //时间为0的为正计时，大于0的为倒计时
    if (time.value.testTime == 0) {
      getCounting('+');
    } else {
      getCounting('-');
    }
  }, myTime);

  // 立即开版本
  // startOneTest(data == null, () => {
  //   //显示再测一次按钮
  //   showTestAgain.value = true;
  //   //计时项目才开
  //   if (needStart.value == true) {
  //     //时间为0的为正计时，大于0的为倒计时
  //     if (time.value.testTime == 0) {
  //       getCounting("+");
  //     } else {
  //       getCounting("-");
  //     }
  //   } else {
  //     speckText("请开始测试");
  //   }
  // })
};

/**
 * 再测一次
 */
const getAgain = async () => {
  let txt = '是否再测一次？';
  await proxy?.$modal.confirm(txt);
  getClearTimer();
  speckCancel(); //停止播报;
  let loading = ElLoading.service({ text: '请稍等...', background: 'rgba(0, 0, 0, 0.8)', customClass: `sports ${parameter.value.project}` });
  //预存测试人员
  let student = faceStudentList.value.map((item: any) => {
    let obj = {
      face_pic: item.face_pic,
      student_id: item.student_id,
      student_name: item.student_name,
      gender: item.gender,
      track: item.track
    };
    return obj;
  });
  //测试中
  if (examState.value == 42) {
    await finishOneTest();
  }
  //其他状态
  if ([43, 41, 40].includes(examState.value)) {
    await closeOneTest();
  }
  //重新走一次流程
  await openOneTest();
  await startFace();
  await stopFace();
  await getFaceConfirmOnly(student);
  showTestAgain.value = false;
  loading?.close();
  let loadingTime = setTimeout(() => {
    loading?.close();
    clearTimeout(loadingTime);
  }, 10000);
};

/**
 * 确认退出
 */
const getConfirmEnd = async () => {
  let txt = '是否结束';
  await proxy?.$modal.confirm(txt);
  getClearTimer(); //清除计时器
  speckCancel(); //停止播报;
  let loading = ElLoading.service({ text: '请稍等...', background: 'rgba(0, 0, 0, 0.8)', customClass: `sports ${parameter.value.project}` });
  let loadingTime = setTimeout(() => {
    proxy?.$modal.msgWarning('操作超时');
    loading?.close();
    clearTimeout(loadingTime);
  }, 10000);
  showTestAgain.value = false;
  //测试中
  if (examState.value == 42) {
    await finishOneTest();
  }
  //其他状态
  if ([43, 41, 40].includes(examState.value)) {
    await closeOneTest();
  }
  if (!isLongRun.value) {
    await openOneTest();
    await startFace();
  }
  loading?.close();
  clearTimeout(loadingTime);
};

/**
 * 确认退出
 */
const confirmExit = () => {
  proxy?.$modal
    .confirm('确定退出吗？')
    .then(() => {
      getExit();
    })
    .finally(() => { });
};

/**
 * 退出
 */
const getExit = () => {
  getClearTimer(); //清除计时器
  speckCancel(); //停止播报;
  examEnds(); //通知工作站关闭
  window.onbeforeunload = null; //移除事件处理器
  if (parameter.value.taskId) {
    router.push({ path: '/test' });
  } else {
    router.push({ path: '/train' });
  }
};

/**
 * 清空定时任务
 */
const getClearTimer = (data?: any) => {
  if (data) {
    //清除指定
    clearInterval(timerManager.value[data]);
    timerManager.value[data] = null;
  } else {
    //清除全部
    for (let key in timerManager.value) {
      if (timerManager.value.hasOwnProperty(key)) {
        clearInterval(timerManager.value[key]);
        timerManager.value[key] = null;
      }
    }
  }
};

/**
 * 选择学生
 */
const getChooseStudent = (track?: number) => {
  if (examState.value < 41) {
    if (needStart.value) {
      proxy?.$modal.msgWarning('请点击开始识别');
    } else {
      proxy?.$modal.msgWarning('请稍等...');
    }
    return false;
  }
  if (examState.value == 43) {
    proxy?.$modal.msgWarning('请点击重新识别');
    return false;
  }
  if (examState.value == 42) {
    proxy?.$modal.msgWarning('正在测试...');
    return false;
  }
  currentTrack.value = track;
  // stopFace();
  chooseStudentRef.value.open();
};

/**
 * 返回被选学生
 */
const returnStudent = (data: any) => {
  if (isLongRun.value) {
    //长跑
    longStudent(data);
  } else {
    //短跑
    sprintStudent(data);
  }
};

/**
 * 处理短跑返回被选学生
 */
const sprintStudent = (data: any) => {
  if (data == undefined || !data) {
    return false;
  }
  suspendFaceRecognitionChannels(currentTrack.value); //停止识别
  let obj = {
    result_id: resultId.value,
    face_pic: data.face_pic || data.logo_url,
    student_id: data.id || data.student_id,
    student_name: data.name,
    gender: data.gender
  };
  //可能已检录的先清除
  let oldIndex = faceStudentList.value.findIndex((item: any) => {
    return data.student_id == item.student_id;
  });
  if (oldIndex != -1) {
    faceStudentList.value[oldIndex] = { track: faceStudentList.value[oldIndex].track };
  }
  //赋值
  let newIndex = faceStudentList.value.findIndex((item: any) => {
    return currentTrack.value == item.track;
  });
  faceStudentList.value[newIndex] = { ...faceStudentList.value[newIndex], ...obj };
  if (!isLongRun.value) {
    speckText(`第${currentTrack.value == 2 ? '二' : currentTrack.value}道, ${data.name}`);
  }
  currentTrack.value = null;
};

/**
 * 处理长跑返回被选学生
 */
const longStudent = (data: any) => {
  let ids = faceStudentList.value.map((item: any, index: any) => {
    return item.student_id;
  });
  //排除掉已经存在的
  let newList = data.filter((item: any, index: any) => {
    return !ids.includes(item.id);
  });
  let list = newList.map((item: any, index: any) => {
    let obj = {
      result_id: resultId.value,
      face_pic: item.face_pic || item.logo_url,
      student_id: item.id,
      student_name: item.name,
      gender: item.gender
    };
    return obj;
  });
  faceStudentList.value.push(...list);
};

/**
 * 重新识别指定跑道
 */
const getRetestTrackFace = (data: any) => {
  if (data == undefined || !data) {
    return false;
  }
  resumeFaceRecognitionChannels(data); //重新识别
  let obj = {
    student_id: null,
    track: data,
    isfinish: false
  };
  let myIndex = faceStudentList.value.findIndex((item: any) => {
    return item.track == data;
  });
  faceStudentList.value[myIndex] = obj;
};

/**
 * 清除历史记录
 */
const cleanData = () => {
  time.value.countdownNum = time.value.testTime;
  showTestAgain.value = false;
  if (isLongRun.value) {
    faceStudentList.value = [];
  } else {
    //重置全部
    let list = faceStudentList.value.map((item: any) => {
      let obj = {
        student_id: null,
        track: item.track,
        isfinish: false
      };
      return obj;
    });
    faceStudentList.value = list;
  }
};

/**
 * 自动初始化项目
 */
const initProject = () => {
  //停止计时
  getClearTimer('countdownTimer');
  speckCancel(); //停止播报
  time.value.countdownNum = 0;
  if (!resultId.value) {
    getOpenOneTestAndStartFace();
  }
  //自动项目定时进入下一步
  //if (!needStart.value) {
  //let time = 0;
  //控制新建测试的时间，第一次快，之后就慢
  // if (!resultId.value) {
  // getOpenOneTestAndStartFace();
  // }
  // if (!resultId.value) {
  //   time = 1000;
  // } else {
  //   time = 10000;
  // }
  // setTimeout(() => {
  //   //再加一个判断以免和再测一次冲突
  //   if (examState.value == 3) {
  //     getOpenOneTestAndStartFace();
  //   }
  // }, time)
  //}
};

/**
 * 倒计时
 */
const getCounting = (type: string) => {
  timerManager.value.countdownTimer = setInterval(() => {
    //正计时
    if (type == '+') {
      time.value.countdownNum++;
    }
    //倒计时
    if (type == '-') {
      if (time.value.countdownNum <= 0) {
        getClearTimer('countdownTimer');
      } else {
        time.value.countdownNum--;
      }
    }
  }, 1000);
};

/**
 * 成绩
 */
const getAchievement = (data: any) => {
  if (!data) {
    return;
  }
  let dataList = data.map((item: any) => {
    if (item.track && item.times != 0) {
      if (typeof item.times === 'string') {
        item.times = JSON.parse(item.times);
      }
      if (typeof item.times === 'object') {
        item.timeStr = proxy?.$utils.runTime(item.times[item.times.length - 1], false, isLongRun.value);
        item.turns = Math.floor(item.times.length / 2);
        if (item.times.length) {
          item.timeTotal = item.times.reduce((total: any, num: any) => {
            return total + Number(num);
          });
        } else {
          item.timeTotal = 0;
        }
      } else {
        item.timeStr = proxy?.$utils.runTime(item.times, false, isLongRun.value);
        item.turns = 0;
        item.timeTotal = 0;
      }
    }
    return item;
  });
  faceStudentList.value.forEach((item: any, index: any) => {
    let obj = dataList.find((items: any) => {
      return parseInt(item.track) == parseInt(items.track);
    });
    //加this.result_id == obj.result_id是避免抢跑的时候上一把成绩没返回会被覆盖的可能，要新的ID才能赋值
    if (obj != undefined && resultId.value == obj.result_id) {
      if (parseInt(obj.track) === parseInt(item.track) || isLongRun.value) {
        faceStudentList.value[index].timeStr = obj.timeStr;
        faceStudentList.value[index].times = obj.times;
        faceStudentList.value[index].timeTotal = obj.timeTotal;
        faceStudentList.value[index].tid_num = obj.tid_num;
        faceStudentList.value[index].score = obj.score;
        faceStudentList.value[index].isfinish = obj.isfinish;
        faceStudentList.value[index].turns = obj.turns;
        faceStudentList.value[index].result_id = obj.result_id;
      } else {
        faceStudentList.value[index].trackFalse = true;
        faceStudentList.value[index].timeStr = '跑道错误';
      }
    }
  });
};

/**
 * 移除长跑待测试列表
 */
const close = (data: any) => {
  faceStudentList.value = JSON.parse(JSON.stringify(faceStudentList.value)).filter((item: any) => {
    return item.student_id != data.student_id;
  });
};

/**
 * 长跑分页并按圈数排序
 */
const testListArr: any = computed(() => {
  // 按圈数分组排序
  let list = faceStudentList.value.filter((item: any) => {
    return item.student_id;
  });
  let myArr: any = [];
  JSON.parse(JSON.stringify(list)).forEach((item: any, index: number) => {
    let myIndex = 0;
    if (item.times != undefined) {
      myIndex = item.times.length;
    }
    if (myArr[myIndex] == undefined) {
      myArr[myIndex] = [];
    }
    myArr[myIndex].push(item);
    if (myArr[myIndex]) {
      myArr[myIndex].sort((a: any, b: any) => {
        let val1 = a.timeTotal;
        let val2 = b.timeTotal;
        return val1 - val2;
      });
    }
  });
  let myList = [];
  if (myArr.length) {
    for (let i = myArr.length - 1; i >= 0; --i) {
      if (myArr.hasOwnProperty(i)) {
        myList.push(...myArr[i]);
      }
    }
  } else {
    myList = list;
  }
  // 分页
  let myFaceStudentList = myList;
  let arrList: any = [];
  let num = 8;
  let myLength = Math.ceil(myFaceStudentList.length / num);
  for (let i = 0; i < myLength; i++) {
    arrList[i] = [];
    for (let j = 0; j < myFaceStudentList.length; j++) {
      if (j >= i * num && j < (i + 1) * num) {
        arrList[i].push(myFaceStudentList[j]);
      }
    }
  }
  return arrList;
});

/**
 * 时间转换
 */
const countdownNumFormat = computed(() => {
  return proxy?.$utils.timeFormat(time.value.countdownNum);
});

onBeforeMount(() => {
  parameter.value = route.query;
  let project = parameter.value.project;
  let area = parameter.value.area;
  parameter.value.examId = `${project}_${area}`; //项目+区
  if (parameter.value.time) {
    time.value.testTime = parameter.value.time;
  }
  time.value.countdownNum = time.value.testTime;
  let myInfo: any = localStorage.getItem('userInfo');
  userInfo.value = JSON.parse(myInfo);
  let dic: any = dataDictionary;
  unit.value = dic.unit[project];
  if (parameter.value.gesture == 'true') {
    parameter.value.gesture = true;
  } else {
    parameter.value.gesture = false;
  }
  //是否折返跑
  if (project.slice(0, 3) === 'run' && project.includes('x')) {
    isBackRun.value = true;
  }
  //是否长跑
  if (project.replace('run', '') > 799) {
    isLongRun.value = true;
  }
  //需要开始按钮的项目
  if (isLongRun.value) {
    needStart.value = true;
  }
  //加载WS
  initWs({ parameter: parameter.value, testTime: time.value.testTime }, (data: any) => {
    getMessage(data);
  });
  //初始化语音
  initSpeech();
  //刷新关闭
  window.onbeforeunload = function (e) {
    var confirmationMessage = '刷新/关闭页面将会关闭页面,是否确认退出页面?';
    (e || window.event).returnValue = confirmationMessage; // 兼容 Gecko + IE
    let bUrl = import.meta.env.VITE_APP_BASE_API;
    let classId = parameter.value.classes;
    let project = parameter.value.project;
    let area = parameter.value.area;
    let examId = `${project}_${area}`;
    let mySid = sid.value;
    let token: any = localStorage.getItem('token');
    let formData = new FormData();

    formData.append('exam_id', examId);
    formData.append('class_id', classId);
    formData.append('token', token);
    formData.append('sid', mySid);
    navigator.sendBeacon(bUrl + '/exam/close_exam', formData);

    return confirmationMessage; // 兼容 Gecko + Webkit, Safari, Chrome
  };
});

onBeforeUnmount(() => {
  getExit();
});
</script>

<style scoped lang="scss">
$topPadding: 5.19rem;
$waiPadding: 6.51rem;

.time {
  width: 20vh;
  height: 20vh;
  line-height: 20vh;
  border-radius: 50%;
  color: #ff9402;
  font-size: 7.5vh;
  text-align: center;
  background-image: url('@/assets/images/test/time.png');
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  position: absolute;
  right: 50%;
  top: -4.5vh;
  margin-right: -10vh;
  font-family: 'Saira-BlackItalic';
}

.main {
  width: calc(100% - ($waiPadding * 2));
  height: 70vh;
  padding-top: 10rem;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  overflow: hidden;

  .main-left {
    width: 71.5%;
    height: 100%;
    display: flex;
    background: linear-gradient(58deg, #092941 -85%, #2a484b 96%);
    box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.4);
    border-radius: 1.6rem;

    .trackItem {
      width: 100%;
      overflow-y: scroll;
      padding: 0px 10px;

      &::-webkit-scrollbar {
        width: 10px;
      }

      &::-webkit-scrollbar-thumb {
        border-width: 2px;
        border-radius: 4px;
        border-style: dashed;
        border-color: transparent;
        background-color: rgba(26, 62, 78, 0.9);
        background-clip: padding-box;
      }

      &::-webkit-scrollbar-button:hover {
        border-radius: 6px;
        background: rgba(26, 62, 78, 1);
      }

      .li {
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-bottom: 1px solid #475557;
        height: calc(100% / 8);
        box-sizing: border-box;
        padding: 0px 20px 0px 50px;

        .left {
          display: flex;
          align-items: center;

          .track {
            width: 5rem;
            color: #13ed84;
            font-size: 2rem;
            font-family: 'Saira-ExtraBold';
            margin-right: 1rem;
          }

          .pic {
            width: 6.7vh;
            height: 6.7vh;
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: hidden;
            margin-right: 15px;

            img {
              width: 100%;
            }
          }

          .pic2 {
            box-sizing: border-box;
            border: 1px solid rgba(255, 255, 255, 0.5);
          }

          .userInfo {
            display: flex;
            justify-content: flex-start;
            align-items: center;

            .nameBox {
              width: 8rem;

              .name {
                font-size: 1.5rem;
                color: #ffffff;
              }
            }
          }
        }

        .scoreBox {
          display: flex;
          align-items: center;

          .score {
            color: #ffffff;
            font-size: 2rem;
            font-family: 'Saira-ExtraBold';
          }

          .turns {
            margin-left: 3rem;
            color: #ffffff;
            display: flex;
            align-items: center;

            span {
              font: 1.5rem;
              margin: 0 5px;
            }

            i {
              font-style: normal;
              font-size: 1.8rem;
              font-family: 'Saira-ExtraBold';
            }
          }
        }

        .menuBtn {
          width: auto;
          padding: 0 1.2rem;
          height: 2.8rem;
          line-height: 2.8rem;
          border-radius: 1.4rem;
          color: #ffffff;
          font-size: 1.5rem;
          background: linear-gradient(180deg, #ffb200 0%, #ed7905 72%);
          box-shadow: inset 0px 1px 0px 1px rgba(255, 255, 255, 0.5);
          display: flex;
          align-items: center;
          cursor: pointer;
        }

        .menuBtn2 {
          color: #1a293a;
          background: radial-gradient(159% 126% at 5% 93%, #8effa9 0%, #07ffe7 100%);
          box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.1874), inset 0px 1px 0px 2px rgba(255, 255, 255, 0.3);
        }

        .close {
          width: 2rem;
          height: 2rem;
        }
      }
    }
  }

  .main-left2 {
    width: 100%;

    .trackItem {
      .li {
        .scoreBox {
          .score {
            font-size: 1.8rem;
          }
        }
      }
    }
  }

  .main-right {
    width: 27%;
    border-radius: 1.6rem;
    background: linear-gradient(29deg, #092941 -82%, #2a484b 94%);
    box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.4);
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .swiper-btn {
    width: 2.5rem;
    height: 2.5rem;
    display: block;

    &::after {
      display: none;
    }
  }

  .swiper-btn-left {
    background: url('@/assets/images/ranking/btn-left.png') left center no-repeat;
    background-size: 100% 100%;
  }

  .swiper-btn-right {
    background: url('@/assets/images/ranking/btn-right.png') left center no-repeat;
    background-size: 100% 100%;
  }
}

.footerBtn {
  width: 100%;
  padding: 0 calc(13.02rem / 2);
  box-sizing: border-box;
  position: fixed;
  bottom: 3vh;
  display: flex;
  justify-content: flex-end;

  .btn {
    width: 13vw;
    height: 6.1vh;
    line-height: 6.1vh;
    font-size: 3vh;
    color: #1a293a;
    text-align: center;
    border-radius: 1vh;
    margin-left: 20px;
    cursor: pointer;
    background: radial-gradient(159% 126% at 5% 93%, #8effa9 0%, #07ffe7 100%);
    box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.1874), inset 1px 1px 1px 1px rgba(255, 255, 255, 0.3);

    &:hover {
      background: #8effa9;
    }
  }

  .startBtn {
    color: #ffffff;
    background: radial-gradient(159% 126% at 5% 93%, #f99f02 0%, #ed7905 100%);
    box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.1874), inset 1px 1px 1px 1px rgba(255, 255, 255, 0.3);

    &:hover {
      background: #f99f02;
    }
  }

  .exitBtn {
    color: #ffffff;
    background: radial-gradient(159% 126% at 5% 93%, #931b1b 0%, #ec5624 0%, #ff6860 76%);
    box-shadow: 3px 6px 4px 1px rgba(0, 0, 0, 0.1874), inset 0px 1px 0px 2px rgba(255, 255, 255, 0.5577);

    &:hover {
      background: #ec5624;
    }
  }
}
</style>
