<template>
  <wrapper
    class="c-dashboard"
    margin
  >
    <div class="l-flex--row c-dashboard__block c-count">
      <div class="l-flex__none l-flex--row">
        设备分类：
        <!-- <el-select
          v-model="product"
          placeholder="请选择产品"
          :loading="productOptions.fetching"
          @visible-change="getProducts"
          @change="onProductChange"
        >
          <el-option
            v-for="item in productOptions.list"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select> -->
        <schema-select
          v-model="product"
          :schema="productSelectSchema"
          @change="onProductChange"
        />
      </div>
      <div class="l-flex__none c-count__item u-color--black u-text-center">
        <div>设备总数</div>
        <i
          v-if="monitor.loading"
          class="el-icon-loading"
        />
        <div v-else>{{ monitor.total }}</div>
      </div>
      <div class="l-flex__none c-count__item u-color--success dark u-text-center">
        <div>● 在线</div>
        <i
          v-if="monitor.loading"
          class="el-icon-loading"
        />
        <div v-else>{{ monitor.online }}</div>
      </div>
      <div class="l-flex__none c-count__item u-color--error light u-text-center">
        <div>● 离线</div>
        <i
          v-if="monitor.loading"
          class="el-icon-loading"
        />
        <div v-else>{{ monitor.offline }}</div>
      </div>
      <div class="l-flex__none c-count__item u-color--info u-text-center">
        <div>● 未启用</div>
        <i
          v-if="monitor.loading"
          class="el-icon-loading"
        />
        <div v-else>{{ monitor.inactive }}</div>
      </div>
      <i
        class="c-count__refresh el-icon-refresh u-pointer"
        @click="onRefresh"
      />
    </div>
    <div
      v-if="__PLACEHOLDER__"
      class="c-dashboard__block c-cards"
    >
      <card
        class="c-cards__item"
        type="info"
        title="总次数"
        tip="100"
      />
      <card
        class="c-cards__item"
        type="safety"
        title="安全异常"
        desc="累计异常数：30"
      />
      <card
        class="c-cards__item"
        type="performance"
        title="性能异常"
        desc="累计异常数：30"
        count="3"
      />
      <card
        class="c-cards__item"
        type="log"
        title="日志异常"
        desc="累计异常数：30"
        count="10"
      />
      <card
        class="c-cards__item"
        type="date"
        title="即将空闲排期"
        count="100"
      />
    </div>
    <div class="l-grid--info c-dashboard__block">
      <device
        v-for="item in deviceOptions.list"
        :key="item.id"
        :device="item"
      />
    </div>
    <div
      v-if="!deviceOptions.loaded"
      class="c-dashboard__block u-text-center"
    >
      <i class="el-icon-loading" />
    </div>
    <iframe
      v-if="elk"
      class="c-dashboard__block"
      style="height: 850px; border: none;"
      :src="elk"
    />
  </wrapper>
</template>

<script>
import {
  subscribe,
  unsubscribe
} from '@/utils/mqtt'
import {
  getDevices,
  getProducts,
  getDeviceStatistics
} from '@/api/device'
import Card from './components/Card'
import Device from './components/Device'

export default {
  name: 'Dashboard',
  components: {
    Card,
    Device
  },
  data () {
    return {
      productSelectSchema: {
        remote: getProducts,
        pagination: true,
        placeholder: '全部产品',
        value: 'id',
        label: 'name'
      },
      product: void 0,
      monitor: { loading: true },
      deviceOptions: {
        list: [],
        loaded: false
      },
      elk: process.env.VUE_APP_SENSOR_ELK
    }
  },
  created () {
    this.$timer = -1
    this.refreshDevices(true)
    subscribe([
      '+/+/online',
      '+/+/offline',
      '+/+/calendar/update'
    ], this.onMessage)
  },
  beforeDestroy () {
    clearTimeout(this.$timer)
    this.monitor = { loading: true }
    unsubscribe([
      '+/+/online',
      '+/+/offline',
      '+/+/calendar/update'
    ], this.onMessage)
  },
  methods: {
    onMessage (topic) {
      const result = /^(\d+)\/(\d+)\/(online|offline)$/.exec(topic)
      if (result && (!this.product || this.product === result[1]) && this.deviceOptions.loaded) {
        const deviceId = result[2]
        const device = this.deviceOptions.list.find(({ id }) => id === deviceId)
        if (device) {
          const status = result[3]
          const onlineStatus = device.onlineStatus === 1 ? 'online' : 'offline'
          if (status === onlineStatus) {
            return
          }
        }
        this.onRefresh()
      }
    },
    onProductChange () {
      this.refreshDevices(true)
    },
    onRefresh () {
      this.refreshDevices()
    },
    refreshDevices (force) {
      if (!force && this.monitor.loading) {
        return
      }
      const monitor = {
        loading: true,
        total: '-',
        online: '-',
        offline: '-',
        inactive: '-'
      }
      this.monitor = monitor
      clearTimeout(this.$timer)
      this.deviceOptions = { loaded: false }
      getDeviceStatistics(this.product).then(({ data }) => {
        const { notEnabledTotal, offLineTotal, onLineTotal, total } = data
        monitor.total = total || 0
        monitor.online = onLineTotal || 0
        monitor.offline = offLineTotal || 0
        monitor.inactive = notEnabledTotal || 0
      }).finally(() => {
        monitor.loading = false
        if (!this.monitor.loading) {
          this.getDevices(this.monitor.total)
        }
      })
    },
    sort (a, b) {
      if (a.onlineStatus === 1) {
        return -1
      }
      return b.onlineStatus === 1 ? 1 : -1
    },
    getDevices (total) {
      if (!total || total === '-') {
        this.deviceOptions = { list: [], loaded: true }
        return
      }
      const options = { list: [], loaded: false }
      this.deviceOptions = options
      getDevices({
        pageNum: 1,
        pageSize: total,
        productId: this.product,
        activate: 2
      }, { custom: true }).then(
        ({ data }) => {
          options.list = data.sort(this.sort)
          options.loaded = true
        },
        ({ isCancel }) => {
          if (!isCancel && !this.monitor.loading) {
            this.$timer = setTimeout(total => {
              this.getDevices(total)
            }, 2000, total)
          }
        }
      )
    }
  }
}
</script>

<style lang="scss" scoped>
.c-dashboard {
  &__block + &__block {
    margin-top: $spacing;
  }
}

.c-count {
  justify-content: space-between;
  padding: 8px 16px;
  font-weight: bold;
  border-radius: $radius;
  background-color: #fff;

  &__item > div:first-child {
    margin-bottom: 10px;
  }

  &__refresh {
    font-size: 24px;
    color: $blue;
  }
}

.c-cards {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-column-gap: $spacing;

  &__item {
    min-width: 0;
  }
}
</style>
