import AlarmAPI from '../../api/restApis/AlarmAPI'
import HelperUtil from '../../utils/HelperUtil'
import Vue from 'vue'
import DeviceStateSocketApi from '../../api/websocketApis/DeviceStateSocketApi'
import LinkService from './LinkService'
import {
  ALARM_KEY,
  ALARM_CLEAR_STATUS_ENUM,
  ALARM_COMFIRM_STATUS_ENUM,
  ENABLED_STATUS_ENUM,
  DISCOVER_STATUS_ENUM,
  DISABLED_STATUS_ENUM,
  DEVICE_DISABLED_STATUS_ENUM,
  DEVICE_ENABLED_STATUS_ENUM,
  DEVICE_DISCOVER_STATUS_ENUM
} from '../../utils/constantCollection'

let helperMethods = {
  // 通过 告警设备的状态 推断 所连接的链路的状态信息
  batchUpdateLinksStatus: function (links, devices, alarms, returnObject) {
    // for (var linkKey in links) {
    //   if (links[linkKey].startDeviceKey === returnObject.elementKey || links[linkKey].endDeviceKey === returnObject.elementKey) {
    //     LinkService.updateLinkStatusByAlarmCause(links, devices, alarms, links[linkKey])
    //   }
    // }
    for (var linkKey in links) {
      if (returnObject.isLink === 1 && returnObject.elementKey === linkKey) {
        LinkService.updateLinkStatusByAlarmCause(links, devices, alarms, links[linkKey])
        break
      }
    }
  },

  // 恢复告警相关设备的链路状态
  recoverLinkStatus: function (links, returnObject) {
    // for (var linkKey in links) {
    //   if (links[linkKey].startDeviceKey === returnObject.elementKey || links[linkKey].endDeviceKey === returnObject.elementKey) {
    //     links[linkKey].status = ENABLED_STATUS_ENUM
    //   }
    // }
    for (var linkKey in links) {
      if (returnObject.isLink === 0 && returnObject.elementKey === linkKey) {
        links[linkKey].status = ENABLED_STATUS_ENUM
        break
      }
    }
  },
  addDeviceAndTopologyStatus: function (devices, topologys) {
    for (var deviceKey in devices) {
      if (devices[deviceKey].deviceStatus === DEVICE_DISABLED_STATUS_ENUM) {
        Vue.set(devices[deviceKey], 'status', DISABLED_STATUS_ENUM)
        Vue.set(topologys[devices[deviceKey].subnetKey], 'status', DISABLED_STATUS_ENUM)
      } else if (devices[deviceKey].deviceStatus === DEVICE_ENABLED_STATUS_ENUM) {
        Vue.set(devices[deviceKey], 'status', ENABLED_STATUS_ENUM)
        Vue.set(topologys[devices[deviceKey].subnetKey], 'status', ENABLED_STATUS_ENUM)
      } else if (devices[deviceKey].deviceStatus === DEVICE_DISCOVER_STATUS_ENUM) {
        Vue.set(devices[deviceKey], 'status', DISCOVER_STATUS_ENUM)
        Vue.set(topologys[devices[deviceKey].subnetKey], 'status', DISCOVER_STATUS_ENUM)
      }
    }
  },
}

// 静态方法
let staticMethods = {
  // 获取所有告警
  getAllAlarmCollection: function () {
    return AlarmAPI.getAlarmCollection().then(result => {
      if (result.data.result) {
        return HelperUtil.arrayToObject(result.data.returnValue, ALARM_KEY)
      } else {
        return HelperUtil.returnPromiseRejectObj(result)
      }
    })
  },

  // 批量确认告警
  batchAlarmConfirm: function (alarmKeys) {
    return AlarmAPI.putAlarmConfirm(alarmKeys).then(result => {
      if (result.data.result) {
      } else {
        return HelperUtil.returnPromiseRejectObj(result)
      }
    })
  },

  // 批量清除告警
  batchAlarmClear: function (alarmKeys) {
    return AlarmAPI.putAlarmClearup(alarmKeys).then(result => {
      if (result.data.result) {
      } else {
        return HelperUtil.returnPromiseRejectObj(result)
      }
    })
  },
  // 批量删除告警
  batchAlarmDelete: function (alarmKeys) {
    return AlarmAPI.putAlarmDelete(alarmKeys).then(result => {
      if (result.data.result) {
      } else {
        return HelperUtil.returnPromiseRejectObj(result)
      }
    })
  },
  // 更新设备以及服务器状态状态
  updateDeviceAndTopologyAndServerStatus: function (alarms, devices, topologys, subnets) {
    for(var subnet in subnets) {
      Vue.set(topologys[subnet], 'status', -1)
      Vue.set(subnets[subnet], 'status', -1)
    }
    for (var alarmKey in alarms) {
      if (alarms[alarmKey].isLink === 0) {
        var elementKeyTemp = alarms[alarmKey].elementKey
        for (var subnetKey in subnets) {
          for (var deviceKey in topologys[subnetKey].deviceList) {
            if (elementKeyTemp === deviceKey) {
              // 更新对应设备结点的信息
              var a = parseInt(alarms[alarmKey].alarmLevel)
              var b = parseInt(devices[deviceKey].status)
              if (a >= b && devices[deviceKey].deviceStatus === 0) {
                Vue.set(devices[deviceKey], 'status', alarms[alarmKey].alarmLevel)
                Vue.set(topologys[subnetKey].deviceList[deviceKey], 'status', alarms[alarmKey].alarmLevel)
                Vue.set(subnets[subnetKey].deviceList[deviceKey], 'status', alarms[alarmKey].alarmLevel)
                if (subnets[subnetKey].status < alarms[alarmKey].alarmLevel) {
                  Vue.set(topologys[subnetKey], 'status', alarms[alarmKey].alarmLevel)
                  Vue.set(subnets[subnetKey], 'status', alarms[alarmKey].alarmLevel)
                }
              }
            }
          }
        }
      }
    }
  }
}

function AlarmService (websocketService = null) {
  // 新建告警
  function subscribeAddAlarm (alarms, devices, topologys, links, servers,subnets, mutator = (alarms, devices, topologys, links, servers,subnets) => {}) {
    websocketService.subscribe(DeviceStateSocketApi.MsgType.ADD_ALARM, alarms, (returnObject) => {
      console.log('aaa告警新增之前长度+++++++++++++++' + Object.keys(alarms).length)
      console.log('bbb告警新增长度+++++++++++++++' + returnObject.length)
      for (var i = 0; i < returnObject.length; i++) {
        switch (returnObject[i].isLink) {
        // 设备
          case 0:
            Vue.set(returnObject[i], 'elementName', devices[returnObject[i].elementKey].displayName)
            Vue.set(returnObject[i], 'deviceTypeName', devices[returnObject[i].elementKey].deviceTypeName)
            break
          case 1:
            Vue.set(returnObject[i], 'elementName', links[returnObject[i].elementKey].linkName)
            break
          default:
        }
        // 将新建对象添加到 alarmList 中
        for (let t in alarms) {
          if (t === returnObject[0].alarmKey) {
            console.log('ttt告警新增中alarm已经存在1' + JSON.stringify(alarms[t]))
            console.log('ccc告警新增中alarm已经存在' + JSON.stringify(returnObject[0]))
          }
        }
        Vue.set(alarms, returnObject[i].alarmKey, returnObject[i])
        helperMethods.batchUpdateLinksStatus(links, devices, alarms, returnObject[i])
      }
      console.log('ddd告警新增之后长度+++++++++++++++' + Object.keys(alarms).length)
      staticMethods.updateDeviceAndTopologyAndServerStatus(alarms, devices, topologys,subnets)
      mutator(alarms, devices, topologys, links, servers,subnets)
    })
  }
  function unsubscribeAddAlarm (alarms) {
    websocketService.unsubscribe(DeviceStateSocketApi.MsgType.ADD_ALARM, alarms)
  }

  // 删除告警
  function subscribeDeleteAlarm (alarms, devices, topologys, links, mutator = (alarms, devices, topologys, links) => {}) {
    websocketService.subscribe(DeviceStateSocketApi.MsgType.DELETE_ALARM, alarms, (returnObject) => {
      for (let i = 0; i < returnObject.length; i++) {
        Vue.delete(alarms, returnObject[i].alarmKey)
        helperMethods.batchUpdateLinksStatus(links, devices, alarms, returnObject[i])
      }
      staticMethods.updateDeviceAndTopologyAndServerStatus(alarms, devices, topologys)
      mutator(alarms, devices, topologys, links)
    })
  }
  function unsubscribeDeleteAlarm (alarms) {
    websocketService.unsubscribe(DeviceStateSocketApi.MsgType.DELETE_ALARM, alarms)
  }

  // 修改告警
  function subscribeModifyAlarm (alarms, devices, topologys, links,subnets, mutator = (alarms, devices, topologys, links,subnets) => {}) {
    websocketService.subscribe(DeviceStateSocketApi.MsgType.MODIFY_ALARM, alarms, (returnObject) => {
      console.log('修改告警')
      for (var i = 0; i < returnObject.length; i++) {
        alarms[returnObject[i].alarmKey].isLink = returnObject[i].isLink
        alarms[returnObject[i].alarmKey].deviceTypeKey = returnObject[i].deviceTypeKey
        alarms[returnObject[i].alarmKey].elementKey = returnObject[i].elementKey
        alarms[returnObject[i].alarmKey].deviceModel = returnObject[i].deviceModel
        alarms[returnObject[i].alarmKey].slotNum = returnObject[i].slotNum
        alarms[returnObject[i].alarmKey].portName = returnObject[i].portName
        alarms[returnObject[i].alarmKey].alarmLevel = returnObject[i].alarmLevel
        alarms[returnObject[i].alarmKey].alarmCode = returnObject[i].alarmCode
        alarms[returnObject[i].alarmKey].alarmName = returnObject[i].alarmName
        // alarms[returnObject[i].alarmKey].cause = returnObject[i].cause;
        alarms[returnObject[i].alarmKey].alarmCount = returnObject[i].alarmCount
        alarms[returnObject[i].alarmKey].alarmStatus = returnObject[i].alarmStatus
        alarms[returnObject[i].alarmKey].firstTime = returnObject[i].firstTime
        alarms[returnObject[i].alarmKey].curTime = returnObject[i].curTime
        alarms[returnObject[i].alarmKey].recoverTime = returnObject[i].recoverTime
        alarms[returnObject[i].alarmKey].clearTime = returnObject[i].clearTime
        alarms[returnObject[i].alarmKey].confirmTime = returnObject[i].confirmTime
        alarms[returnObject[i].alarmKey].confirmUser = returnObject[i].confirmUser
        alarms[returnObject[i].alarmKey].deleteUser = returnObject[i].deleteUser
        alarms[returnObject[i].alarmKey].deleteTime = returnObject[i].deleteTime
        alarms[returnObject[i].alarmKey].confirmUser = returnObject[i].confirmUser
        alarms[returnObject[i].alarmKey].confirmUser = returnObject[i].confirmUser
        alarms[returnObject[i].alarmKey].note = returnObject[i].note
        staticMethods.updateDeviceAndTopologyAndServerStatus(alarms, devices, topologys,subnets)
        helperMethods.batchUpdateLinksStatus(links, devices, alarms, returnObject[i])
      }
      mutator(alarms, devices, topologys, links)
    })
  }
  function unsubscribeModifyAlarm (alarms) {
    websocketService.unsubscribe(DeviceStateSocketApi.MsgType.MODIFY_ALARM, alarms)
  }

  // 确认告警
  function subscribeConfirmAlarm (alarms, mutator = (alarms) => {}) {
    websocketService.subscribe(DeviceStateSocketApi.MsgType.CONFIRM_ALARM, alarms, (returnObject) => {
      for (var i = 0; i < returnObject.length; i++) {
        Vue.set(alarms[returnObject[i].alarmKey], 'alarmStatus', ALARM_COMFIRM_STATUS_ENUM)
        Vue.set(alarms[returnObject[i].alarmKey], 'confirmUser', returnObject[i].confirmUser)
      }
      mutator(alarms)
    })
  }
  function unsubscribeConfirmAlarm (alarms) {
    websocketService.unsubscribe(DeviceStateSocketApi.MsgType.CONFIRM_ALARM, alarms)
  }
  // 清除告警
  function subscribeClearAlarm (alarms, mutator = (alarms) => {}) {
    websocketService.subscribe(DeviceStateSocketApi.MsgType.CLEAR_ALARM, alarms, (returnObject) => {
      for (var i = 0; i < returnObject.length; i++) {
        Vue.set(alarms[returnObject[i].alarmKey], 'alarmStatus', ALARM_CLEAR_STATUS_ENUM)
        Vue.set(alarms[returnObject[i].alarmKey], 'clearUser', returnObject[i].clearUser)
      }
      mutator(alarms)
    })
  }
  function unsubscribeClearAlarm (alarms) {
    websocketService.unsubscribe(DeviceStateSocketApi.MsgType.CLEAR_ALARM, alarms)
  }
  // 恢复告警
  function subscribeRecoverAlarm (alarms, devices, topologys, links, servers,subnets, mutator = (alarms, devices, topologys, links, servers,subnets) => {}) {
    websocketService.subscribe(DeviceStateSocketApi.MsgType.RECOVER_ALARM, alarms, (returnObject) => {
      if (window.sessionStorage.getItem('del') === '1') {
        for (var j = 0; j < returnObject.length; j++) {
          Vue.delete(alarms, returnObject[j].alarmKey)
          staticMethods.updateDeviceAndTopologyAndServerStatus(alarms, devices, topologys, subnets)
          // 将告警设备相关链路的状态进行恢复
          helperMethods.recoverLinkStatus(links, returnObject[j])
          helperMethods.batchUpdateLinksStatus(links, devices, alarms, returnObject[j])
        }
        window.sessionStorage.setItem('del', '2')
      } else {
        console.log('000告警恢复开始-----------')
        console.log('111告警恢复之前长度-----------' + Object.keys(alarms).length)
        console.log('222告警恢复的条数------------' + returnObject.length)
        for (var i = 0; i < returnObject.length; i++) {
          if (alarms[returnObject[0].alarmKey] === undefined) {
            console.log('333告警恢复消息--  告警不存在')
          }
          Vue.delete(alarms, returnObject[i].alarmKey)
          if (JSON.stringify(devices) !== '{}') {
            switch (returnObject[i].isLink) {
              case 0:
                // 对设备对象进行字段的补充
                switch (devices[returnObject[i].elementKey].deviceStatus) {
                  case 0:
                    devices[returnObject[i].elementKey].status = ENABLED_STATUS_ENUM
                    topologys[devices[returnObject[i].elementKey].subnetKey].deviceList[returnObject[i].elementKey].status = ENABLED_STATUS_ENUM
                    break
                  case 1:
                    devices[returnObject[i].elementKey].status = DISABLED_STATUS_ENUM
                    topologys[devices[returnObject[i].elementKey].subnetKey].deviceList[returnObject[i].elementKey].status = DISABLED_STATUS_ENUM
                    break
                  case 2:
                    devices[returnObject[i].elementKey].status = DISCOVER_STATUS_ENUM
                    topologys[devices[returnObject[i].elementKey].subnetKey].deviceList[returnObject[i].elementKey].status = DISCOVER_STATUS_ENUM
                    break
                  default:
                }
                break
              case 1:
                links[returnObject[i].elementKey].status = ENABLED_STATUS_ENUM
                break
              default:
            }
            staticMethods.updateDeviceAndTopologyAndServerStatus(alarms, devices, topologys,subnets)
            // 将告警设备相关链路的状态进行恢复
            helperMethods.recoverLinkStatus(links, returnObject[i])
            helperMethods.batchUpdateLinksStatus(links, devices, alarms, returnObject[i])
          }
        }
        console.log('444告警恢复之后长度-----------' + Object.keys(alarms).length)
        console.dir('555告警恢复消息-----------' + JSON.stringify(returnObject[0]))
      }
      mutator(alarms, devices, topologys, links, servers, subnets)
    })
  }
  function unsubscribeRecoverAlarm (alarms) {
    websocketService.unsubscribe(DeviceStateSocketApi.MsgType.RECOVER_ALARM, alarms)
  }
  function subscribeRefreshAlarm (alarms, devices, topologys, links, subnets, mutator = (alarms, devices, topologys, links, subnets) => {}) {
    websocketService.subscribe(DeviceStateSocketApi.MsgType.REFRESH_ALARM, alarms, (returnObject) => {
      var als = []
      var alsT = {}
      AlarmAPI.getAlarmCollection().then(result => {
        if (result.data.result) {
          als = result.data.returnValue
          alsT = HelperUtil.arrayToObject(als, ALARM_KEY)
          helperMethods.addDeviceAndTopologyStatus(devices, topologys)
          AlarmService.updateDeviceAndTopologyAndServerStatus(alsT, devices, topologys, subnets)
          for (var linkKey in links) {
            LinkService.updateLinkStatusByAlarmCause(links, devices, alsT, links[linkKey])
          }
          mutator(alsT, devices, topologys, links, subnets)
        } else {
          return HelperUtil.returnPromiseRejectObj(result)
        }
      })
    })
  }
  function unsubscribeRefreshAlarm (alarms) {
    websocketService.unsubscribe(DeviceStateSocketApi.MsgType.REFRESH_ALARM, alarms)
  }

  return Object.freeze(Object.assign(
    {
      // object methods comes here
      subscribeAddAlarm,
      unsubscribeAddAlarm,
      subscribeDeleteAlarm,
      unsubscribeDeleteAlarm,
      subscribeModifyAlarm,
      unsubscribeModifyAlarm,
      subscribeConfirmAlarm,
      unsubscribeConfirmAlarm,
      subscribeClearAlarm,
      unsubscribeClearAlarm,
      subscribeRecoverAlarm,
      unsubscribeRecoverAlarm,
      subscribeRefreshAlarm,
      unsubscribeRefreshAlarm
    },
    staticMethods
  ))
}
// inject static methods
Object.assign(AlarmService, staticMethods)
export default AlarmService
