<template>
  <div class="deviceList">
    <Search :onClickSearch="async () => { }" :onClickReset="async () => { }" />
    <div class="deviceList-table">
      <a-table :columns="columns" :data-source="data.device" :pagination="paginationProp" @change="refreshData"
        row-key="device_sn" :expandedRowKeys="expandRows" :row-selection="rowSelection" :rowClassName="rowClassName"
        :scroll="{ x: '100%', y: 500 }" :expandIcon="expandIcon" :loading="loading">
        <template v-for="col in ['nickname']" #[col]="{ text, record }" :key="col">
          <div>
            <a-input v-if="editableData[record.device_sn]" v-model:value="editableData[record.device_sn][col]" />
            <template v-else>
              <a-tooltip :title="text">
                {{ text }}
              </a-tooltip>
            </template>
          </div>
        </template>
        <template v-for="col in ['sn', 'workspace']" #[col]="{ text }" :key="col">
          <a-tooltip :title="text">
            <span>{{ text }}</span>
          </a-tooltip>
        </template>
        <!-- 固件版本 -->
        <template #firmware_version="{ record }">
          <span v-if="record.domin === 3">
            <DeviceFirmwareUpgrade :device="record" class="table-flex-col" @device-upgrade="onDeviceUpgrade" />
          </span>
          <span v-else>
            {{ record.firmware_version }}
          </span>
        </template>
        <!-- 固件升级 -->
        <template #firmware_status="{ text }">
          <div v-if="text === -1">
            不支持
          </div>
          <div v-else>
            {{ DeviceFirmwareStatus[text] }}
          </div>
        </template>
        <!-- 状态 -->
        <template #status="{ text }">
          <span v-if="text" class="flex-row flex-align-center">
            <span class="mr5" style="width: 12px; height: 12px; border-radius: 50%; background-color: green;" />
            <span>在线</span>
          </span>
          <span class="flex-row flex-align-center" v-else>
            <span class="mr5" style="width: 12px; height: 12px; border-radius: 50%; background-color: red;" />
            <span>离线</span>
          </span>
        </template>
        <!-- 操作 -->
        <template #action="{ record }">
          <!-- 编辑态操作 -->
          <div v-if="editableData[record.device_sn]">
            <a-tooltip title="确定">
              <CheckOutlined style="color: #28d445;margin-right: 10px;" @click="save(record)" />
            </a-tooltip>
            <a-tooltip title="取消">
              <CloseOutlined style="color: #e70102;" @click="() => delete editableData[record.device_sn]" />
            </a-tooltip>
          </div>
          <!-- 非编辑态操作 -->
          <div v-else class="flex-align-center flex-row" style="color: #2d8cf0">
            <a-tooltip title="设备日志">
              <CloudServerOutlined style="margin-right: 10px;" @click="showDeviceLogUploadRecord(record)" />
            </a-tooltip>
            <a-tooltip title="告警信息">
              <FileSearchOutlined style="margin-right: 10px;" @click="showHms(record)" />
            </a-tooltip>
            <a-tooltip title="编辑">
              <EditOutlined style="margin-right: 10px;" @click="edit(record)" />
            </a-tooltip>
            <a-tooltip title="删除">
              <DeleteOutlined @click="onClickDelete(record)" />
            </a-tooltip>
          </div>
        </template>
      </a-table>
      <!-- 设备升级 -->
      <DeviceFirmwareUpgradeModal title="设备升级" v-model:visible="deviceFirmwareUpgradeModalVisible"
        :device="selectedDevice" @ok="onUpgradeDeviceOk" />
      <!-- 设备日志上传记录 -->
      <DeviceLogUploadRecordDrawer v-model:visible="deviceLogUploadRecordVisible" :device="currentDevice" />
      <!-- hms 信息 -->
      <DeviceHmsDrawer v-model:visible="hmsVisible" :device="currentDevice" />
    </div>
  </div>
</template>

<script lang="ts" setup>
import { h, onMounted, reactive, ref, UnwrapRef } from 'vue'
import { Modal, notification } from 'ant-design-vue'
import { EditOutlined, CheckOutlined, CloseOutlined, DeleteOutlined, FileSearchOutlined, CloudServerOutlined } from '@ant-design/icons-vue'
import Search from './components/Search.vue'
import { getBindingDevices, unbindDevice, updateDevice } from '/@/api/manage'
import { Device, DeviceFirmwareStatus, DeviceFirmwareStatusEnum } from '/@/types/device'
import DeviceFirmwareUpgrade from '/@/components/devices/device-upgrade/DeviceFirmwareUpgrade.vue'
import DeviceFirmwareUpgradeModal from '/@/components/devices/device-upgrade/DeviceFirmwareUpgradeModal.vue'
import { useDeviceFirmwareUpgrade } from '/@/components/devices/device-upgrade/use-device-upgrade'
import { useDeviceUpgradeEvent } from '/@/components/devices/device-upgrade/use-device-upgrade-event'
import { DeviceCmdExecuteInfo, DeviceCmdExecuteStatus } from '/@/types/device-cmd'
import DeviceLogUploadRecordDrawer from '/@/components/devices/device-log/DeviceLogUploadRecordDrawer.vue'
import DeviceHmsDrawer from '/@/components/devices/device-hms/DeviceHmsDrawer.vue'
import { IPage } from '/@/api/http/type'
import { EDeviceTypeName, ELocalStorageKey } from '/@/types'

const loading = ref(true)

const columns = [
  {
    title: '设备型号',
    dataIndex: 'device_name',
    width: 150,
    ellipsis: true,
    sorter: (a: any, b: any) => a.device_name.localeCompare(b.device_name),
  },
  {
    title: '设备SN',
    dataIndex: 'device_sn',
    width: 200,
    ellipsis: true,
    slots: { customRender: 'sn' }
  },
  {
    title: '设备名称',
    dataIndex: 'nickname',
    width: 150,
    ellipsis: true,
    sorter: (a: any, b: any) => a.nickname.localeCompare(b.nickname),
    slots: { customRender: 'nickname' }
  },
  {
    title: '固件版本',
    dataIndex: 'firmware_version',
    width: 150,
    ellipsis: true,
    slots: { customRender: 'firmware_version' },
  },
  {
    title: '固件升级',
    dataIndex: 'firmware_status',
    width: 150,
    ellipsis: true,
    slots: { customRender: 'firmware_status' },
  },
  {
    title: '当前状态',
    dataIndex: 'status',
    width: 100,
    ellipsis: true,
    slots: { customRender: 'status' }
  },
  {
    title: '加入项目时间',
    dataIndex: 'bound_time',
    width: 200,
    sorter: (a: any, b: any) => a.bound_time.localeCompare(b.bound_time),
  },
  {
    title: '最后在线时间',
    dataIndex: 'login_time',
    width: 200,
    sorter: (a: any, b: any) => a.login_time.localeCompare(b.login_time),
  },
  {
    title: '操作',
    dataIndex: 'actions',
    fixed: 'right',
    width: 150,
    slots: { customRender: 'action' },
  },
]

const expandIcon = (props: any) => {
  if (!props.expanded) {
    return h('div',
      {
        style: 'border-left: 2px solid rgb(200,200,200); border-bottom: 2px solid rgb(200,200,200); height: 16px; width: 16px; float: left;',
        class: 'mt-5 ml0',
      })
  }
}

const rowClassName = (record: any, index: number) => {
  const className = []
  if ((index & 1) === 0) {
    className.push('table-striped')
  }
  return className.toString().replaceAll(',', ' ')
}

const expandRows = ref<string[]>([])

const data: {
  device: Device[]
} = reactive({
  device: []
})

const paginationProp = reactive({
  pageSizeOptions: ['20', '50', '100'],
  showQuickJumper: true,
  showSizeChanger: true,
  pageSize: 20,
  current: 1,
  total: 0
})

// 获取分页信息
function getPaginationBody() {
  return {
    page: paginationProp.current,
    page_size: paginationProp.pageSize
  } as IPage
}

const rowSelection = {
  onChange: (selectedRowKeys: (string | number)[], selectedRows: []) => {
    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
  },
  onSelect: (record: any, selected: boolean, selectedRows: []) => {
    console.log(record, selected, selectedRows)
  },
  onSelectAll: (selected: boolean, selectedRows: [], changeRows: []) => {
    console.log(selected, selectedRows, changeRows)
  },
  getCheckboxProps: (record: any) => ({
    disabled: record.domain !== EDeviceTypeName.Dock,
  }),
}

const workspaceId: string = localStorage.getItem(ELocalStorageKey.WorkspaceId) || ''

const editableData: UnwrapRef<Record<string, Device>> = reactive({})

// 设备升级
const {
  deviceFirmwareUpgradeModalVisible,
  selectedDevice,
  onDeviceUpgrade,
  onUpgradeDeviceOk
} = useDeviceFirmwareUpgrade(workspaceId)

function onDeviceUpgradeWs(payload: DeviceCmdExecuteInfo) {
  updateDevicesByWs(data.device, payload)
}

function updateDevicesByWs(devices: Device[], payload: DeviceCmdExecuteInfo) {
  if (!devices || devices.length <= 0) {
    return
  }
  for (let i = 0; i < devices.length; i++) {
    if (devices[i].device_sn === payload.sn) {
      if (!payload.output) return
      const { status, progress, ext } = payload.output
      if (status === DeviceCmdExecuteStatus.Sent || status === DeviceCmdExecuteStatus.InProgress) { // 升级中
        const rate = ext?.rate ? (ext.rate / 1024).toFixed(2) + 'kb/s' : ''
        devices[i].firmware_status = DeviceFirmwareStatusEnum.DuringUpgrade
        devices[i].firmware_progress = (progress?.percent || 0) + '% ' + rate
      } else { // 终态：成功，失败，超时
        if (status === DeviceCmdExecuteStatus.Failed || status === DeviceCmdExecuteStatus.Timeout) {
          notification.error({
            message: `(${payload.sn}) Upgrade failed`,
            description: `Error Code: ${payload.result}`,
            duration: null
          })
        }
        // 拉取列表
        getDevices(true)
      }
      return
    }
    if (devices[i].children) {
      updateDevicesByWs(devices[i].children || [], payload)
    }
  }
}

useDeviceUpgradeEvent(onDeviceUpgradeWs)

// 获取设备列表信息
function getDevices(closeLoading?: boolean) {
  if (!closeLoading) {
    loading.value = true
  }
  getBindingDevices(workspaceId, getPaginationBody()).then(res => {
    if (res.code !== 0) {
      return
    }
    const resData: Device[] = res.data.list
    expandRows.value = []
    resData.forEach((val: any) => {
      if (val.children) {
        val.children = [val.children]
        expandRows.value.push(val.device_sn);
      }
    })
    data.device = resData;
    paginationProp.total = res.data.pagination.total
    paginationProp.current = res.data.pagination.page
    paginationProp.pageSize = res.data.pagination.page_size
    loading.value = false
  })
}

function refreshData(page: any) {
  paginationProp.current = page?.current!
  paginationProp.pageSize = page?.pageSize!
  getDevices()
}

// 编辑
function edit(record: Device) {
  editableData[record.device_sn] = record
}

// 保存
function save(record: Device) {
  delete editableData[record.device_sn]
  updateDevice({ nickname: record.nickname }, workspaceId, record.device_sn)
}

// 点击删除
const onClickDelete = (record: Device) => {
  Modal.confirm({
    title: '提示',
    content: `确定删除${record.device_name}吗？`,
    onOk: async () => {
      unbindDevice(record.device_sn).then(res => {
        if (res.code !== 0) {
          return
        }
        getDevices()
      })
    },
  });
}

const currentDevice = ref({} as Device)
// 设备日志
const deviceLogUploadRecordVisible = ref(false)
function showDeviceLogUploadRecord(dock: Device) {
  deviceLogUploadRecordVisible.value = true
  currentDevice.value = dock
}

// 健康状态
const hmsVisible = ref<boolean>(false)

function showHms(dock: Device) {
  hmsVisible.value = true
  currentDevice.value = dock
}

onMounted(() => {
  getDevices()
})
</script>

<style lang="scss">
.deviceList {
  padding: 20px;
}

.ant-table {
  border-top: 1px solid rgb(0, 0, 0, 0.06);
  border-bottom: 1px solid rgb(0, 0, 0, 0.06);
}

.ant-table-tbody tr td {
  border: 0;
}

.table-striped {
  background-color: #f7f9fa;
}
</style>