<template>
  <div
    v-loading="loading"
    class="l-flex--col c-tree"
  >
    <warning
      v-if="error"
      @click="getDevices"
    />
    <template v-else-if="!loading">
      <div class="l-flex__none l-flex--row has-bottom-padding">
        <div class="l-flex__auto" />
        <search-input
          v-model.trim="deviceName"
          class="l-flex__none c-sibling-item"
          placeholder="设备名称"
          @search="getDevices"
        />
        <button
          class="l-flex__none c-sibling-item o-button"
          @click="getDevices"
        >
          搜索
        </button>
      </div>
      <template v-if="devices.length">
        <div
          class="l-flex__none l-flex--row c-tree__title c-tree__content u-pointer"
          @click="onAllToggle"
        >
          <span class="l-flex__auto">全部设备</span>
          <el-checkbox
            :value="isAll"
            :indeterminate="isIndeterminate"
            class="l-flex__none c-tree__checkbox"
          />
        </div>
        <div class="l-flex__auto l-flex--col c-tree__list u-overflow-y--auto">
          <div
            v-for="device in devices"
            :key="device.id"
            class="c-tree__content u-pointer"
            @click="onDeviceToggle(device)"
          >
            <span class="c-tree__label">{{ device.name }} {{ showRatio ? device.resolutionRatio : '' }}</span>
            <el-checkbox
              :value="device.checked"
              class="l-flex__none c-tree__checkbox"
            />
          </div>
        </div>
      </template>
      <div
        v-else
        class="c-tree__empty"
      >
        暂无设备
      </div>
    </template>
  </div>
</template>

<script>
import { getDevices } from '@/api/device'

export default {
  name: 'DeviceTree',
  props: {
    showRatio: {
      type: [Boolean, String],
      default: false
    },
    invoke: {
      type: Function,
      default: getDevices
    }
  },
  data () {
    return {
      loading: false,
      error: false,
      deviceName: '',
      isAll: false,
      isIndeterminate: false,
      devices: []
    }
  },
  created () {
    this.getDevices()
  },
  methods: {
    emitChange () {
      this.$emit('change', this.isAll || this.isIndeterminate ? this.devices.filter(({ checked }) => checked) : [])
    },
    getDevices () {
      this.loading = true
      this.error = false
      this.isAll = false
      this.isIndeterminate = false
      this.emitChange()
      this.fetchDevices().then(
        data => {
          data.forEach(device => {
            device.checked = false
          })
          this.devices = data
        },
        () => {
          this.error = true
        }
      ).finally(() => {
        this.loading = false
      })
    },
    fetchDevices (total = 999) {
      return this.invoke({
        pageNum: 1,
        pageSize: total,
        name: this.deviceName
      }).then(({ data, totalCount }) => {
        if (totalCount > total) {
          return this.fetchDevices(totalCount)
        }
        return data
      })
    },
    onAllToggle () {
      this.isAll = !this.isAll
      this.isIndeterminate = false
      const checked = this.isAll
      this.devices.forEach(device => {
        device.checked = checked
      })
      this.emitChange()
    },
    onDeviceToggle (device) {
      device.checked = !device.checked
      this.isAll = !this.devices.some(({ checked }) => !checked)
      this.isIndeterminate = !this.isAll && this.devices.some(({ checked }) => checked)
      this.emitChange()
    },
    reset () {
      this.deviceName = ''
      this.getDevices()
    }
  }
}
</script>
