<script>
import { ThirdPartyDevice } from '@/constant'
import { publish } from '@/utils/mqtt'
import {
  Status,
  RELAY_KEY,
  GET_MULTI_POWER_TIMING,
  SET_MULTI_POWER_TIMING,
  addListener,
  removeListener,
  addInjectListener,
  removeInjectListener
} from '@/utils/adapter'
import { savePowerLogger } from '@/api/platform'

export default {
  name: 'DevicePowerTask',
  props: {
    device: {
      type: Object,
      required: true
    },
    tasks: {
      type: Array,
      required: true
    }
  },
  data () {
    return {
      status: 0,
      retryCount: 0,
      cardInfo: null
    }
  },
  mounted () {
    this.$timer = -1
    addListener(this.device.id, this.onMessage)
    addInjectListener(this.device.id, this.onInjectMessage)
  },
  beforeDestroy () {
    clearTimeout(this.$timer)
    removeListener(this.device.id, this.onMessage)
    removeInjectListener(this.device.id, this.onInjectMessage)
  },
  methods: {
    onMessage (value) {
      const multiCard = value[ThirdPartyDevice.MULTI_FUNCTION_CARD]
      if (multiCard.status === Status.OK) {
        if (!this.cardInfo) {
          const { connectIndex, portIndex } = multiCard.powers[0]
          const type = multiCard.powers.find(({ type }) => type === '屏体电源' || type === '默认')?.type || multiCard.powers.find(({ type }) => !!type)?.type
          this.cardInfo = { type, connectIndex, portIndex }
          if (type) {
            this.onSync()
          } else {
            this.status = 4
          }
        }
      }
    },
    onInjectMessage (message) {
      if (message.messageId === this.$messageId) {
        this.$messageId = null
        if (message.code !== 0) {
          this.status = 3
          return
        }
        const data = message.data ? JSON.parse(message.data.replaceAll("'", '"')) : {}
        if (data.logined === false) {
          this.status = 3
          return
        }
        switch (message.function) {
          case GET_MULTI_POWER_TIMING:
            clearTimeout(this.$timer)
            if (this.retryCount > 0) {
              this.checkTasks(data.data.filter(({ connectIndex, portIndex }) => connectIndex !== RELAY_KEY && portIndex !== RELAY_KEY))
            } else {
              this.sendTasks(data.data.filter(({ connectIndex, portIndex }) => connectIndex !== RELAY_KEY && portIndex !== RELAY_KEY))
            }
            break
          case SET_MULTI_POWER_TIMING:
            clearTimeout(this.$timer)
            this.status = 2
            break
          default:
            break
        }
      }
    },
    onSync () {
      this.$timer = setTimeout(this.retry, 5000)
      this.sendTopic(GET_MULTI_POWER_TIMING, { sn: this.device.serialNumber }).then(messageId => {
        this.$messageId = messageId
      }, () => {
        clearTimeout(this.$timer)
      })
    },
    createTasks () {
      const type = this.cardInfo.type
      return this.tasks.map(task => {
        return {
          ...task,
          type
        }
      })
    },
    sendTasks (tasks) {
      this.status = 1
      const { connectIndex, portIndex } = this.cardInfo
      const newTasks = this.createTasks()
      this.$timer = setTimeout(this.retry, 5000)
      this.sendTopic(SET_MULTI_POWER_TIMING, {
        sn: this.device.serialNumber,
        taskInfo: tasks.length
          ? tasks.map(({ enable, conditions, ...options }) => {
            return {
              ...options,
              enable: true,
              conditions: [
                ...newTasks,
                ...conditions.map(({ status, ...task }) => task)
              ]
            }
          })
          : [{
            connectIndex,
            portIndex,
            enable: true,
            conditions: newTasks
          }]
      }).then(messageId => {
        this.$messageId = messageId
        savePowerLogger({
          description: `设备【${this.device.name}】 新增电源定时任务 ${this.cardInfo.type}`,
          method: '电源定时任务设置',
          params: JSON.stringify({
            id: this.device.id,
            name: this.device.name,
            tasks: this.tasks
          })
        })
      }, () => {
        clearTimeout(this.$timer)
      })
    },
    retry () {
      this.retryCount += 1
      this.status = 1
      this.onSync()
    },
    checkTasks (tasks) {
      const map = {}
      this.tasks.forEach(({ flag }) => {
        map[flag] = true
      })
      for (let i = 0; i < tasks.length; i++) {
        if (tasks[i].conditions.some(({ flag }) => map[flag])) {
          this.status = 2
          return
        }
      }
      this.sendTasks(tasks)
    },
    sendTopic (invoke, inputs) {
      const timestamp = `${Date.now()}`
      const messageId = `${invoke}_${timestamp}`
      return publish(
        `${this.device.productId}/${this.device.id}/multifunctionCard/invoke`,
        JSON.stringify({
          messageId,
          timestamp,
          'function': invoke,
          inputs: JSON.stringify(inputs || [])
        }),
        true
      ).then(() => messageId)
    }
  },
  render (h) {
    if (this.status === 3 || this.status === 4) {
      return h('el-tooltip', {
        props: {
          content: this.status === 3 ? '连接失败，请联系管理员' : '无可用端口，请联系管理员',
          placement: 'left',
          enterable: false
        }
      }, [
        h('el-tag', {
          staticClass: 'o-tag u-readonly',
          props: {
            size: 'medium',
            'disable-transitions': true,
            type: 'danger'
          }
        }, '失败')
      ])
    }
    return h('el-tag', {
      staticClass: 'o-tag u-readonly',
      props: {
        size: 'medium',
        'disable-transitions': true,
        type: ['primary', 'warning', 'success'][this.status]
      }
    }, ['等待', this.retryCount === 0 ? '同步中' : `重试(${this.retryCount})`, '成功'][this.status])
  }
}
</script>
