<template>
  <div class="l-flex--col center has-border radius has-padding">
    <i
      class="o-icon lg u-pointer"
      :class="iconClass"
      @click="invoke"
    />
    <div class="has-padding u-color--black u-bold">
      {{ powerStatusTip }}
    </div>
    <c-dialog
      ref="dialog"
      size="lg"
      title="PDU定时"
      :before-close="handleClose"
      @close="onClose"
    >
      <template #default>
        <tabbar
          :items="tabs"
          :active="active"
          @click="onClickTab"
        >
          <div
            v-if="hasChanged"
            class="u-font-size--sm u-color--error has-padding--h"
          >
            设置需点击【应用】后生效
          </div>
        </tabbar>
        <div
          v-loading="loading"
          class="l-flex__auto l-flex--col"
        >
          <schema-table
            :key="active"
            ref="table"
            :schema="schema"
          />
        </div>
      </template>
    </c-dialog>
    <pdu-task-dialog
      ref="pduTaskDialog"
      :title="dialogTitle"
      :multi="isAdd"
      @confirm="onSave"
    >
      <template #default>
        <div class="c-grid-form u-align-self--center">
          <template v-if="isAdd">
            <schema-select
              v-model="taskType"
              class="u-width--sm"
              :schema="typeSelectSchema"
            />
          </template>
          <div
            v-else
            class="l-flex--row c-grid-form__option u-color--blue u-bold"
          >
            {{ taskType }}
          </div>
        </div>
      </template>
    </pdu-task-dialog>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import {
  FOREVER, ONE_DAY, ThirdPartyDevice
} from '@/constant.js'
import {
  parseTime, transformScreenTaskInfo
} from '@/utils'
import {
  addInjectListener,
  addListener,
  GET_PDU_STATUS,
  GET_PDU_TASK,
  removeInjectListener,
  removeListener,
  Status
} from '@/utils/adapter'
import { toDate } from '@/utils/event.js'
import baseMixin from './mixins/base.js'
import {
  addPduTask, deletePduTask, getPduTasks, submitPduTasks, updatePduTask
} from '@/api/external'

/* const ErrorMessage = {
  TIMEOUT: '暂未获取到操作反馈，请回读查看',
  TIMEOUT_RETRY: '暂未获取到操作反馈，请稍后重试',
  DEFAULT: '操作异常，请稍后重试',
  BUSY: '终端被他人占用',
  PASSWORD: '登录密码错误，请联系管理员',
  [GET_PDU_STATUS]: '获取电源状态超时，请稍后重试',
  [GET_PDU_TASK]: '获取定时任务超时，请回读查看'
} */

export default {
  name: 'PduPowerSwitch',
  mixins: [baseMixin],
  data () {
    return {
      topic: '/multifunctionCard/invoke',
      powerStatus: Status.LOADING,
      active: GET_PDU_STATUS,
      tabs: [
        { key: GET_PDU_STATUS, name: '电源状态' }
      ],
      powerSchema: {
        props: {
          size: 'small'
        },
        nonPagination: true,
        list: this.getPowers,
        /* buttons: [
          { label: '一键开启', on: this.onSwitchOpen },
          { label: '一键关闭', on: this.onSwitchClose }
        ], */
        cols: [
          { prop: 'slot_no', label: '序号', 'align': 'center' },
          { prop: 'name', label: '电源端口', 'align': 'center' },
          { prop: 'state', label: '状态', 'align': 'center' }
        ]
      },
      typeSelectSchema: { options: [] },
      actionInfo: ['开启', '关闭'],
      timingStatus: 0,
      hasChanged: false,
      isAdd: true,
      taskType: ''
    }
  },
  computed: {
    ...mapGetters(['account']),
    powerStatusTip () {
      switch (this.powerStatus) {
        case Status.OK:
          return 'PDU定时'
        default:
          return '检测PDU中'
      }
    },
    iconClass () {
      return this.powerStatus === Status.OK ? 'ok' : ''
    },
    loading () {
      return this.active !== GET_PDU_STATUS && !this.timingStatus
    },
    schema () {
      switch (this.active) {
        case GET_PDU_STATUS:
          return this.powerSchema
        case GET_PDU_TASK:
          return this.taskSchema
        default:
          return null
      }
    },
    taskSchema () {
      return {
        props: {
          size: 'small'
        },
        nonPagination: true,
        list: () =>
          // 传递 device.id 作为参数
          // eslint-disable-next-line implicit-arrow-linebreak
          getPduTasks({ deviceId: this.device.id })
            .then(result => {
              // 在接口调用结束后结束 loading
              this.timingStatus = 1
              return result
            })
            .catch(error => {
              // 处理错误情况也要结束 loading
              this.timingStatus = 1
              throw error
            }),
        buttons: [
          { type: 'add', label: '新增', on: this.onAdd },
          { label: '应用', render: () => this.hasChanged, on: this.onSubmitPowerTasks }
        ].filter(Boolean),
        filters: [].filter(Boolean),
        cols: [
          {
            prop: 'slotNo',
            label: '插座序号',
            align: 'center',
            render: task => task.slotNo || '-'
          },
          {
            prop: 'startDate',
            label: '开始日期',
            render: ({ startDate }) => startDate ? startDate.split(' ')[0] : '-'
          },
          {
            prop: 'endDate',
            label: '结束日期',
            render: ({ endDate }) => endDate ? endDate.split(' ')[0] : '-'
          },
          {
            label: '开屏时间',
            align: 'center',
            render: ({ powerOnTime }) => powerOnTime || '-',
            'show-overflow-tooltip': false
          },
          {
            label: '关屏时间',
            align: 'center',
            render: ({ powerOffTime }) => powerOffTime || '-',
            'show-overflow-tooltip': false
          },
          {
            type: 'tag', render: task => this.isExpired(task)
              ? { type: 'warning', label: '已过期' }
              : task.status === 1
                ? { type: 'success', label: '启用' }
                : { type: 'danger', label: '停用' }
          },
          {
            type: 'invoke',
            render: [
              { label: ({ status }) => status === 1 ? '停用' : '启用', on: this.onToggle },
              { label: '编辑', on: this.onEdit },
              { label: '删除', on: this.onDel }
            ],
            width: 140
          }
        ]
      }
    },
    dialogTitle () {
      return this.isAdd ? '新增定时任务' : '编辑定时任务'
    }
  },
  mounted () {
    addListener(this.device.id, this.onCacheMessage)
    addInjectListener(this.device.id, this.onMessage)
  },
  beforeDestroy () {
    this.$openDialog = false
    removeListener(this.device.id, this.onCacheMessage)
    removeInjectListener(this.device.id, this.onMessage)
  },
  methods: {
    isExpired ({ endDate }) {
      // 如果是 FOREVER 常量，则永不过期
      if (endDate === FOREVER) {
        return false
      }
      // 从日期字符串中提取日期部分
      const dateStr = typeof endDate === 'string' ? endDate.split(' ')[0] : endDate
      // 判断是否过期
      return toDate(`${dateStr} 00:00:00`) <= Date.now() - ONE_DAY
    },
    handleClose (done) {
      if (this.hasChanged) {
        this.$confirm(
          '设置未保存，是否放弃修改？<p class="u-color--error">若需保存请点击【应用】</p>',
          '温馨提示',
          {
            dangerouslyUseHTMLString: true,
            type: 'warning',
            confirmButtonText: '放弃'
          }
        )
          .then(() => {
            this.$openDialog = false
            done()
          })
        return
      }
      this.$openDialog = false
      done()
    },
    onClickTab (val) {
      if (this.hasChanged) {
        this.$confirm(
          '设置未保存，是否放弃修改？<p class="u-color--error">若需保存请点击【应用】</p>',
          '温馨提示',
          {
            dangerouslyUseHTMLString: true,
            type: 'warning',
            confirmButtonText: '放弃'
          }
        )
          .then(() => {
            this.hasChanged = false
            this.onClickTab(val)
          })
        return
      }
      if (val !== GET_PDU_STATUS && (val !== this.active || !this.timingStatus)) {
        this.getTasksByKey(val)
      }
      this.active = val
    },
    invoke () {
      if (this.powerStatus !== Status.OK) {
        this.$message({
          type: 'warning',
          message: '获取PDU信息中，请稍后尝试'
        })
        return
      }
      this.$openDialog = true
      this.getPowerStatus()
    },
    onCacheMessage (value) {
      try {
        console.log('cache message', value)
        const pdu = value[ThirdPartyDevice.PDU]
        const socket = pdu[0]
        const pduStatus = socket.state
        this.$pdu = pdu
        console.log('pdu schedule socket', socket)
        if (pduStatus === 'ON' || pduStatus === 'OFF') {
          this.powerStatus = Status.OK
        } else {
          this.powerStatus = Status.LOADING
        }
      } catch (e) {
        console.log('cache pdu message error', e)
      }
    },
    /* fetchPowerStatus () {
      this.sendTopic(
        GET_PDU_STATUS,
        JSON.stringify({ sn: this.device.serialNumber }),
        true
      )
    }, */
    onMessage (message) {
      console.log('on message', message)
    },
    onClose () {
      this.$powers = []
      this.$taskPorts = []
      this.$tasks = []
      this.closeAsyncLoading()
    },
    getPowerStatus () {
      this.$powers = []
      this.hasChanged = false
      console.log('this.$pdu', this.$pdu)
      this.setCachePowerStatus(this.$pdu)
      if (this.$openDialog) {
        this.$refs.dialog?.show()
      }
      this.$refs.table?.pageTo(1)
    },
    setCachePowerStatus (powersData) {
      const map = {}
      const options = []
      console.log('powersData', powersData)

      // 将对象转换为数组
      let powersArray = []
      if (powersData && typeof powersData === 'object' && !Array.isArray(powersData)) {
        // 提取数字键的值组成数组
        powersArray = Object.keys(powersData)
          .filter(key => key !== 'timestamp')
          .map(key => powersData[key])
      } else if (Array.isArray(powersData)) {
        powersArray = powersData
      }

      console.log('powersArray', powersArray)

      if (powersArray.length === 0) {
        return
      }

      const timestamp = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
      this.$powers = [{
        connectIndex: powersArray[0].slot_no,
        portIndex: powersArray[0].slot_no,
        powers: powersArray.map(power => {
          const { connectIndex, portIndex, type } = power
          if (type) {
            if (!map[type]) {
              map[type] = {
                connectIndex,
                portIndex,
                type
              }
              options.push({
                value: type,
                label: type
              })
            }
          }
          return {
            timestamp,
            ...power
          }
        })
      }]
      this.tabs = [
        { key: GET_PDU_STATUS, name: '电源状态' },
        { key: GET_PDU_TASK, name: '定时控制' }
      ]
      this.$typeMap = map
      this.typeSelectSchema = { options }
      this.$refs.table?.pageTo(1)
    },
    getPowers () {
      const data = []
      this.$powers.forEach(({ powers }) => {
        powers.forEach(power => {
          data.push(power)
        })
      })
      return Promise.resolve({ data })
    },
    /* onSwitchPower (power) {
      const { powerIndex, type, action } = power
      const targetAction = action ^ 1
      this.$confirm(
        `立即${this.actionInfo[targetAction]}电源 ${powerIndex} ${type}？<p class="u-color--blue">确认操作后请等待数据同步</p>`,
        '操作确认',
        {
          dangerouslyUseHTMLString: true,
          type: 'warning'
        }
      )
        .then(() => {
          savePowerLogger({
            description: `手动${this.actionInfo[targetAction]} 设备【${this.device.name}】 ${type} 端口${powerIndex}`,
            method: `${this.actionInfo[targetAction]}电源`,
            params: `${this.device.id} ${this.device.name}`
          })
          sendDeviceAlarm({
            deviceId: this.device.id,
            errorEnumId: targetAction ? 36 : 37,
            message: `用户【${this.account}】 手动${this.actionInfo[targetAction]} ${type} 端口${powerIndex}`
          })
          this.onSwitchPowerSingle(power)
        })
    }, */
    /* onSwitchPowerSingle (power) {
      const { connectIndex, portIndex, powerIndex, type } = power
      this.sendTopic(
        SET_POWER_STATUS,
        JSON.stringify({
          sn: this.device.serialNumber,
          info: {
            data: [{
              connectIndex, portIndex,
              conditions: this.$powers
                .find(item => item.portIndex === portIndex)
                .powers
                .filter(power => power.type === type)
                .map(power => {
                  return {
                    type,
                    powerIndex: power.powerIndex,
                    action: power.powerIndex === powerIndex ? power.action ^ 1 : power.action
                  }
                })
            }]
          }
        }),
        this.getPowerStatus
      )
    }, */
    /* onSwitchTypePower (power) {
      const { type, action } = power
      const targetAction = action ^ 1
      this.$confirm(
        `立即${this.actionInfo[targetAction]}电源 ${type}？<p class="u-color--blue">确认操作后请等待数据同步</p>`,
        '操作确认',
        {
          dangerouslyUseHTMLString: true,
          type: 'warning'
        }
      ).then(() => {
        savePowerLogger({
          description: `手动${this.actionInfo[targetAction]} 设备【${this.device.name}】 ${type}`,
          method: `${this.actionInfo[targetAction]}电源`,
          params: `${this.device.id} ${this.device.name}`
        })
        sendDeviceAlarm({
          deviceId: this.device.id,
          errorEnumId: targetAction ? 36 : 37,
          message: `用户【${this.account}】 手动${this.actionInfo[targetAction]} ${type}`
        })
        this.onSwitchPowerMulti(power)
      })
    }, */
    /* onSwitchPowerMulti (power) {
      const { connectIndex, portIndex, type } = power
      const action = power.action ^ 1
      this.sendTopic(
        SET_POWER_STATUS,
        JSON.stringify({
          sn: this.device.serialNumber,
          info: {
            data: [{
              connectIndex, portIndex,
              conditions: [{
                powerIndex: 0,
                type,
                action
              }]
            }]
          }
        }),
        this.getPowerStatus
      )
    }, */
    /* onSwitchOpen () {
      this.onSwitch(PowerStatus.OPEN)
    }, */
    /* onSwitchClose () {
      this.onSwitch(PowerStatus.CLOSE)
    }, */
    /* onSwitch (action) {
      if (!this.$powers.length) {
        return
      }
      this.$confirm(
        `立即${this.actionInfo[action]}所有电源？<p class="u-color--blue">确认操作后请等待数据同步</p>`,
        '操作确认',
        {
          dangerouslyUseHTMLString: true,
          type: 'warning'
        }
      ).then(() => {
        savePowerLogger({
          description: `手动${this.actionInfo[action]} 设备【${this.device.name}】 所有电源`,
          method: `${this.actionInfo[action]}电源`,
          params: `${this.device.id} ${this.device.name}`
        })
        sendDeviceAlarm({
          deviceId: this.device.id,
          errorEnumId: action ? 36 : 37,
          message: `用户【${this.account}】 手动${this.actionInfo[action]} 所有电源`
        })
        this.sendTopic(
          SET_POWER_STATUS,
          JSON.stringify({
            sn: this.device.serialNumber,
            info: {
              data: this.$powers.map(({ connectIndex, portIndex, powers }) => {
                return {
                  connectIndex, portIndex,
                  conditions: powers.map(({ powerIndex, type }) => {
                    return { powerIndex, type, action }
                  })
                }
              })
            }
          }),
          this.getPowerStatus
        )
      })
    }, */
    getTasksByKey () {
      this.timingStatus = 0
      this.hasChanged = false
      this.$taskPorts = []
      this.$tasks = []
      this.$refs.table?.pageTo(1)
      /* this.sendTopic(
        key,
        JSON.stringify({ sn: this.device.serialNumber }),
        true
      ) */
    },
    getPowerTasks () {
      this.getTasksByKey(this.active)
    },
    setMultiPowerTasks (data) {
      console.log('GET_PDU_TASK', data)
      const tasks = []
      const ports = []
      const map = {}
      data.forEach(({ connectIndex, portIndex, conditions }) => {
        ports.push({ connectIndex, portIndex })
        conditions.forEach(task => {
          if (task.flag) {
            const flagArr = `${task.flag}`.split('_')
            const flag = flagArr.length > 2 ? `${flagArr[0]}_${flagArr[1]}` : task.flag
            if (!map[flag]) {
              tasks.push(map[flag] = {
                connectIndex, portIndex, flag,
                ...this.transfromDataToTask(task)
              })
            }
            if (flagArr.length > 2) {
              map[flag].executeTime[flagArr[2]] = {
                ...map[flag].executeTime[flagArr[2]],
                ...this.transformDataToExecuteTime(task)
              }
            } else {
              map[flag].executeTime.push(this.transformDataToExecuteTime(task))
            }
          } else {
            tasks.push({
              connectIndex, portIndex,
              ...this.transfromDataToTask(task)
            })
          }
        })
      })
      this.$tasks = tasks.map(task => {
        task.info = transformScreenTaskInfo(task.startDate, task.endDate, task.dayOfWeek, task.executeTime)
        return task
      })
      this.$taskPorts = ports
      this.timingStatus = 1
      this.$refs.table?.pageTo(1)
    },
    /* transfromDataToTask ({ enable, type, startTime, endTime, cron }) {
      const { dayOfWeek } = transformCron(cron)
      return {
        enable, type, dayOfWeek,
        startDate: startTime,
        endDate: endTime,
        executeTime: []
      }
    }, */
    /* transformDataToExecuteTime ({ action, cron }) {
      return action === PowerStatus.OPEN
        ? { start: transformCron(cron).executeTime }
        : { end: transformCron(cron).executeTime }
    }, */
    onSubmitPowerTasks () {
      const deviceId = this.device.id
      submitPduTasks({ deviceId })
        .then(
          () => {
            this.hasChanged = false
            this.$message({
              type: 'success',
              message: '应用成功'
            })
          }
        )
    },
    /* getMultiPowerTaskData () {
      const map = {}
      const data = []
      this.$taskPorts.forEach(({ connectIndex, portIndex }) => {
        if (!map[portIndex]) {
          data.push(map[portIndex] = {
            connectIndex,
            portIndex,
            enable: true,
            conditions: []
          })
        }
      })
      this.$tasks.forEach(({ connectIndex, portIndex, flag, type, enable, startDate, endDate, dayOfWeek, executeTime }) => {
        if (!map[portIndex]) {
          data.push(map[portIndex] = {
            connectIndex,
            portIndex,
            enable: true,
            conditions: []
          })
        }
        const tasks = []
        executeTime.forEach(({ start, end }, index) => {
          start && tasks.push({
            type,
            enable,
            powerIndex: 0,
            flag: `${flag}_${index}`,
            action: PowerStatus.OPEN,
            startTime: startDate,
            endTime: endDate,
            cron: [transformToCron(startDate, endDate, dayOfWeek, start)]
          })
          end && tasks.push({
            type,
            enable,
            powerIndex: 0,
            flag: `${flag}_${index}`,
            action: PowerStatus.CLOSE,
            startTime: startDate,
            endTime: endDate,
            cron: [transformToCron(startDate, endDate, dayOfWeek, end)]
          })
        })
        map[portIndex].conditions.push(...tasks)
      })
      savePowerLogger({
        description: `设置设备【${this.device.name}】的电源定时任务`,
        method: '电源定时任务设置',
        params: JSON.stringify({
          id: this.device.id,
          name: this.device.name,
          tasks: this.$tasks
        })
      })
      return data.filter(({ conditions }) => conditions.length)
    }, */
    onToggle (task) {
      this.hasChanged = true
      task.enable = task.status === 1
      console.log('task.enable : ', task.enable)
      task.status = task.enable ? 0 : 1
      updatePduTask(task)
        .then(() => {
          getPduTasks({ deviceId: this.device.id })
          this.$refs.table.pageTo(1)
        })
        .finally(() => {
        })
    },
    onAdd () {
      this.isAdd = true
      // this.taskType = this.typeSelectSchema.options[0]?.value
      this.$refs.pduTaskDialog.show()
    },
    onEdit (task) {
      // 创建 executeTime 数组，符合 PduTaskDialog 的期望格式
      const executeTime = []
      // 如果有 powerOnTime 或 powerOffTime，则创建执行时间对象
      if (task.powerOnTime || task.powerOffTime) {
        executeTime.push({
          start: task.powerOnTime || '',
          end: task.powerOffTime || ''
        })
      } else {
        // 如果都没有，则添加一个空的执行时间对象
        executeTime.push({ start: '', end: '' })
      }
      const taskId = task.id
      const { startDate, endDate } = task
      this.isAdd = false
      this.$task = task
      this.$refs.pduTaskDialog.show({
        startDate,
        endDate,
        executeTime,
        taskId
      })
    },
    onSave ({ value, done }) {
      if (this.isAdd) {
        const deviceId = this.device.id
        addPduTask(value, deviceId)
          .then(() => {
            // 重新加载表格数据
            getPduTasks({ deviceId: this.device.id })
            this.$refs.table.pageTo(1)
          })
          .finally(() => {
            done()
          })
      } else {
        const task = value[0]
        updatePduTask(task)
          .then(() => {
            // 重新加载表格数据
            getPduTasks({ deviceId: this.device.id })
            this.$refs.table.pageTo(1)
          })
          .finally(() => {
            done()
          })
      }
      this.hasChanged = true
    },
    onDel (task) {
      this.hasChanged = true
      deletePduTask({ id: task.id })
        .then(() => {
          // 重新加载表格数据
          getPduTasks({ deviceId: this.device.id })
          this.$refs.table.pageTo(1)
        })
    }
  }
}
</script>

<style lang="scss" scoped>
.o-icon {
  background-image: url("~@/assets/icon_screen_switch.png");

  &.ok {
    background-image: url("~@/assets/icon_device_switch.png");
  }
}
</style>
