<template>
  <div id="supervisory">
    <div class="side-area">
      <el-input
        prefix-icon="el-icon-search"
        placeholder="监控点名称"
        style="margin-bottom: 12px"
        v-model="filterText"
      ></el-input>
      <ShadowContainer class="tree-shadow-container">
        <div class="tree-container">
          <el-tree
            ref="tree"
            :data="treeData"
            :props="defaultProps"
            icon-class="el-icon-arrow-right"
            :render-content="renderContent"
            :filter-node-method="filterNode"
          ></el-tree>
        </div>
      </ShadowContainer>
    </div>
    <div class="video-out-container">
      <div class="splice-screen">
        <el-button
          :class="[activeSplice == 1 ? 'active' : '']"
          @click="activeSplice = 1"
          >一分屏</el-button
        >
        <el-button
          :class="[activeSplice == 4 ? 'active' : '']"
          @click="activeSplice = 4"
          >四分屏</el-button
        >
        <el-button
          :class="[activeSplice == 6 ? 'active' : '']"
          @click="activeSplice = 6"
          >六分屏</el-button
        >
        <el-button
          :class="[activeSplice == 9 ? 'active' : '']"
          @click="activeSplice = 9"
          >九分屏</el-button
        >
        <el-button @click="closeAll">全部关闭</el-button>
        <el-button @click="viewAll">全部预览</el-button>
      </div>
      <div class="video-area">
        <div
          v-for="(videoImg, index) in activeSplice"
          :key="index"
          :class="[
            'camera',
            activeIndex == index ? 'active' : '',
            `camera-in-${activeSplice}`,
          ]"
        >
          <div v-if="!cameraList[index] || cameraList[index].player === null">
            <div class="video-info">
              <div class="video-no">{{ index + 1 }}</div>
              <div class="video-description">暂无画面~</div>
            </div>
          </div>
          <div v-else class="video-pic" :ref="`video-js-container-${index}`">
            <i class="el-icon-circle-close" @click="closeSingle(index)"></i>
            <div
              :id="[`video-container-${index + 1}`]"
              style="height: 100%"
            ></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { getVideoTreeData, getVideoLiveAddressUrl } from "@/api/index";
require("vue-video-player/node_modules/video.js/dist/video-js.css");
import videojs from "video.js";
import "videojs-contrib-hls";
export default {
  name: "Supervisory",
  data() {
    return {
      filterText: "",
      treeData: [],

      defaultProps: {
        children: "children",
        label: "label",
      },
      cameraList: [],
      activeIndex: null,
      liveVisible: false,
      singlePlayer: null,
      activeSplice: 4,
    };
  },
  mounted() {
    this.getVideoTreeData();
  },
  methods: {
    getVideoTreeData() {
      getVideoTreeData().then((res) => {
        this.treeData = this.handleData(res.data);
      });
    },
    handleData(data) {
      return data.map((item) => {
        return {
          label: item.area_name,
          children: this.handleChildrenData(item.device_data),
          device_count: item.device_count,
        };
      });
    },
    handleChildrenData(data) {
      return data.map((item, index) => {
        return {
          label: item.device_name,
          index: index,
          id: item.id,
        };
      });
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    renderContent(h, { node, data }) {
      return (
        <span
          class="custom-tree-node"
          on-click={() => this.selectNode(node, data)}
        >
          <span>
            <span
              class={
                node.level == 1
                  ? "iconfont icon-shipinjiankong-1"
                  : "iconfont icon-shipinjiankong-2"
              }
              style="margin-right:6px"
            ></span>
            {node.label}
          </span>
          {node.level == 1 && <span>{data.device_count}</span>}
        </span>
      );
    },
    selectNode(node, data) {
      if (node.level > 1) {
        const playerArray = this.cameraList.map((item) => {
          return item.player;
        });
        const cameraIdList = this.cameraList.map((item) => {
          return item.id;
        });
        if (cameraIdList.indexOf(data.id) != -1) {
          return this.$message.warning("该监控已存在!");
        }
        const nullIndex = playerArray.indexOf(null);
        if (nullIndex != -1) {
          this.cameraList[nullIndex] = {
            player: undefined,
            id: data.id,
          };
          this.$forceUpdate();
          getVideoLiveAddressUrl(data.id).then((res) => {
            this.$nextTick(() => {
              const myVideoDiv = document.getElementById(
                `video-container-${nullIndex + 1}`
              );
              myVideoDiv.innerHTML = `<video
            id="singleVideo${nullIndex + 1}"
            autoplay="autoplay"
            class="video-js vjs-default-skin"
          ></video>`;
              const singlePlayer = videojs(`singleVideo${nullIndex + 1}`, {
                autoplay: true, // 自动播放
                controls: true, // 控件显示
                preload: "auto", //定义视频加载模式
                loop: true, //是否循环播放
              });
              singlePlayer.src({
                src: res.data.live_address_url,
                type: "application/x-mpegURL",
              });
              singlePlayer.play();
              this.cameraList[nullIndex].player = singlePlayer;
            });
          });
        } else {
          if (this.cameraList.length == this.activeSplice) {
            return this.$message.warning("请先关闭多余的监控!");
          }
          this.cameraList.push({
            player: undefined,
            id: data.id,
          });
          this.$forceUpdate();
          getVideoLiveAddressUrl(data.id).then((res) => {
            this.$nextTick(() => {
              const myVideoDiv = document.getElementById(
                `video-container-${this.cameraList.length}`
              );
              myVideoDiv.innerHTML = `<video
          id="singleVideo${this.cameraList.length}"
          autoplay="autoplay"
          class="video-js vjs-default-skin"
        ></video>`;
              const singlePlayer = videojs(
                `singleVideo${this.cameraList.length}`,
                {
                  autoplay: true, // 自动播放
                  controls: true, // 控件显示
                  preload: "auto", //定义视频加载模式
                  loop: true, //是否循环播放
                }
              );
              singlePlayer.src({
                src: res.data.live_address_url,
                type: "application/x-mpegURL",
              });
              singlePlayer.play();
              this.cameraList[this.cameraList.length - 1].player = singlePlayer;
            });
          });
        }
      }
    },
    closeAll() {
      this.cameraList.map((item) => {
        item.player.dispose();
      });
      this.cameraList = [];
    },
    closeSingle(index) {
      this.cameraList[index].player.dispose();
      this.cameraList[index].player = null;
      this.cameraList[index].live_address_url = "";
      this.cameraList[index].id = "";
      this.$forceUpdate();
    },
    viewAll() {
      this.cameraList.map((item) => {
        item.player.dispose();
        item.player = null;
        item.id = "";
        item.live_address_url = "";
      });

      const allVideoIdArray = this.treeData
        .map((item) => {
          return item.children.map((child) => {
            return child.id;
          });
        })
        .flat();

      allVideoIdArray.map((id, index) => {
        this.cameraList.push({
          player: undefined,
          id: id,
        });
        getVideoLiveAddressUrl(id).then((res) => {
          this.$nextTick(() => {
            const myVideoDiv = document.getElementById(
              `video-container-${index + 1}`
            );
            myVideoDiv.innerHTML = `<video
          id="singleVideo${index + 1}"
          autoplay="autoplay"
          class="video-js vjs-default-skin"
        ></video>`;
            const singlePlayer = videojs(`singleVideo${index + 1}`, {
              autoplay: true, // 自动播放
              controls: true, // 控件显示
              preload: "auto", //定义视频加载模式
              loop: true, //是否循环播放
            });
            singlePlayer.src({
              src: res.data.live_address_url,
              type: "application/x-mpegURL",
            });
            singlePlayer.play();

            this.cameraList[index].player = singlePlayer;
          });
        });
      });
    },
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
    activeSplice(newValue, oldValue) {
      if (newValue < oldValue && this.cameraList.length > newValue) {
        for (let i = newValue; i < this.cameraList.length; i++) {
          this.cameraList[i].player = null;
          this.cameraList[i].id = "";
          this.cameraList[i].live_address_url = "";
        }
      }
    },
  },
};
</script>
<style lang="less" scoped>
@import "@/assets/common/element.less";

#supervisory {
  padding: 12px 20px;
  display: flex;
  justify-content: space-between;
  padding-bottom: 0;
  height: 100%;
  .side-area {
    width: 300px;
    height: 100%;
  }
}

::v-deep .custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
  font-size: 16px;
  line-height: 40px;
  letter-spacing: 1px;
  img {
    width: 20px;
    margin-top: 10px;
    margin-right: 8px;
    vertical-align: top;
  }
}

.tree-container {
  height: 100%;
  overflow-y: scroll;
}
.video-out-container {
  width: calc(100% - 312px);
}
.video-area {
  height: calc(97% - 55px);
  width: 100%;
  .camera {
    &:hover {
      border-color: #fff;
    }
    border: 1px solid #0f95d4;
    position: relative;
    float: left;
    box-sizing: border-box;
    &.camera-in-1 {
      width: 100%;
      height: 100%;
    }
    &.camera-in-4 {
      width: calc(50% - 2px);
      height: calc(100% / 2 - 2px);
    }
    &.camera-in-6 {
      width: calc(100% / 3);
      height: calc(100% / 3);
      display: inline-block;
      &:first-child {
        width: calc(calc(100% / 3) * 2);
        height: calc(calc(100% / 3 - calc(1px / 3)) * 2);
      }
    }
    &.camera-in-9 {
      width: calc(100% / 3 - 2px);
      height: calc(100% / 3 - 2px);
    }

    .video-info {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translateX(-50%) translateY(-50%);
      text-align: center;
      .video-no {
        font-size: 44px;
        font-weight: bold;
        color: #c6eaf9;
        margin-bottom: 12px;
      }
      .video-description {
        font-size: 16px;
        color: #c6eaf9;
        opacity: 0.3;
      }
    }
    .video-pic {
      padding: 8px;
      height: calc(100% - 16px);
      &:hover {
        .el-icon-circle-close {
          display: block;
          cursor: pointer;
        }
      }
      img {
        width: 100%;
        vertical-align: top;
        height: 100%;
      }
      .play {
        width: 100px;
        height: 100px;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
        cursor: pointer;
      }
    }
  }
}

.vueVideoPlayer {
  & .video-js {
    & .vjs-big-play-button {
      top: 50%;
      left: 50%;
      transform: translateX(-50%) translateY(-50%);
    }
  }
}
::v-deep .video-js {
  width: 100%;
  height: 100%;
}
.splice-screen {
  display: flex;
  justify-content: space-between;
  margin-bottom: 12px;
  .el-button {
    background: rgba(40, 137, 195, 0.2);
    color: #c6def9;
    font-size: 18px;
    border-color: rgba(33, 127, 247, 1);
    width: calc(100% / 5 - 20px);
    &.active {
      background: #00a2ff;
      color: #fff;
    }
  }
}
.el-icon-circle-close {
  display: none;
  color: #fff;
  font-size: 24px;
  position: absolute;
  right: 20px;
  top: 20px;
  z-index: 999;
}
.tree-shadow-container {
  height: calc(97% - 52px);
}
</style>