<template>
  <div class="train-monitor" v-loading="loading">
    <div>
      <TrainInfo
        :trainInfo="trainInfo"
        :trainList="trainList"
        :groupIdList="groupIdList"
        :groupInfo="groupInfo"
        @change="changeTrain"
        :showFloorBar="true"
        :deviceAllOnline="deviceAllOnline"
        @trainControl="trainControl"
        @changeGroup="changeGroup"
      ></TrainInfo>
      <TrainChunkBox title="训练要素状态"></TrainChunkBox>
    </div>
    <div>
      <TrainChunkBox title="训练步骤信息">
        <TrainStep
          :trainInfo="trainInfo"
          :settings="trainInfo?.settings?.[checkedGroup]"
          :groupInfo="groupInfo[checkedGroup]"
        ></TrainStep
      ></TrainChunkBox>
    </div>
    <div>
      <TrainChunkBox
        title="训练进度详情"
        style="min-height: 150px; max-height: 185px"
      >
        <ul class="schedule-detail" style="list-style: none">
          <li class="schedule-detail-item">
            <span class="schedule-item-label ellipsis-1">总体进度：</span>
            <span class="schedule-item-content"
              ><el-progress
                color="#00d07a"
                :percentage="calculateSchedule?.all?.percentage"
              ></el-progress
            ></span>
          </li>
          <li
            class="schedule-detail-item"
            v-for="(user, i) in groupInfo[checkedGroup]?.usersArray"
            :key="i"
          >
            <span class="schedule-item-label ellipsis-1"
              >{{ user.name }}：</span
            >
            <span class="schedule-item-content"
              ><el-progress
                color="#00d07a"
                :percentage="
                  calculateSchedule?.[user.id + user.deviceInfo.deviceInfo.id]
                    ?.percentage
                "
              ></el-progress
            ></span>
          </li>
        </ul>
      </TrainChunkBox>
      <TrainChunkBox title="训练判读数据" style="max-height: 150px">
        <ul style="list-style: none" id="messageList" ref="messageList">
          <li
            :class="`message-list-item message-list-item-${item.status}`"
            v-for="(item, index) in groupInfo[checkedGroup]?.messageList"
            :key="index"
          >
            <div style="flex: 1">
              <div class="message-list-item-title">{{ item.content }}</div>
              <div class="message-list-item-info" v-if="item.info">
                {{ item.info }}
              </div>
            </div>
            <i
              style="font-size: 18px"
              :class="{
                'el-icon-error': item.status === 'error',
                'el-icon-warning': item.status === 'timeout',
                'el-icon-success': item.status === 'correct',
              }"
            ></i>
          </li>
        </ul>
      </TrainChunkBox>
      <TrainVideo
        title="训练实时画面"
        :trainInfo="trainInfo"
        :stepInf="stepInfo"
        :checkedGroup="checkedGroup"
      >
      </TrainVideo>
    </div>
    <!-- <TrainCalculateScore :isShow="trainInfo.isOver"></TrainCalculateScore> -->
    <TrainCalculateScore
      @saveTrainGrade="saveTrainGrade"
      :groupInfo="groupInfo"
      :groupIdList="groupIdList"
      :trainInfo="trainInfo"
    ></TrainCalculateScore>
  </div>
</template>

<script>
import TrainInfo from "../components/train-info.vue";
import TrainChunkBox from "../components/train-chunk-box.vue";
import {
  getTrainListApi,
  getTrainStepApi,
  getTrainDetailsApi,
  editorTrainApi,
  saveTrainScoreApi,
} from "@/api/training/train";
import { getDevicesInfoApi } from "@/api/training/device";
import TrainStep from "./components/train-step.vue";
import TrainMqtt from "../utils/train-mqtt";
import TrainVideo from "./components/train-video.vue";
import TrainCalculateScore from "./components/train-calculate-score.vue";
export default {
  components: {
    TrainChunkBox,
    TrainInfo,
    TrainStep,
    TrainVideo,
    TrainCalculateScore,
  },
  data() {
    return {
      trainList: [],
      trainInfo: {},
      loading: false,
      checkedGroup: null,
      stepInfo: {},
      groupInfo: {},
      groupIdList: [],
      everyGroupNowTrainStep: {},
      nowTrainStep: null,
      prevStepTime: null,
      trainDeviceInfo: null,
      trainUserInfo: null,
    };
  },
  mixins: [TrainMqtt],
  created() {
    this.initData();
  },
  methods: {
    changeGroup(key) {
      this.checkedGroup = key;
      this.$nextTick(() => {
        const messageBox = document.getElementById("messageList");
        const stepBox = document.querySelectorAll(".stepInfoBox");
        stepBox?.forEach((item) => {
          let ele = item.querySelector(".step-item-pending");
          console.log(ele);
          ele && ele.scrollIntoView(true);
        });
        messageBox.scrollTo(0, messageBox.scrollHeight);
      });
    },
    // 初始化数据获取训练列表
    async initData() {
      this.loading = true;
      const { data } = await getTrainListApi();
      if (!data || !data.length) {
        this.$message.error("暂无训练数据");
        return;
      }
      this.trainList = data;
    },
    // 切换训练
    async changeTrain(id) {
      this.loading = true;
      await this.getTrainDetail(id);
      await this.getTrainStep(id);
      if (!this.trainInfo) {
        this.$message.error("暂无训练");
        return;
      }
      this.loading = false;
    },
    // 获取训练详情
    async getTrainDetail(id) {
      const { data } = await getTrainDetailsApi(id);
      const group = {};
      data.isShowCalculate = false;
      data.rule = JSON.parse(data.rule);
      data.settings.forEach((device) => {
        if (group[device.group]) {
          group[device.group].push(device);
        } else {
          group[device.group] = [device];
        }
      });
      // 获取参加训练的设备信息包括部件等
      this.getTrainDeviceInfo(data.settings.map((item) => item.deviceInfo.id));
      // 获取参加训练的用户信息
      this.trainUserInfo = data.settings.map((item) => {
        return {
          userInfo: item.userInfo,
          device: item,
        };
      });
      data.settings = Object.values(group);
      // 初始化组信息
      for (const k in group) {
        // this.groupInfo[k] =
        this.$set(this.groupInfo, k, {
          usersObject: {},
          usersArray: [],
          devicesArray: [],
          devicesObject: {},
          steps: [],
          nowStep: null,
          nowStepIndex: 0,
          prevStepTime: null,
          pause: null,
          messageList: null,
          // completeStepCount: 0
        });
        group[k].forEach((device) => {
          device.userInfo = { ...device.userInfo, deviceInfo: device };
          this.groupInfo[k].devicesObject[device.deviceInfo.id] = device;
          this.groupInfo[k].devicesArray.push(device);
          this.groupInfo[k].usersObject[
            device.userInfo.id + device.deviceInfo.id
          ] = device.userInfo;
          this.groupInfo[k].usersArray.push(device.userInfo);
        });
      }
      this.groupIdList = Object.keys(this.groupInfo);
      this.$set(this, "trainInfo", data);
      this.$set(this.trainInfo, "suspend", 0);
      if (this.client) {
        this.getOnlineClients();
      }
      // this.$set(this.trainInfo, 'status', 0)
    },
    /** */

    async getTrainDeviceInfo(ips) {
      const { data } = await getDevicesInfoApi(ips);
      this.trainDeviceInfo = data;
    },
    /**
     * 获取训练步骤信息
     * @param {number} id  训练ID
     */
    async getTrainStep(id) {
      const { data } = await getTrainStepApi(id);
      data.forEach((step) => {
        if (step.status === 1 || step.status === 2) {
          this.$set(step, "result", step.status);
          step.result = step.status;
          step.status = 1;
        }
      });
      data.sort((a, b) => {
        return a.stepInfo.sort - b.stepInfo.sort;
      });
      // 分组
      // 处理分组步骤信息 处理用户步骤信息
      for (const key in this.groupInfo) {
        const base = this.groupInfo[key];
        if (!base.steps) {
          this.$set(base, "steps", []);
        }
        const groupData = data.filter((item) => {
          return item.settingInfo.group === +key;
        });
        groupData.forEach((step) => {
          // console.log(base.usersObject[step.userInfo.id]);
          base.steps.push(step);
          let objKey = step.userInfo.id + step.deviceInfo.id;
          if (base.usersObject[objKey]?.step) {
            base.usersObject[objKey]?.step.push(step);
          } else if (base.usersObject[objKey]) {
            base.usersObject[objKey].step = [step];
          }
        });
      }
      // 查到当前正在执行的数据

      for (const key in this.groupInfo) {
        const base = this.groupInfo[key];
        let nowStepIndex = -1;
        for (let i = base.steps.length - 1; i >= 0; i--) {
          if (base.steps[i]?.status === 1 || base.steps[i]?.status === 2) {
            nowStepIndex = i;
            break;
          }
        }
        if (nowStepIndex === -1) {
          base.nowStepIndex = 0;
          base.nowStep = base.steps[0];
        } else {
          base.nowStepIndex = nowStepIndex + 1;
          base.nowStep = base.steps[nowStepIndex + 1];
        }
        base.nowStep && (base.nowStep.status = 3);
        if (this.trainInfo.status === 1) {
          this.setStepTimeLine(key, { status: "等待用时", value: 0 });
        }
      }
    },
    /**
     * 训练控制
     * @param {number} key
     * 1 = 开始训练
     * 2 = 暂停训练
     * 3 = 回复训练
     * 4 = 结束训练
     * 5 = 重新训练
     * 6 = 查看成绩
     */
    async trainControl(key) {
      const nowTime = new Date().getTime();
      switch (key) {
        // 开始训练
        case 1:
          this.startTranin();
          break;
        // 暂停训练
        case 2:
          for (const key in this.groupInfo) {
            if (this.groupInfo[key].nowStep) {
              this.groupInfo[key].nowStep.suspendStratTime = nowTime;
              this.groupInfo[key].nowStep.suspend = 1;
            }
            this.timer[key] && clearInterval(this.timer[key]);
          }
          this.trainInfo.suspend = 1;
          this.pauseResumeEnd(2);
          break;
        // 恢复训练
        case 3:
          this.pauseResumeEnd(3);
          for (const key in this.groupInfo) {
            if (this.groupInfo[key].nowStep) {
              const base = this.groupInfo[key];
              if (+base.nowStep.pause) {
                base.nowStep.pause += nowTime - base.nowStep.suspendStratTime;
              } else {
                base.nowStep.pause = nowTime - base.nowStep.suspendStratTime;
              }
              base.nowStep.suspendStratTime = null;
              this.trainInfo.suspend = 0;
            }
            this.sendRobotStepInfo(key, this.groupInfo[key].nowStep);
            this.setStepTimeLine(key);
          }
          break;
        // 结束训练
        case 4:
          this.$confirm("确定要结束当前训练吗？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
            // eslint-disable-next-line prefer-promise-reject-errors
          })
            .then(async (res) => {
              Object.keys(this.groupInfo).forEach((item) => {
                this.setStepTimeLine(item);
              });
              const needUpLoadDate = await this.calculateGrade();
              if (needUpLoadDate) {
                await saveTrainScoreApi(this.trainInfo.id, needUpLoadDate);
                this.$router.push({
                  path: "/train/training?step=3",
                  query: { id: this.trainInfo.id },
                });
                location.reload();
              } else {
                for (let key in this.groupInfo) {
                  const base = this.groupInfo[key];
                  base.usersArray.forEach((item) => {
                    item.stepScore = parseInt(item.stepScore * 0.8);
                    console.log(item.stepScore);
                  });
                }
                this.trainInfo.isShowCalculate = true;
              }
              await editorTrainApi(this.trainInfo.id, { status: 3 });
            })
            .catch((_) => {});

          break;
        // 重新训练
        case 5:
          this.$router.push({
            path: "/train/training?step=1",
            query: { anewId: this.trainInfo.id },
          });
          location.reload();
          break;
        // 查看成绩
        case 6:
          this.$router.push({
            path: "/train/training",
            query: { id: this.trainInfo.id, step: 3 },
          });
          location.reload();
          break;
        default:
          break;
      }
    },
    async saveTrainGrade() {
      const needUpLoadData = [];
      let needSendData = [];
      for (const key in this.groupInfo) {
        const base = this.groupInfo[key];
        console.log(base, "asdasdasdasdas");
        base.usersArray.forEach((user) => {
          let duration = 0;
          if (!user.step) return;
          user.step.forEach((st) => {
            duration += +st.duration;
          });
          needUpLoadData.push({
            train: this.trainInfo.id,
            setting: user.deviceInfo.id,
            duration: duration,
            score: user.stepScore + (user.score || 0),
          });
          let errList = user.step.filter((item) => item.status === 2);
          console.log(user.stepScore, user.score);
          needSendData.push({
            UserID: user.id,
            JobId: user.deviceInfo.deviceInfo.position,
            GroupID: key,
            JobDevice: user.deviceInfo.deviceInfo.keycode,
            Score: user.stepScore + (user.score || 0),
            TotalStep: user.step?.length || 0,
            ErrorStep: errList.length,
            CorrectStep: user.step ? user.step.length - errList.length : 0,
            Ip: user.deviceInfo.ip.ip,
          });
        });
      }
      console.log(needSendData);
      this.sendOverData(needSendData);
      await saveTrainScoreApi(this.trainInfo.id, needUpLoadData);
      this.$router.push({
        path: "/train/training?step=3",
        query: { id: this.trainInfo.id },
      });
      location.reload();
    },
  },
  computed: {
    // 计算每个学员训练进度的百分比
    calculateSchedule() {
      try {
        if (!this.checkedGroup || !this.groupInfo[this.checkedGroup]) {
          return {};
        }
        const listObj = { all: { all: [], correct: [] } };
        // 根据之前统计的步骤信息拿到所有学员组成基础数据！
        for (const key in this.groupInfo[this.checkedGroup].usersObject) {
          listObj[key] = { all: [], correct: [] };
        }
        // 根据之前统计的步骤信息处理每个角色的所有步骤数及对应的正确步骤数
        this.groupInfo[this.checkedGroup].steps?.forEach((item) => {
          if (item.status === 1 || item.status === 2) {
            listObj.all?.correct.push(item);
            listObj[item.userInfo.id + item.deviceInfo.id]?.correct.push(item);
          }
          listObj.all.all.push(item);
          listObj[item.userInfo.id + item.deviceInfo.id].all.push(item);
        });
        // 计算百分比
        for (const key in listObj) {
          if (!listObj[key]?.all.length) {
            listObj[key].percentage = 1 * 100;
          } else {
            listObj[key].percentage = (
              (listObj[key]?.correct.length / listObj[key].all.length) *
              100
            ).toFixed();
          }
        }
        return listObj;
      } catch (error) {
        console.log("计算训练进度详情时出现错误：", error);
      }
      return null;
    },
    deviceAllOnline() {
      let isAllOnline = true;
      this.trainInfo.settings?.forEach((group) => {
        group.forEach((device) => {
          if (!device.alive) {
            isAllOnline = false;
          }
        });
      });
      return isAllOnline;
    },
  },
};
</script>

<style lang="scss" scoped>
.train-monitor {
  flex: 1;
  display: flex;
  overflow: auto;
  flex-wrap: wrap;
  > div {
    min-width: 530px;
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 300px;
    height: 100%;
  }
  .schedule-detail {
    padding: 10px;
    height: 100%;
    overflow: auto;
    .schedule-detail-item {
      display: flex;
      margin-bottom: 10px;
    }
    .schedule-item-label {
      width: 80px;

      font-size: 14px;
      font-weight: 700;
    }
    .schedule-item-content {
      flex: 1;
      ::v-deep .el-progress__text {
        font-weight: bold;
        color: #00d07a;
      }
    }
  }
  ul {
    height: 100%;
    overflow: auto;
    padding: 5px 10px;
    .message-list-item {
      display: flex;
      // align-items: center;
      // justify-content: flex-start;
      // flex-wrap: wrap;
      margin-bottom: 5px;
      padding: 5px 10px;
      align-items: center;
    }
    .message-list-item-title {
      font-weight: bold;
      font-size: 14px;
    }
    .message-list-item-info {
      margin-top: 5px;
    }
    .message-list-item-correct {
      background-color: #c2f2e2;
      color: #25d58b;
    }
    .message-list-item-timeout {
      background-color: #f5f1cb;
      color: #fec829;
    }
    .message-list-item-error {
      background-color: #f2d5d7;
      color: #ef4e4e;
    }
  }
}
</style>
