<template>
  <div class="alarmBox" :class="alarmList?.length ? 'notEmpty' : ''">
    <div
      class="alarmItem animate__animated"
      :class="item.class"
      v-for="(item, index) in alarmList"
      :key="index"
    >
      <div class="alarmTitle">{{ item.alarmName }}</div>
      <div class="alarmContent">
        <div class="contentItem">报警描述: {{ item.description }}</div>
        <div class="contentItem">报警时间: {{ item.tsName }}</div>
      </div>
      <div class="btntBox" :class="`lv${item.lv}BdColor`">
        <div class="btnItem" :class="`lv${item.lv}BdColor`">
          <el-button
            class="comfirmAll"
            size="small"
            type="text"
            @click="comfirm(item)"
            >确认本条</el-button
          >
        </div>
        <div class="btnItem">
          <el-button
            class="comfirmAll"
            size="small"
            type="text"
            @click="comfirmAll"
            >全部确认</el-button
          >
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { confirmAlart } from "@api/api.js";
export default {
  data() {
    return {
      alarmList: [],
      seriousWarning: false,
      audioElement: null,
      ws: null,
      timeConnect: 0,
      limitConnect: 5,
    };
  },

  created() {
    this.webSocketInit(
      `ws://10.81.3.154:6014/websocket/${this.$store.state.user.authToken}`
    );
  },

  unmounted() {
    this.ws?.close();
  },

  methods: {
    getAlarmName(alarmItem) {
      let alarmName = "";
      if (alarmItem.deviceType === "booststation") {
        alarmName += "升压站";
      } else if (alarmItem.deviceType === "inverter") {
        alarmName += "逆变器";
      } else if (alarmItem.deviceType === "windturbine") {
        alarmName += "风机";
      }

      if (alarmItem.alarmType === "custom") {
        alarmName += "自定义";
      }
      return `${alarmName}报警`;
    },

    comfirm(item) {
      this.$confirm("您确定要执行此操作吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        item.class = `animate__bounceOutRight lv${item.lv}`;
        item.confirm = true;
        setTimeout(() => {
          item.class = `animate__bounceOutRight hidden lv${item.lv}`;
          confirmAlart([item]).then((res) => {
            if (res.code === 200) {
              this.BASE.showMsg({
                type: "success",
                msg: "确认成功",
              });
              this.$store.commit("removeWarning", item);
              this.playAudioEffect();
            }
          });
        }, 500);
      });
    },

    comfirmAll() {
      this.$confirm("您确定要执行此操作吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        for (let i = 0; i < this.alarmList.length; i++) {
          if (!this.alarmList[i].comfirm) {
            this.alarmList[
              i
            ].class = `animate__bounceOutRight lv${this.alarmList[i].lv}`;
            this.alarmList[i].confirm = true;
            setTimeout(() => {
              this.alarmList[
                i
              ].class = `animate__bounceOutRight hidden lv${this.alarmList[i].lv}`;
            }, 500);
          }
        }

        confirmAlart(this.alarmList).then((res) => {
          if (res.code === 200) {
            this.BASE.showMsg({
              type: "success",
              msg: "全部确认成功",
            });
            this.$store.commit("emptyWarning");
            this.playAudioEffect();
          }
        });
        this.playAudioEffect();
      });
    },

    getRandomNumber(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min;
    },

    playAudioEffect() {
      const fiveLvWarning = this.alarmList.some((ele) => {
        return ele.lv === 5 && !ele.confirm;
      });

      const fourLvWarning = this.alarmList.some((ele) => {
        return ele.lv === 4 && !ele.confirm;
      });

      if (fiveLvWarning && !this.seriousWarning) {
        this.seriousWarning = true;
        this.audioElement = new Audio();
        this.audioElement.src = "./static/sound/lv5.mp3";
        this.audioElement.loop = true;
        this.audioElement?.play();
      } else if (fourLvWarning && !this.seriousWarning) {
        this.audioElement = new Audio();
        this.audioElement.src = "./static/sound/lv4.mp3";
        this.audioElement.addEventListener("ended", () => {
          this.audioElement.removeEventListener(
            "ended",
            this.stopPlayAudioEffect
          );
        });
        this.audioElement?.play();
      } else {
        if (!this.seriousWarning) {
          this.stopPlayAudioEffect();
        }
      }
    },

    stopPlayAudioEffect() {
      this.seriousWarning = false;
      if (this.audioElement) {
        this.audioElement.pause();
        this.audioElement.currentTime = 0;
        this.audioElement.loop = false;
      }
      this.audioElement = null;
    },

    webSocketInit(serveIP) {
      if ("WebSocket" in window) {
        this.ws = new WebSocket(serveIP);
        this.ws.onmessage = (res) => {
          let alarmItem = JSON.parse(res.data);
          if (alarmItem) {
            const alarmOption = {
              lv: alarmItem.rank,
              id: alarmItem.id,
              class: `animate__bounceInRight lv${alarmItem.rank}`,
              confirm: alarmItem.isClose,
              alarmType: alarmItem.alarmType,
              alarmName: this.getAlarmName(alarmItem),
              description: alarmItem.description,
              deviceType: alarmItem.deviceType,
              oval: alarmItem.oval,
              triggerType: alarmItem.triggerType,
              ts: alarmItem.ts,
              tsName: new Date(alarmItem.ts).formatDate("yyyy-MM-dd hh:mm:ss"),
            };
            this.alarmList.push(alarmOption);
            this.$store.commit("setWarning", alarmOption);
            this.alarmList.sort((a, b) => {
              return b.lv - a.lv;
            });
            this.playAudioEffect();
          }
        };

        this.ws.onclose = () => {
          this.ws = null;
        };

        this.ws.onopen = () => {
          this.timeConnect = 0;
          console.log("WebSocket 服务已建立");
        };

        this.ws.onerror = () => {
          this.reconnect(serveIP);
        };
      } else {
        this.BASE.showMsg({
          msg: "当前浏览器不支持 WebSocket ，请更换浏览器后重试",
        });
      }
    },

    reconnect(serveIP) {
      if (this.timeConnect < this.limitConnect) {
        console.log(`webSocket 连接失败，第 ${++this.timeConnect} 次重连`);
        setTimeout(() => {
          this.webSocketInit(serveIP);
        }, 2000);
      } else {
        console.log("webSocket 连接已超时");
        this.BASE.showMsg({
          showClose: true,
          duration: 0,
          msg: `webSocket 连接超时，实时报警获取失败`,
        });
        this.ws?.close();
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.alarmBox {
  width: 200px;
  height: 100%;
  padding: 0 12px 0 30px;
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 5000;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  font-size: 12px;
  overflow-y: scroll;
  pointer-events: none;
  transition: 0.2s;

  .alarmItem {
    width: 100%;
    box-sizing: border-box;
    border-radius: 8px;
    border: 1px solid #ebeef5;
    background: #1890ff;
    margin-bottom: 12px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    color: #fff;
    pointer-events: auto;
    cursor: pointer;
    .alarmTitle {
      display: flex;
      justify-content: flex-start;
      align-content: center;
      width: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      padding: 0 8px;
      margin-top: 8px;
    }

    .alarmContent {
      width: calc(100% - 16px);
      display: flex;
      justify-content: flex-start;
      align-items: flex-start;
      flex-wrap: wrap;
      margin-top: 4px;
      padding: 0 8px;

      .contentItem {
        width: 100%;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        margin-bottom: 2px;
        word-wrap: break-word;

        &:last-child {
          margin-bottom: 0;
        }
      }
    }

    .btntBox {
      display: flex;
      width: 100%;
      justify-content: center;
      align-items: center;
      margin-top: 4px;
      border-top: 1px solid red;

      .btnItem {
        width: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 4px 0;

        .el-button {
          padding: 0;
          width: 45%;
          height: 20px;
          min-height: 20px;
        }

        .confirmCurrent {
          color: #67c23a;
        }
        .confirmAll {
          color: #e6a23c;
        }

        &:first-child {
          border-right: 1px solid red;
        }
      }
    }
    &.lv5 {
      background: #fef0f0;
      border: 1px solid #f56c6c;
      color: #f56c6c;
    }

    &.lv4 {
      background: #f0f9eb;
      border: 1px solid #e6a23c;
      color: #e6a23c;
    }

    &.lv1,
    &.lv2,
    &.lv3 {
      background: #fdf6ec;
      border: 1px solid #67c23a;
      color: #67c23a;
    }

    .lv1BdColor,
    .lv2BdColor,
    .lv3BdColor {
      border-color: #67c23a !important;
    }

    .lv4BdColor {
      border-color: #e6a23c !important;
    }

    .lv5BdColor {
      border-color: #f56c6c !important;
    }

    &.hidden {
      height: 0;
      padding: 0;
      margin-bottom: 0;
      border: 0;
      transition: 0.2s;
      overflow: hidden;
    }
  }

  &::-webkit-scrollbar {
    width: 0; /* 隐藏Webkit浏览器的滚动条宽度 */
    height: 0; /* 隐藏Webkit浏览器的滚动条高度 */
  }

  &.notEmpty:hover {
    background: rgba(0, 0, 0, 0.12);
    box-shadow: 0 0 12px rgba(0, 0, 0, 0.12);
    transition: 0.2s;
  }
}
</style>
