import {
  subscribe,
  unsubscribe,
  publish
} from '@/utils/mqtt'
import { parseTime } from '@/utils'
import request from '@/utils/request'

export let opend = false
const deviceMap = {}
export const deviceMessage = [
  { id: 'other', name: '其他', list: [] }
]
export const devices = [
  { id: 'all', name: '全部' },
  { id: 'other', name: '其他' }
]

export function start () {
  if (!opend) {
    opend = true
    subscribe('+/#', onMessage)
  }
}

export function stop () {
  if (opend) {
    opend = false
    unsubscribe('+/#', onMessage)
  }
}

export function clear () {
  deviceMessage.forEach(item => {
    item.list.splice(0, item.list.length)
  })
}

export function send (topic, message, encode) {
  return publish(topic, message, encode)
}

function onMessage (topic, message) {
  const result = /^\d+\/(\d+)(.+)$/.exec(topic)
  if (result) {
    const id = result[1]
    getDevice(id)
    deviceMessage[deviceMap[id].index].list.unshift({
      id: Math.random().toString(16).slice(2),
      time: parseTime(Date.now()),
      topic: result[2],
      desc: message
    })
  } else {
    deviceMessage[0].list.unshift({
      id: Math.random().toString(16).slice(2),
      time: parseTime(Date.now()),
      topic,
      desc: message
    })
  }
}

function getDevice (id) {
  if (deviceMap[id]?.loading || deviceMap[id]?.loaded) {
    return
  }
  if (!deviceMap[id]) {
    deviceMap[id] = { index: deviceMessage.length, loading: true, loaded: false }
    deviceMessage.push({ id, name: id, list: [] })
    devices.push({ id, name: id })
  }
  deviceMap[id].loading = true
  request({
    url: `/device/${id}`,
    method: 'get',
    custom: true,
    background: true
  }).then(({ data }) => {
    deviceMap[id].loaded = true
    if (data) {
      const { name, serialNumber, mac } = data
      const device = deviceMessage.find(item => item.id === id)
      device.name = name
      device.serialNumber = serialNumber
      device.mac = mac
      devices.find(item => item.id === id).name = name
    }
  }).finally(() => {
    deviceMap[id].loading = false
  })
}
