<template>
  <div class="c-device-group-level">
    <template v-if="hasData">
      <device-group-level-item
        v-for="item in groupOptions.list"
        :key="item.id"
        class="c-sibling-item--v far"
        v-bind="$attrs"
        :group="item"
        @volume="onVolume"
      />
      <volume-dialog ref="volumeDialog" />
    </template>
    <div
      v-else-if="groupOptions.loading"
      class="has-padding--v u-text--center"
    >
      <i class="el-icon-loading u-font-size--lg" />
    </div>
    <el-empty v-else />
  </div>
</template>

<script>
import { getDepartmentDeviceTreeByGroup } from '@/api/device'
import groupMixin from './mixins/group.js'
import DeviceGroupLevelItem from './DeviceGroupLevelItem.vue'
import VolumeDialog from './VolumeDialog.vue'

export default {
  name: 'DeviceGroupLevel',
  components: {
    DeviceGroupLevelItem,
    VolumeDialog
  },
  mixins: [groupMixin],
  inject: ['dashboard'],
  props: {
    path: {
      type: String,
      required: true
    }
  },
  computed: {
    hasData () {
      return this.groupOptions.list.length > 0
    }
  },
  watch: {
    path () {
      this.refreshGroups(true)
    }
  },
  methods: {
    refreshGroups (force) {
      if (!this.path || !force && this.groupOptions.loading) {
        return
      }
      this.onResetGroupOptions()

      const groupOptions = this.createGroupOptions({ loading: true })
      this.groupOptions = groupOptions
      this.onChanged()

      getDepartmentDeviceTreeByGroup(this.path, { custom: true }).then(
        ({ data }) => {
          if (groupOptions.ignore) {
            return
          }
          const cache = { list: [], map: {}, topics: [] }
          this.flatTree('', data, cache)
          groupOptions.list = cache.list
          groupOptions.map = cache.map
          groupOptions.loaded = true
          this.onChanged()
          this.onSubscribe(cache.topics)
        },
        ({ isCancel }) => {
          if (isCancel || groupOptions.ignore) {
            return
          }
          this.$timer = setTimeout(this.refreshGroups, 2000)
        }
      ).finally(() => {
        groupOptions.loading = false
      })
    },
    flatTree (parent, { id = 'root', name, children, devices }, cache) {
      const group = parent && name ? `${parent} / ${name}` : name
      if (devices.length) {
        cache.list.push({
          id,
          name: group || '我的部门',
          children: devices.map(device => {
            const item = this.transformDevice(device)
            cache.map[item.id] = item
            cache.topics.push(...this.createTopics(item))
            return item
          })
        })
      }
      children?.forEach(node => {
        this.flatTree(group, node, cache)
      })
    },
    onChanged () {
      this.$emit('change', [...this.groupOptions.list])
    },
    onVolume ({ value, device }) {
      this.$refs.volumeDialog.show(value, device)
    }
  }
}
</script>

<style lang="scss" scoped>
.c-device-group-level {
  min-height: 400px;
}
</style>
