<template>
  <wrapper margin>
    <div
      class="l-flex--row c-sibling-item--v c-count u-pointer"
      @click="onClickMineDevices"
    >
      <div class="l-flex__none u-color--black u-bold">我的设备</div>
      <div class="l-flex__none c-count__item u-color--black u-bold 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-bold 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 dark u-bold 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-bold 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 has-active u-pointer"
        @click.stop="onRefresh"
      />
    </div>
    <div
      v-if="__PLACEHOLDER__"
      class="c-sibling-item--v far 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-sibling-item--v far">
      <device
        v-for="item in deviceOptions.list"
        :key="item.id"
        :device="item"
      />
    </div>
    <div
      v-if="!deviceOptions.loaded"
      class="c-sibling-item--v far u-text-center"
    >
      <i class="el-icon-loading" />
    </div>
    <iframe
      v-if="elk"
      class="c-sibling-item--v far"
      style="height: 850px; border: none;"
      :src="elk"
    />
  </wrapper>
</template>

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

export default {
  name: 'Dashboard',
  components: {
    Card,
    Device
  },
  data () {
    return {
      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) {
      if (this.deviceOptions.loaded) {
        return
      }
      const result = /^\d+\/(\d+)\/(online|offline)$/.exec(topic)
      if (!result) {
        return
      }
      const deviceId = result[1]
      const status = result[2]
      const device = this.deviceOptions.list.find(({ id }) => id === deviceId)
      if (device) {
        const onlineStatus = device.onlineStatus === 1 ? 'online' : 'offline'
        if (status === onlineStatus) {
          return
        }
      } else if (status === 'offline') {
        return
      }
      this.refreshDevices()
    },
    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().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,
        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)
          }
        }
      )
    },
    onClickMineDevices () {
      this.$router.push({
        name: 'device-list'
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.c-count {
  justify-content: space-between;
  padding: 8px $spacing;
  border-radius: $radius;
  background-color: #fff;

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

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

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

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