<template>
  <section class="deviceSlider">
    <div class="mainPane" v-if="show">
      <div flex overview>
        <b>监控设备</b>
        <div>
          <div>设备总数：{{ overview.total }}</div>
          <div flex>在线设备：<p v-text="overview.online"/></div>
        </div>
        <el-progress type="circle" :width="40" :percentage="overview.percent" color="#19D286" :stroke-width="4"/>
      </div>
      <div flex search>
        <el-select v-model="search.bind" size="mini" placeholder="全部" clearable @change="onChange">
          <el-option v-for="(op,i) in dict.getDict('deviceStatus')" :key="i" :value="op.dictValue"
                     :label="op.dictName"/>
        </el-select>
        <el-input
            v-model="search.name"
            size="mini"
            placeholder="设备名称"
            v-throttle="handleTreeFilter"
            prefix-icon="el-icon-search"
            @clear="search.name = '', handleTreeFilter()" clearable/>
      </div>
      <div title>
        <div>设备列表</div>
        <el-button type="text" icon="iconfont iconResetting" @click="updateDev" size="mini" :loading="btnLoading">刷新</el-button>
      </div>
      <div fill class="deviceList">
        <el-tree ref="deviceTree" highlight-current :render-content="renderItem" :data="treeData" :props="propsConfig"
                 @node-click="handleNodeClick" @node-contextmenu="nodeContextmenu"
                 :filter-node-method="handleFilter"/>
        <ul
          v-if="isShowMenu && menuInfo.node.type==1 && permissions('video_config')"
          class="el-dropdown-menu el-popper"
          :style="{top: menuInfo.y + 'px', left: menuInfo.x + 'px', position: 'fixed', zIndex: 2023}"
          x-placement="top-end">
          <li class="el-dropdown-menu__item" @click="handleTreeCommand('edit', menuInfo.node)">修改名称</li>
          <li class="el-dropdown-menu__item" @click="handleTreeCommand('locate', menuInfo.node)">地图标绘</li>
        </ul>
      </div>
    </div>
    <div class="rightBtn" :class="{show}" @click="handleShow">
      <i class="iconfont iconArrow_Right"/>
    </div>
  </section>
</template>

<script>
export default {
  name: "deviceSlider",
  props: {
    show: Boolean,
    instance: Function,
    dict: Object,
    permissions: Function,
    renderItem: Function,
  },
  computed: {
    overview() {
      let total = this.list?.length || 0,
          online = this.list?.filter(e => e.deviceStatus == 1)?.length || 0
      return {
        total, online,
        percent: Math.ceil(online / total * 100) || 0
      }
    },
    propsConfig() {
      return {
        label: 'name',
        children: 'children'
      }
    },
    treeData() {
      let {list, noArea, staData} = this
      let meta = [staData?.reduce((t, e) => {
        return t.type <= e.type ? t : e
      }, {name: '读取中...'})]
      meta.map(p => this.addChild(p, [...staData, ...list].map(s => ({
        ...s,
        parentId: s.areaId || s.parent_id
      }))))
      return [...meta, {
        id: 'no_area',
        name: '未知区划',
        children: noArea
      }]
    }
  },
  data() {
    return {
      list: [],
      noArea: [],
      staData: [],
      name: '',
      isShowMenu: false,
      search: {
        bind: ''
      },
      menuInfo: {
        x: '',
        y: '',
        node: {}
      },
      btnLoading: false,
    }
  },
  methods: {
    handleShow() {
      this.$emit('update:show', !this.show)
    },

    bindEvent() {
      this.isShowMenu = false
    },
    getDevices() {
      this.instance.post(`/app/appzyvideoequipment/tree`, null, {
        params: {
          size: 999
        }
      }).then(res => {
        if (res?.data) {
          this.staData = res.data.count
          this.list = res.data.list
          this.noArea = res.data.noArea
          this.$emit('list', this.list)
        }
      })
    },

    updateDev() {
      this.btnLoading = true
      this.instance.post(`/app/appzyvideoequipment/sync`, null, {
        timeout: 1000000
      }).then(res => {
        if (res.code == 0) {
          this.$message.success('更新成功')
          this.getDevices()
        }
        this.btnLoading = false
      }).catch(() => {
        this.btnLoading = false
      })
    },

    handleTreeCommand(e, node) {
      this.$emit('treeCommand', {
        type: e,
        node
      })
    },

    nodeContextmenu(e, node) {
      this.isShowMenu = true
      let y = e.y + 6
      if (y + 202 > document.body.clientHeight) {
        y = y - 202
      }
      this.menuInfo = {
        x: e.x + 16, y,
        node
      }
    },
    handleNodeClick(data) {
      this.isShowMenu = false
      this.$emit('select', data)
    },
    handleFilter(v, data) {
      if (!v) {
        return !this.search.bind ? true : data.deviceStatus === this.search.bind
      }

      return data?.name?.indexOf(v) > -1 && (!this.search.bind ? true : data.deviceStatus === this.search.bind)
    },
    handleTreeFilter() {
      this.$refs.deviceTree?.filter(this.search.name)
    },
    onChange() {
      this.$refs.deviceTree?.filter(this.search.name)
    },
    
  },

  created() {
    this.$dict.load("deviceStatus").then(()=>{
      this.getDevices()
    })
  },

  mounted() {
    document.querySelector('html').addEventListener('click', this.bindEvent)
  }
}
</script>

<style lang="scss" scoped>
.deviceSlider {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  color: #fff;
  overflow: hidden;

  div[flex] {
    display: flex;
    align-items: center;
  }

  .deviceList {
    overflow: auto;

    ::v-deep .el-tree {
      width: -webkit-fit-content;
      width: -moz-fit-content;
      width: fit-content;
      min-width: 100%;
    }

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

    &::-webkit-scrollbar-thumb {
      box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
      background: #535353;
    }

    &::-webkit-scrollbar-track {
      box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
      background: #fff;
    }
  }

  div[fill] {
    flex: 1;
    min-width: 0;
    min-height: 0;
  }

  .mainPane {
    width: 280px;
    height: 100%;
    background: #333C53;
    display: flex;
    flex-direction: column;
    padding-top: 16px;
    overflow: hidden;
    box-sizing: border-box;

    b {
      font-size: 18px;
    }

    div[overview], div[search] {
      box-sizing: border-box;
      font-size: 12px;
      justify-content: space-between;
      padding: 0 16px;
      gap: 4px;
      margin-bottom: 16px;

      ::v-deep.el-input__inner {
        color: #fff;
      }
    }

    div[title] {
      height: 28px;
      background: #3E4A69;
      padding: 0 16px;
      line-height: 28px;
      display: flex;
      justify-content: space-between;
      align-items: center;

      ::v-deep .el-button {
        padding: 0 4px;
        height: 28px;
        background: #3E4A69;
      }
      ::v-deep .el-button:hover {
        border: none;
      }
    }

    ::v-deep.deviceList {
      padding: 0 8px;

      .el-scrollbar {
        height: 100%;

        .el-scrollbar__wrap {
          box-sizing: content-box;
          padding-bottom: 17px;
        }
      }
    }

    ::v-deep .el-progress__text, p {
      color: #19D286;
    }

    ::v-deep .el-input__inner {
      background: #282F45;
      border: none;
    }

    ::v-deep .el-tree {
      background: transparent;
      color: #fff;

      .el-tree-node__content {
        background: transparent!important;
      }

      .el-tree-node__children .is-current > .el-tree-node__content {
        background: linear-gradient(90deg, #299FFF 0%, #0C61FF 100%)!important;
      }

      .el-tree-node__content:hover {
        background: transparent;
      }

      .el-tree-node__content {
        height: 32px;
      }
    }

    ::v-deep .el-input__icon {
      color: #89b;
    }
  }

  .rightBtn {
    width: 16px;
    height: 80px;
    background: url("https://cdn.cunwuyun.cn/monitor/drawerBtn.png");
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;

    .iconfont {
      transition: transform 0.2s;
    }


    &.show > .iconfont {
      transform: rotate(180deg);
    }
  }
}
</style>
