import {
  addDevice, addSubDevice, delDevice, delDeviceMul, delDeviceTag,
  getDeviceById, getDeviceCount, getDeviceList, getDeviceMsgList, addDeviceMsg, getDeviceTag,
  getSubDeviceList, updateDeviceLabel, addDeviceCmd, getDeviceCmdList, addDeviceTag, addDeviceGroup,
  listDeviceGroup, postGroupBindDevice, delGroupBindDevice, getDeviceByGroup, getDevicePage, delSubDevice, getDeviceAttribute, getDevicShadow, getDeviceTopology, getDeviceSession, getDeviceAttributes, getDeviceSecret, getOtaByDeviceId, otaUpgradationRecordByDeviceId, upgradationOtaByDeviceId, liveById, liveControlRts, liveCustomRtsUrl, getDeviceLabelsByLabel
} from '@/api/iot/device'
import { DeviceMsgEnum, OtaStatusEnum } from '@/enum/common'
import { message } from 'ant-design-vue'
import dayjs from 'dayjs'
import { number } from 'echarts'

export class DeviceContriller {
  static deviceStatus = [
    { name: '初始化', key: 'INIT' },
    { name: '链接中', key: 'CONNECT' },
    { name: '断开链接', key: 'DISCONNECT' },
    { name: '禁止连接', key: 'DISABLED' }
  ]

  static transDeviceCountMap = new Map([
    ['TOTAL', { label: '总数', color: 'green' }],
    ['DISABLED', { label: '禁用数', color: 'grey' }],
    ['INIT', { label: '初始化状态数', color: 'orange' }],
    ['CONNECT', { label: '连接数', color: 'skyblue' }],
    ['DISCONNECT', { label: '断开连接数', color: 'red' }]
  ])

  static deviceStatusMap = new Map([
    ['INIT', { color: 'cyan', name: '初始化', key: 'INIT' }],
    ['CONNECT', { color: '#87d068', name: '链接中', key: 'CONNECT' }],
    ['DISCONNECT', { color: '#f50', name: '断开链接', key: 'DISCONNECT' }],
    ['DISABLED', { color: 'grey', name: '禁止连接', key: 'DISABLED' }]
  ])

  static deviceMag = new Map([
    [DeviceMsgEnum.QUEUED, { name: '队列中', key: DeviceMsgEnum.QUEUED }],
    [DeviceMsgEnum.SENT, { name: '已发送', key: DeviceMsgEnum.SENT }],
    [DeviceMsgEnum.DELIVERED, { name: '设备收到', key: DeviceMsgEnum.DELIVERED }],
    [DeviceMsgEnum.TIMEOUT, { name: '超时', key: DeviceMsgEnum.TIMEOUT }],
    [DeviceMsgEnum.FAILED, { name: '失败', key: DeviceMsgEnum.FAILED }]
  ])

  static searchKeyList = [
    { name: '设备ID', key: 'deviceId' },
    { name: '设备标识码', key: 'deviceCode' },
    { name: '设备名称', key: 'deviceLabel' }
  ]

  static otaStatusMap = new Map([
    [OtaStatusEnum.QUEUED, { key: OtaStatusEnum.QUEUED, label: '在消息队列中', color: 'orange' }],
    [OtaStatusEnum.SENT, { key: OtaStatusEnum.SENT, label: '已经发送', color: 'blue' }],
    [OtaStatusEnum.DELIVERED, { key: OtaStatusEnum.DELIVERED, label: '设备已收到', color: 'pink' }],
    [OtaStatusEnum.SUCCESSFUL, { key: OtaStatusEnum.SUCCESSFUL, label: '成功', color: 'green' }],
    [OtaStatusEnum.TIMEOUT, { key: OtaStatusEnum.TIMEOUT, label: '超时', color: 'red' }],
    [OtaStatusEnum.FAILED, { key: OtaStatusEnum.FAILED, label: '失败', color: 'grey' }]
  ])

  static otaStatusList = [
    { key: OtaStatusEnum.QUEUED, label: '在消息队列中' },
    { key: OtaStatusEnum.SENT, label: '已经发送' },
    { key: OtaStatusEnum.DELIVERED, label: '设备已收到' },
    { key: OtaStatusEnum.SUCCESSFUL, label: '成功' },
    { key: OtaStatusEnum.TIMEOUT, label: '超时' },
    { key: OtaStatusEnum.FAILED, label: '失败' }
  ]

  static async page (params: IOT.API.DEVICE.QueryPamars) {
    const { data: _data, sum } = await getDevicePage(params)
    const data = _data.map(item => {
      return {
        ...item,
        deviceStatus: DeviceContriller.deviceStatusMap.get(item.deviceStatus)
      }
    })
    return {
      data,
      sum
    }
  }

  /**
   *
   * @param  deviceStatus 传递对应的key，就只会返回对应状态的设备，不填写返回全部
   * @returns
   */
  static async list (params: {modelId: string, deviceLabel: string, limit: number, lastId: string, deviceStatus: 'INIT' | 'CONNECT' | 'DISCONNECT' | 'DISABLED' | ''} = {
    modelId: '',
    deviceLabel: '',
    limit: 20,
    lastId: '',
    deviceStatus: ''
  }) {
    const data = await getDeviceList(params)
    return {
      ...data,
      data: params.deviceStatus === '' ? data.data : data.data.filter(item => item.deviceStatus === params.deviceStatus)
    }
  }

  static async post (data: IOT.API.DEVICE.BodyParams) {
    const { code } = await addDevice(data)
    if (code === 200) message.success('新增成功')
  }

  static async del (id: string | string[]) {
    if (typeof id === 'string') {
      await delDevice(id)
    } else {
      await delDeviceMul(id)
    }
    message.success('删除成功')
  }

  static async byId (id: string) {
    const { data } = await getDeviceById(id)
    return data
  }

  /** 分页获取子设备列表 */
  static async pageSub (id: string, params: IOT.API.DEVICE.QueryPamars) {
    return await getSubDeviceList(id, params)
  }

  /** 获取设备密匙 */
  static async secret (params: {deviceId: string, authType: 'SECRET' | 'X509CERT'}) {
    return await getDeviceSecret(params)
  }

  /** 新增子设备 */
  static async postSub (data: IOT.API.DEVICE.SubBodyParams) {
    const { code } = await addSubDevice(data)
    if (code === 200) message.success('新增成功')
  }

  static async delSub (id: string) {
    const { code } = await delSubDevice(id)
    if (code === 200) message.success('删除成功')
  }

  static async ListTag (params: {deviceId: number | string}) {
    return await getDeviceTag(params)
  }

  static async delTag (id: string) {
    const { code } = await delDeviceTag(id)
    if (code === 200) message.success('删除标签成功')
  }

  static async postTag (data: IOT.API.DEVICE.DeviceTag[]) {
    const { code } = await addDeviceTag(data)
    if (code === 200) message.success('新增标签成功')
  }

  static async updateLabel (data: {id: string, deviceLabel: string}) {
    const { code } = await updateDeviceLabel(data)
    if (code === 200) message.success('修改设备名称成功')
  }

  static async count () {
    return await getDeviceCount()
  }

  /** 设备统计 */
  static async statistics (params: {modelId: string}) {
    const { data } = await getDeviceCount(params)

    return Object.keys(data).map((key) => {
      return {
        key: key,
        label: DeviceContriller.transDeviceCountMap.get(key)?.label,
        color: DeviceContriller.transDeviceCountMap.get(key)?.color,
        value: data[key as keyof typeof data]
      }
    })
  }

  /** 消息下发 获取列表 */
  static async listDeviceMsg (params: {deviceId: string}) {
    const { data } = await getDeviceMsgList(params)
    return data
  }

  /** 消息下发 下发消息 */
  static async addDeviceMsg (data: {deviceId: string, msgPayload: string, msgLabel: string, topic: string}) {
    await addDeviceMsg(data)
    message.success('新增下发消息成功')
  }

  /** 命令下发 获取列表 */
  static async listDeviceCmd (params: {deviceId: string}) {
    const { data } = await getDeviceCmdList(params)
    return data
  }

  /** 命令下发 新增命令 */
  static async addDeviceCmd (data: { deviceId: string, cmdLabel: string, cmdParameters: any}) {
    const { code } = await addDeviceCmd(data)
    if (code === 200) message.success('新增命令成功')
  }

  /** 设备分组 新增分组 */
  static async postDeviceGroup (data: { groupLabel: string, upperGroupId: string }) {
    const { code } = await addDeviceGroup(data)
    if (code === 200) message.success('新增分组成功')
  }

  /** 设备分组 查询分组 */
  static async listDeviceGroup (params: { upperGroupId: string }) {
    return await listDeviceGroup(params)
  }

  /** 设备分组 设备绑定分组 */
  static async postGroupBindDevice (data: { deviceGroupId: string, deviceId: string }[]) {
    const { code } = await postGroupBindDevice(data)
    if (code === 200) message.success('绑定成功')
  }

  /**
 * 此函数删除设备和设备组之间的绑定并显示成功消息。
 * @param data - 参数 `data` 是一个包含两个属性的对象：
 */
  static async delGroupBindDevice (data: { deviceGroupId: string, deviceId: string }[]) {
    const { code } = await delGroupBindDevice(data)
    if (code === 200) message.success('取消绑定成功')
  }

  /**
   * 此函数根据 TypeScript 中的组查询参数检索设备。
   * @param params -
   * 参数“params”的类型为“IOT.API.DEVICE.GroupQueryParams”，这可能是代码库中定义的接口或类型。它用作函数“getDeviceByGroup”的参数，该函数使用“await”关键字调用以生成函数
   * @returns 正在使用 params 参数调用 getDeviceByGroup 函数，并使用 return
   * 关键字返回该函数调用的结果。该函数被标记为“async”，因此它将返回一个解析为“getDeviceByGroup”函数调用结果的承诺。
   */
  static async getDeviceByGroup (params: IOT.API.DEVICE.GroupQueryParams) {
    return await getDeviceByGroup(params)
  }

  static async getLiveData (deviceId: string) {
    return await getDeviceAttribute(deviceId)
  }

  /** 获取设备属性 */
  static async getDeviceAttribute (deviceId: string) {
    return await getDeviceAttribute(deviceId)
  }

  static async getDevicShadow (deviceId: string) {
    return await getDevicShadow(deviceId)
  }

  static async getDeviceTopology (modelId: string) {
    return await getDeviceTopology(modelId)
  }

  static async getSession (params: {deviceId: string, start: number, end: number}) {
    const { data, sum } = await getDeviceSession(params)

    return {
      data: {
        sessionEntities: data.sessionEntities.map(item => {
          return {
            ...item,
            createAt: dayjs(item.createAt).format('YYYY/MM/DD HH:mm:ss')
          }
        }),
        offlineNum: data.offlineNum,
        onlineNum: data.onlineNum
      },
      sum
    }
  }

  static async getAttr (params: {deviceId: string, start: number, end: number, attributeKey: string}) {
    return await getDeviceAttributes(params)
  }

  static async OtaByDeviceId (deviceId: string) {
    const data = await getOtaByDeviceId(deviceId)

    return {
      ...data,
      data: {
        ...data,
        otaTime: data.data.otaTime === 0 ? '尚未升级' : data.data.otaTime,
        otaPkgLabel: data.data.otaPkgLabel === '--' ? '尚未升级' : data.data.otaPkgLabel,
        otaPkgVersion: data.data.otaPkgVersion === '--' ? '尚未升级' : data.data.otaPkgVersion
      }
    }
  }

  static async OtaUpgradationRecordByDeviceId (params: IOT.API.DEVICE.OtaQueryParams) {
    const data = await otaUpgradationRecordByDeviceId(params)
    return {
      ...data,
      data: data.data.map(item => ({ ...item, otaTime: dayjs(item.otaTime).format('YYYY-MM-DD HH:mm:ss') }))
    }
  }

  static async upgradationOtaByDeviceId ({ deviceId, otaPkgId }: {deviceId: string, otaPkgId: string}) {
    await upgradationOtaByDeviceId(deviceId, otaPkgId)
    message.success('升级设备成功')
  }

  static async liveById (deviceId: string) {
    return liveById(deviceId)
  }

  static async liveControlRts (deviceId: string, channel: number) {
    return liveControlRts(deviceId, channel)
  }

  static async liveCustomRtsUrl (data: {id: string, rtsUrl: string}) {
    return liveCustomRtsUrl(data)
  }

  /**
   * @description 模糊查询：根据设备名称来查询全部的符合条件的设备名
   */
  static async labelsByLabel (deviceLabel: string) {
    return await getDeviceLabelsByLabel(deviceLabel)
  }
}
