<template>
  <div class="title">
    设备监控
    <el-button size="small" :icon="renderIcon('Refresh')" @click="refreshData"
               style="margin-left: 5px;"
    />
    <el-button size="small" :icon="renderIcon('fa Simplybuilt')" @click="simBootAll"
               style="margin-left: 2px;" link
               v-if="worldModelState.runState.isRunning && worldModelState.runState.isVirtual"
    >全上线
    </el-button>
    <el-input v-model="searchKeyword" size="small" style="width: 240px" placeholder="Search">
      <template #prefix>
        <component :is="renderIcon('element Search')"></component>
      </template>
    </el-input>
    <span class="close" @click="closeMe">
      <component :is="renderIcon('element Close')" />
    </span>
  </div>
  <div class="calc-left-panel">
    <el-empty v-if="!isActivated || errorDescription" :description="errorDescription" style="width:100%;">
    </el-empty>
    <div v-else class="monitor-tool-wrap">
      <div class="infor-row">
        <div class="infor-item">
          总数<span class="num">{{ total }}</span>
        </div>
        <div class="infor-item">
          上线<span class="num num-green">{{ online }}</span>
        </div>
        <div class="infor-item">
          下线<span class="num num-red">{{ offline }}</span>
        </div>
        <div class="infor-item">
          空闲<span class="num num-orange">{{ idle }}</span>
        </div>
      </div>
      <div class="list">
        <div v-for="deviceInfo in deviceList" class="item" :class="selectedId === deviceInfo.id" @mousedown="()=>{ selectedId = deviceInfo.id }">
          <div class="content">
            <div class="row">
              <div class="row-icon">
                <component :is="renderIcon('antd DeploymentUnitOutlined')"></component>
              </div>
              <div class="row-content">
                <div class="data-infor">
                  <el-button link style="margin-right: 2px; color:WHITE;" @click="copyDeviceId(deviceInfo)">ID:{{ deviceInfo.id }}</el-button>
                  <span :class="deviceInfo.isOnline?'green':'red'">[{{ getDeviceModeDesc(deviceInfo) }}]</span>
                  <div class="infor-right">
                    <span class="num-red" v-if="deviceInfo.isBlocked">阻挡</span>
                    <span class="num-red" v-if="deviceInfo.taskStatus === 'PAUSED'">暂停</span>
                    <span class="blue">{{ deviceInfo.logicX + '_' + deviceInfo.logicY + '(' + deviceInfo.direction + ')' }}</span>
                  </div>
                </div>
                <div class="data-infor">
                  <div class="progress">
                    <span :style="{width:getTaskProcessPercent(deviceInfo)+'%'}"></span>
                    <div class="text"> {{ getTaskProcessPercent(deviceInfo) }} %</div>
                  </div>
                </div>
                <div class="data-infor">
                  {{ getDeviceTaskTypeDesc(deviceInfo) }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import IWidgets from '../IWidgets.js'
import { worldModel } from '@/core/manager/WorldModel.js'

export default {
  name: 'MonitorView',
  mixins: [IWidgets],
  data() {
    return {
      searchKeyword: '',
      selectedId: '',
      stopSubscribe: [],
      /**
       * 设备列表数据
       * @type {Array<Partial<AgvStatusVo>>}
       */
      deviceList: []
    }
  },
  mounted() {
    window['MonitorView'] = this
  },
  unmounted() {
    window['MonitorView'] = null
    this.undescribe()
  },
  methods: {
    simBootAll() {
      const viewport = window['viewport']
      for (const deviceInfo of this.deviceList) {
        if (deviceInfo.isOnline) {
          continue
        }
        const view3DObject = Model.find3D(deviceInfo.id)
        if (typeof view3DObject.bootForMonitor === 'function') {
          view3DObject.bootForMonitor()
        }
      }
    },
    copyDeviceId(deviceInfo) {
      navigator.clipboard.writeText(deviceInfo.id).then(() => {
        system.msg('设备ID已复制到剪贴板', 'success')
      }).catch(err => {
        system.msg('无法复制设备ID:', 'error')
      })
    },
    /**
     * 获取任务进度百分比
     */
    getTaskProcessPercent(deviceInfo) {
      if (deviceInfo == null || !deviceInfo.taskTotalCount || !deviceInfo.taskCompleted) {
        return 0
      }
      return Math.round((deviceInfo.taskCompleted / deviceInfo.taskTotalCount) * 100)
    },
    /**
     * 处理设备存活消息
     * @type {(type: BackendTopicType, topic: string, body: {
     *   id: string
     *   type: string
     *   online: boolean
     * }) => void}
     */
    onDeviceAliveMessage(type, topic, body) {
      const deviceInfo = _.find(this.deviceList, device => device.id === body.id)
      if (!deviceInfo) {
        // 如果设备信息不存在，则添加新设备
        this.deviceList.push({
          id: body.id,
          type: body.type,
          isOnline: body.online
        })

      } else {
        // 如果设备信息已存在，则更新在线状态
        deviceInfo.isOnline = body.online
      }
    },
    /**
     * 处理设备状态消息
     * @type {DeviceStatusFn}
     */
    onDeviceStatusMessage(type, topic, body) {
      const deviceInfo = _.find(this.deviceList, device => device.id === body.id)
      if (!deviceInfo) {
        return
      }
      _.assign(deviceInfo, body)
    },
    async subscribe() {
      await this.refreshData()

      // 订阅设备状态消息
      this.stopSubscribe.push(
        worldModel.backendMessageReceiver.subscribe('DeviceAlive', this.onDeviceAliveMessage.bind(this))
      )
      this.stopSubscribe.push(
        worldModel.backendMessageReceiver.subscribe('DeviceStatus', this.onDeviceStatusMessage.bind(this))
      )
    },
    async refreshData() {
      this.deviceList = []
      const res = await LCC.queryDeviceInfoList()
      if (!res.success) {
        return
      }
      this.deviceList = res.data
    },
    undescribe() {
      // 取消订阅设备状态消息
      for (const stopFn of this.stopSubscribe) {
        stopFn()
      }
      this.stopSubscribe = []
    },
    getDeviceModeDesc(deviceInfo) {
      if (!deviceInfo.isOnline) {
        return '离线'
      }
      if (!deviceInfo.mode) {
        return '在线'
      }
      switch (deviceInfo.mode) {
        case 'AMR_FREE_MODE':
          return '空闲模式'
        case 'AMR_INIT_MODE':
          return '初始化模式'
        case 'AMR_TASK_MODE':
          return '任务模式'
        case 'AMR_SINGLE_ACTION_MODE':
          return '单动作模式'
        case 'AMR_MANUAL_MODE':
          return '手动模式'
        case 'AMR_HANDSET_MODE':
          return '遥控器模式'
        case 'AMR_CHARGE_MODE':
          return '充电模式'
        case 'AMR_TASK_INTERRUPT_MODE':
          return '任务被中断模式'
        case 'AMR_CUSTOMIZE_MODE':
          return '自定义模式'
      }
      return deviceInfo.mode
    },
    getDeviceTaskTypeDesc(deviceInfo) {
      switch (deviceInfo.bizTaskType) {
        case 'MOVE':
          return '移动 ' + deviceInfo.bizTaskFrom + ' -> ' + deviceInfo.bizTaskTo
        case 'CHARGE':
          return '充电' + deviceInfo.bizTaskFrom + ' -> ' + deviceInfo.bizTaskTo
        case 'CARRY':
          return '搬运 [' + deviceInfo.bizLpn + '] ' + deviceInfo.bizTaskFrom + ' -> ' + deviceInfo.bizTaskTo
        case 'LOAD':
          return '装载 [' + deviceInfo.bizLpn + '] ' + deviceInfo.bizTaskFrom + ' -> ' + deviceInfo.bizTaskTo
        case 'UNLOAD':
          return '卸载 [' + deviceInfo.bizLpn + '] ' + deviceInfo.bizTaskFrom + ' -> ' + deviceInfo.bizTaskTo
        default:
          return '无任务'
      }
    }
  },
  computed: {
    /*
    total: 0,
      online: 0,
      offline: 0,
      running: 0,
      idle: 0,
     */
    total() {
      return this.deviceList.length
    },
    online() {
      return this.deviceList.filter(device => device.isOnline).length
    },
    offline() {
      return this.deviceList.filter(device => !device.isOnline).length
    },
    idle() {
      return this.deviceList.filter(device => device.mode === 'AMR_FREE_MODE').length
    },
    worldModelState() {
      return worldModel.state
    }
  },
  watch: {
    errorDescription: {
      handler(newVal) {
        if (newVal) {
          this.undescribe()
        } else {
          this.subscribe()
        }
      },
      immediate: true
    }
  }
}
</script>
<style lang="less">
.monitor-tool-wrap {
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;

  .infor-row {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    //background: #cdcccc;
    padding: 3px 0;

    .infor-item {
      margin: 2px 8px;
      font-size: 12px;
      background: #f3e9c0;
      border-radius: 3px;
      padding: 0 5px;
    }

    .num {
      display: inline-block;
      padding: 0 3px;
      font-weight: bold;
      color: #333;

      &:first-child {
        margin-left: 0;
      }

      &:last-child {
        margin-right: 0;
      }

      &.num-red {
        color: red;
      }

      &.num-green {
        color: green;
      }

      &.num-blue {
        color: blue;
      }

      &.num-orange {
        color: #d78f0b;
      }
    }
  }

  .list {
    flex: 1;
    overflow: auto;
    font-size: 12px;
    color: #fff;

    .item {
      display: flex;
      flex-direction: column;
      border: 2px solid #808080;
      margin: 5px 5px;
      border-radius: 5px;
      background: #747a80;

      &.selected {
        border-color: #fa9d12;
      }

      .title {
        display: flex;
        align-items: center;
        padding: 3px 10px;
        border-bottom: 1px solid #81888e;
        margin-bottom: 5px;

        .num {
          font-weight: bold;
          margin-left: 5px;
        }

        .el-icon {
          margin: 0 5px;
          font-size: 15px;
        }
      }

      .content {
        flex: 1;
        padding: 5px 0;

        .row {
          display: flex;
          flex-direction: row;
          margin: 0 5px;

          .row-icon {
            width: 75px;
            height: 75px;
            background: #3e454c;
            flex-shrink: 0;
            display: flex;
            justify-content: center;
            align-items: center;

            .el-icon {
              font-size: 70px;
              color: #fff;
            }
          }

          .row-content {
            flex: 1;
            margin-left: 5px;
          }
        }

        .data-infor {
          margin: 3px 0;
          display: flex;
          flex-direction: row;
          flex-wrap: wrap;
          align-items: center;

          .infor-right {
            flex: 1;
            flex-shrink: 0;

            span {
              &.blue {
                color: #3dc4ff;
              }

              &.name {
                margin-right: 15px;
              }
            }
          }

          & > span {
            margin-right: 3px;

            &.green {
              color: #00ff00;
            }

            &.red {
              color: red;
            }

            & > svg {
              position: relative;
              top: 3px;
            }
          }

          .progress {
            flex: 1;
            min-width: 80px;
            border: 1px solid #dcdcdc;
            height: 20px;
            margin-left: 5px;
            position: relative;

            span {
              font-size: 12px;
              background: #7ac678;
              display: inline-block;
              width: 0;
              text-align: center;
              height: 18px;
            }

            .text {
              position: absolute;
              width: 100%;
              height: 100%;
              left: 0;
              top: 0;
              text-align: center;
            }
          }

          & > svg {
            margin-right: 5px;
            position: relative;
            top: 1px;
          }
        }
      }
    }
  }
}
</style>
