<template>
  <div class="exam-invigilation">
    <div class="invigilation-analysis">
      <div class="part-box-head">
        <div class="part-box-head-left"><h1>考情监控</h1></div>
        <div class="part-box-head-right" @click="exitFullscreen">
          <i class="icon icon-full-screen"></i>退出全屏
        </div>
      </div>
      <div class="invigilation-summary">
        <div class="invigilation-summary-item">
          <div class="part-box">
            <h5>
              <span>在线(人)</span>
              <el-popover
                placement="top-start"
                popper-class="warning-popover"
                width="200"
                trigger="hover"
                content="当前在线考试人数。"
              >
                <i class="el-icon-question" slot="reference"></i>
              </el-popover>
            </h5>
            <p>{{ monitorCount.onlineCount }}</p>
          </div>
        </div>
        <div class="invigilation-summary-item">
          <div class="part-box">
            <h5>
              <span>待考(人)</span>
              <el-popover
                placement="top-start"
                popper-class="warning-popover"
                width="200"
                trigger="hover"
                content="已进入待考界面等待开考的考生。"
              >
                <i class="el-icon-question" slot="reference"></i>
              </el-popover>
            </h5>
            <p>{{ monitorCount.waitingCount }}</p>
          </div>
        </div>
        <div class="invigilation-summary-item">
          <div class="part-box">
            <h5>
              <span>考试中(人)</span>
              <el-popover
                placement="top-start"
                popper-class="warning-popover"
                width="200"
                trigger="hover"
                content="正在答题的考生。"
              >
                <i class="el-icon-question" slot="reference"></i>
              </el-popover>
            </h5>
            <p>{{ monitorCount.examingCount }}</p>
          </div>
        </div>
        <div class="invigilation-summary-item">
          <div class="part-box">
            <h5>
              <span>通讯故障</span>
              <el-popover
                placement="top-start"
                popper-class="warning-popover"
                width="200"
                trigger="hover"
                content="考生端出现断网、断电、软硬件故障等异常导致考生端与监考端无法正常连接的考生。"
              >
                <i class="el-icon-question" slot="reference"></i>
              </el-popover>
            </h5>
            <p
              :class="{
                'color-danger': monitorCount.exceptionCountChange > 0,
                'color-success': monitorCount.exceptionCountChange < 0,
              }"
            >
              {{ monitorCount.exceptionCount }}
              <i
                :class="[
                  'icon',
                  {
                    'icon-arrows-up': monitorCount.exceptionCountChange > 0,
                    'icon-arrows-down': monitorCount.exceptionCountChange < 0,
                  },
                ]"
              ></i>
            </p>
          </div>
        </div>
        <div class="invigilation-summary-item">
          <div class="part-box">
            <h5>
              <span>预警</span>
              <el-popover
                placement="top-start"
                popper-class="warning-popover"
                width="200"
                trigger="hover"
                content="实时预警数量及升跌趋势（后1分钟增量与前1分钟增量对比，大于为升势，小于为跌势）。"
              >
                <i class="el-icon-question" slot="reference"></i>
              </el-popover>
            </h5>
            <p
              :class="{
                'color-danger': monitorCount.warnCountChange > 0,
                'color-success': monitorCount.warnCountChange < 0,
              }"
            >
              {{ monitorCount.warnCount }}
              <i
                :class="[
                  'icon',
                  {
                    'icon-arrows-up': monitorCount.warnCountChange > 0,
                    'icon-arrows-down': monitorCount.warnCountChange < 0,
                  },
                ]"
              ></i>
            </p>
          </div>
        </div>
      </div>
      <div class="invigilation-online part-box">
        <h3 class="invigilation-part-title">
          <span>各机构在线考试人数分布</span>
          <el-popover
            placement="top-start"
            popper-class="warning-popover"
            width="200"
            trigger="hover"
            content="各二级子机构当前在线考试人数分布。"
          >
            <i class="el-icon-question" slot="reference"></i>
          </el-popover>
        </h3>
        <echart-render
          :chart-data="onlineData"
          chart-type="bar"
        ></echart-render>
      </div>
      <div class="invigilation-warning">
        <el-row :gutter="20">
          <el-col :span="12">
            <div class="part-box">
              <h3 class="invigilation-part-title">
                <span>机构预警分布</span>
                <el-popover
                  placement="top-start"
                  popper-class="warning-popover"
                  width="200"
                  trigger="hover"
                  content="各二级子机构当前预警数量分布。"
                >
                  <i class="el-icon-question" slot="reference"></i>
                </el-popover>
              </h3>
              <echart-render
                :chart-data="orgWarningData"
                chart-type="pieAnnulus"
              ></echart-render>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="part-box">
              <h3 class="invigilation-part-title">
                <span>预警类型分布</span>
                <el-popover
                  placement="top-start"
                  popper-class="warning-popover"
                  width="200"
                  trigger="hover"
                  content="当前考试累计预警的类型分析。"
                >
                  <i class="el-icon-question" slot="reference"></i>
                </el-popover>
              </h3>
              <echart-render
                :chart-data="typeWarningData"
                chart-type="pieAnnulus"
              ></echart-render>
            </div>
          </el-col>
        </el-row>
      </div>
      <div class="invigilation-trend part-box">
        <h3 class="invigilation-part-title">
          <span>预警时间趋势</span>
          <el-popover
            placement="top-start"
            popper-class="warning-popover"
            width="200"
            trigger="hover"
            content="按时间维度呈现预警数量的升跌走势图。"
          >
            <i class="el-icon-question" slot="reference"></i>
          </el-popover>
        </h3>
        <echart-render
          :chart-data="warningTrendData"
          chart-type="line"
        ></echart-render>
      </div>
      <div class="invigilation-message part-box">
        <h3 class="invigilation-part-title">
          <span>预警消息</span>
          <el-popover
            placement="top-start"
            popper-class="warning-popover"
            width="200"
            trigger="hover"
            content="系统实时预警提示滚屏。"
          >
            <i class="el-icon-question" slot="reference"></i>
          </el-popover>
        </h3>
        <div class="message-list">
          <div
            class="message-item"
            v-for="(item, index) in messages"
            :key="index"
          >
            <span><i class="el-icon-warning"></i></span>
            <span>{{ item.time | datetimeFilter }}</span>
            <span>{{ item.content }}</span>
          </div>
        </div>
      </div>
    </div>
    <div class="invigilation-list">
      <h3>实时监控台</h3>
      <invigilation-student
        v-for="(item, index) in students"
        :key="index"
        :data="item"
      ></invigilation-student>
    </div>
  </div>
</template>

<script>
import EchartRender from "../common/EchartRender";
import InvigilationStudent from "../common/InvigilationStudent";
import {
  examInvigilationCount,
  examInvigilationWarnDistribution,
  examInvigilationWarnTrend,
  examInvigilationVideoRandomList,
  examInvigilationWarnMessage,
} from "@/api/invigilation";
import { mapState } from "vuex";

export default {
  name: "exam-invigilation",
  components: { EchartRender, InvigilationStudent },
  data() {
    return {
      monitorCount: {
        onlineCount: 0,
        waitingCount: 0,
        examingCount: 0,
        exceptionCount: 0,
        warnCount: 0,
        exceptionCountChange: false,
        warnCountChange: false,
      },
      onlineData: {
        dataList: [],
        type: "light", // light or dark
      },
      orgWarningData: {
        dataList: [],
        type: "light",
      },
      typeWarningData: {
        dataList: [],
        type: "light",
      },
      warningTrendData: {
        dataList: [],
        type: "light",
      },
      setT: null,
      loopRunning: false,
      students: [],
      messages: [],
    };
  },
  computed: {
    ...mapState("invigilation", ["liveDomains"]),
    isFullScreen() {
      return this.$store.state.isFullScreen;
    },
  },
  watch: {
    isFullScreen(val) {
      this.fullScreenChange(val);
    },
  },
  mounted() {
    this.loopRunning = true;
    this.initData();
  },
  methods: {
    async initData() {
      if (this.setT) clearTimeout(this.setT);
      if (!this.loopRunning) return;

      const fetchAll = [
        this.getCount(),
        this.getWarnDistribution(),
        this.getWarnTrend(),
      ];
      await Promise.all(fetchAll).catch(() => {});

      this.fullScreenChange(this.checkDocIsFullscreen());

      await this.getVideoList();
      await this.getMessageList();

      this.setT = setTimeout(() => {
        this.initData();
      }, 10 * 1000);
    },
    async getCount() {
      const res = await examInvigilationCount();
      const data = res.data.data;
      this.monitorCount = {
        onlineCount: data.onlineCount,
        waitingCount: data.waitingCount,
        examingCount: data.examingCount,
        exceptionCount: data.exceptionCount,
        warnCount: data.warnCount,
        exceptionCountChange:
          data.exceptionCount - this.monitorCount.exceptionCount,
        warnCountChange: data.warnCount - this.monitorCount.warnCount,
      };
      this.onlineData.dataList = data.orgExamingCount.map((item) => {
        return {
          name: item.orgName,
          count: item.count * 1,
        };
      });
    },
    async getWarnDistribution() {
      const res = await examInvigilationWarnDistribution();
      const data = res.data.data;
      this.orgWarningData.dataList = data.orgDistribution.map((item) => {
        return {
          name: item.orgName,
          count: item.count,
        };
      });
      this.typeWarningData.dataList = data.typeDistribution.map((item) => {
        return {
          name: item.type,
          count: item.count * 1,
        };
      });
    },
    async getWarnTrend() {
      const res = await examInvigilationWarnTrend();
      this.warningTrendData.dataList = res.data.data.map((item) => {
        return {
          name: item.hour,
          count: item.count * 1,
        };
      });
    },
    async getVideoList() {
      const res = await examInvigilationVideoRandomList({ randomNum: 4 });
      const domainLen = this.liveDomains.length;
      this.students = res.data.data.map((item, index) => {
        const domain = domainLen ? this.liveDomains[index % domainLen] : "";
        item.liveUrl = item.monitorLiveUrl
          ? `${domain}/live/${item.monitorLiveUrl.toLowerCase()}.flv`
          : "";
        item.progress = item.progress ? Math.round(item.progress * 100) : 0;
        return item;
      });
    },
    async getMessageList() {
      const res = await examInvigilationWarnMessage();
      this.messages = res.data.data;
    },
    // fullscreen
    exitFullscreen() {
      const exitFullscreen =
        document.exitFullscreen ||
        document.mozCancelFullScreen ||
        document.webkitCancelFullScreen;

      exitFullscreen.call(document);
    },
    checkDocIsFullscreen() {
      return (
        document.fullscreenElement ||
        document.msFullscreenElement ||
        document.mozFullscreenElement ||
        document.webkitFullscreenElement
      );
    },
    fullScreenChange(isFullScreen) {
      const colorType = isFullScreen ? "dark" : "light";
      this.onlineData.type = colorType;
      this.orgWarningData.type = colorType;
      this.typeWarningData.type = colorType;
      this.warningTrendData.type = colorType;
    },
  },
  beforeDestroy() {
    this.loopRunning = false;
    if (this.setT) clearTimeout(this.setT);
  },
};
</script>

<style lang="scss" scoped>
.exam-invigilation {
  position: relative;
  padding-right: 310px;
  min-width: 1250px;
  .part-box-head-right {
    display: none;
  }
  .part-box {
    position: relative;
  }
  .invigilation-part-title {
    position: absolute;
    top: 20px;
    left: 20px;
    font-size: 16px;
    font-weight: 500;
    z-index: 9;
  }
  .el-icon-question {
    margin-left: 5px;
    color: #bdc8da;
  }
}
.invigilation-list {
  position: absolute;
  top: 0;
  right: 0;
  width: 280px;
  height: 100%;
  background: #fff;
  border-radius: 6px;
  padding: 20px;
  z-index: 9;
  overflow-y: auto;
  overflow-x: hidden;

  > h3 {
    font-size: 18px;
    font-weight: 600;
    line-height: 25px;
    margin-bottom: 20px;
  }
}
.invigilation-analysis {
  min-width: 940px;
  .part-box-head-left h1 {
    line-height: 25px;
  }
}
.invigilation-summary {
  margin: 0 -10px;
  font-size: 0;

  &-item {
    display: inline-block;
    vertical-align: top;
    width: 20%;
    padding: 0 10px;
    font-size: 14px;
    color: #202b4b;

    h5 {
      font-size: 14px;
      height: 20px;
      color: #626a82;
      margin: 0;
    }
    p {
      font-size: 32px;
      line-height: 51px;
      font-weight: 600;
      margin: 0;
    }
    .icon {
      margin-top: -4px;
    }

    &:first-child {
      .part-box {
        background-color: #3a93fb;
      }
      h5 {
        color: #fff;
      }
      p {
        color: #fff;
        font-weight: 900;
        font-size: 36px;
      }
    }
  }
}
.invigilation-online {
  height: 360px;
}
.invigilation-warning {
  .part-box {
    height: 282px;
    padding-top: 50px;
    padding-bottom: 10px;
  }
}
.invigilation-trend {
  height: 327px;
}
.invigilation-message {
  min-height: 160px;
  padding-top: 70px;
  .message-item {
    margin-bottom: 15px;

    span {
      line-height: 20px;

      &:first-child {
        color: #fe5863;
      }

      &:nth-of-type(2) {
        margin: 0 20px 0 12px;
        color: #8c94ac;
      }
    }
  }
}
</style>
<style lang="scss">
// fullscreen style
.app-fullscreen {
  .part-box {
    background: #2d325a;
  }

  .exam-invigilation {
    margin: -30px;
    padding-right: 280px;
    color: #fff;
    .part-box-head-right {
      display: block;
      cursor: pointer;
      color: #737aae;
      > i {
        margin-right: 8px;
        margin-top: -2px;
      }
    }
    .part-box-head-left > h1 {
      color: #fff;
    }
    .el-icon-question {
      color: #737aae;
    }
  }
  .invigilation-analysis {
    padding: 30px;
    background: #25294a;
  }
  .invigilation-list {
    background: #202442;
    border-radius: 0;
    .invigilation-student {
      background: #2d325a;
      border: 1px solid #2d325a;
    }
    .student-info {
      .student-time {
        background: #353c70;
      }
      > p {
        color: #737aae;
      }
    }
  }
  .invigilation-summary {
    &-item {
      h5 {
        color: #737aae;
      }
      p {
        color: #fff;
      }

      &:first-child {
        .el-icon-question {
          color: #fff;
        }
      }
    }
  }
}
</style>
