<template>
  <div id="DiscoverDisplay" class="h-all">
    <el-tabs v-model="activedName" @tab-click="handleTabClick" type="border-card" class="adapt-height-box h-all">

      <!-- 发现网元列表展示框 -->
      <el-tab-pane :label="$t('DiscoverDisplay.discoverElement')" name="first" class="h-all adapt-height adapt-height-box">
        <el-table
          :empty-text="$t('common.noData')"
          header-row-class-name="table-header"
          cell-class-name="table-cell"
          class="adapt-height"
          height="auto"
          border
          ref="deviceTable"
          :data=deviceList
          tooltip-effect="dark"
          highlight-current-row
          @select="deviceSelect"
          @select-all="deviceSelectAll"
        >
          <el-table-column
            type="selection"
            width="32">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="displayName"
            :label="$t('DiscoverDisplay.netWorkElementName')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="bussIpAddress"
            :label="$t('DiscoverDisplay.ipAddress')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            :formatter="formatterDeviceType"
            :label="$t('DiscoverDisplay.netWorkElementType')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="deviceModel"
            :label="$t('DiscoverDisplay.netWorkElementModel')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="uuid"
            :label="$t('DiscoverDisplay.uuid')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="subnetKey"
            :label="$t('DiscoverDisplay.belongedSubnet')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="deviceDesc"
            :label="$t('DiscoverDisplay.deviceDesc')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            :label="$t('DiscoverDisplay.operations')">
            <template slot-scope="scope">
              <el-button
                size="mini"
                style="background: #008000"
                :title="$t('common.saveBtn')"
                @click="updateDeviceInit(scope.row)">
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-bianji"></use>
                </svg>
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>

      <!-- 发现链路列表展示框 -->
      <el-tab-pane :label="$t('DiscoverDisplay.discoverLink')" name="second" class="h-all adapt-height adapt-height-box">
        <el-table
          :empty-text="$t('common.noData')"
          header-row-class-name="table-header"
          cell-class-name="table-cell"
          class="adapt-height"
          height="auto"
          border
          ref="linkTable"
          :data="linkList"
          tooltip-effect="dark"
          highlight-current-row
          @select="linkSelect"
          @select-all="linkSelectAll"
        >
          <el-table-column
            type="selection"
            width="32"
            :selectable="isSelectable">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="linkName"
            :label="$t('DiscoverDisplay.linkName')"
            style="font-size: 10px;">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            :formatter="formatterName"
            :label="$t('DiscoverDisplay.startNetworkElement')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="startPortName"
            :label="$t('DiscoverDisplay.startPort')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            :formatter="formatterName1"
            :label="$t('DiscoverDisplay.endNetworkElement')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="endPortName"
            :label="$t('DiscoverDisplay.endPort')">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            :label="$t('DiscoverDisplay.operations')">
            <template slot-scope="scope">
              <el-button
                size="mini"
                style="background: #008000"
                :title="$t('common.saveBtn')"
                @click="updateLinkInit(scope.row)">
                <svg class="icon" aria-hidden="true">
                  <use xlink:href="#icon-bianji"></use>
                </svg>
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
    </el-tabs>
    <v-contextmenu ref="deviceContextmenu" id="rightMenu">
      <v-contextmenu-item v-for="command in contextCommands" :key="command.key" @click="command.execute" :disabled="command.disabled">{{command.name}}</v-contextmenu-item>
    </v-contextmenu>
    <CommandExecuteContext v-bind:commands="commandContext"></CommandExecuteContext>
  </div>
</template>

<script>
// import { PlTable, PlTableColumn } from 'pl-table'
import HelperUtil from '../../utils/HelperUtil'
import {EventBus} from '../../domain/EventBus'
import CommandExecuteContext from '@/commands/CommandExecuteContext'
import DeviceCommands from '@/commands/DeviceCommands'
import DeviceService from "../../domain/services/DeviceService";

export default {
  components: {
    CommandExecuteContext
    // PlTable,
    // PlTableColumn
  },

  props: {
    discoveryCollection: Object, // 网元发现返回的信息
    selectDevicesList: Array, // 选择的多个设备
    selectLinksList: Array // 选择的多个链路
  },

  data () {
    return {
      deviceList: [],
      linkList: [],
      deviceTypeList: {},
      flag: false,
      deviceRow: '',
      linkRow: '',
      updateDeviceKey: '',
      updateLinkKey: '',
      contextCommands: [],
      commandContext: {},
      activedName: 'first'
    }
  },

  computed: {
    discoveryDeviceCommand () {
      return DeviceCommands.DiscoveryDeviceCommand(this.createAndCopyTitle, this.createAndCopyInitList, this.commandContext)
    },
    discoveryLinkCommand () {
      return DeviceCommands.DiscoveryLinkCommand(this.createAndCopyTitle, this.createAndCopyInitList, this.commandContext)
    },
    // 合并的网元List
    totalDevicesList () {
      return [...this.existingDevicesList, ...this.discoveredDevicesList]
    },
    // 合并的网元Map
    totalDevicesMap () {
      return HelperUtil.arrayToObject(this.totalDevicesList, 'deviceKey')
    },
    // 选择的多个设备的Set集合
    selectDevicesSet () {
      return new Set(this.selectDevicesList)
    },
    // 选择的多个链路的Set集合
    selectLinksSet () {
      return new Set(this.selectLinksList)
    },
    // 网元发现返回对象中的网元集合
    discoveredDevicesList () {
      return this.discoveryCollection === null ? [] : JSON.parse(JSON.stringify(this.discoveryCollection.devicesNew))
    },
    existingDevicesList () {
      return this.discoveryCollection
        ? JSON.parse(JSON.stringify(this.discoveryCollection.devicesInDb))
        : []
    },
    // 网元的deviceKey集合
    discoveredDeviceKeysSet () {
      return new Set(this.discoveredDevicesList.map(device => device.deviceKey))
    },
    // 网元集合的Map
    discoveredDevicesMap () {
      return HelperUtil.arrayToObject(this.discoveredDevicesList, 'deviceKey')
    },
    // 网元发现返回对象中的链路集合
    discoveredLinksList () {
      return this.discoveryCollection === null ? [] : JSON.parse(JSON.stringify(this.discoveryCollection.linksNew))
    },
    // 链路的linkKey集合
    discoveredLinkKeysSet () {
      return new Set(this.discoveredLinksList.map(link => link.linkKey))
    },
    // 链路集合的Map
    discoveredLinksMap () {
      return HelperUtil.arrayToObject(this.discoveredLinksList, 'linkKey')
    },
    // 将链路集合转化成一个Object, key为deviceKey，value为与此deviceKey相连接的链路的集合
    deviceKeyToLinkKeys () {
      const tmpObj = {}
      this.discoveredLinksList.forEach(link => {
        const {startDeviceKey, endDeviceKey, linkKey} = link
        if (tmpObj[startDeviceKey]) tmpObj[startDeviceKey].add(linkKey)
        else tmpObj[startDeviceKey] = new Set([linkKey])
        if (tmpObj[endDeviceKey]) tmpObj[endDeviceKey].add(linkKey)
        else tmpObj[endDeviceKey] = new Set([linkKey])
      })
      return tmpObj
    }
  },
  created () {
    this.getDeviceType()
  },

  watch: {
    discoveredDevicesList (val) {
      this.deviceList = val
    },
    discoveredLinksList (val) {
      this.linkList = val
    },
    // 当selectDevicesSet有更新时，更新发现网元的勾选
    selectDevicesSet () {
      this.toggleDevicesSelection()
    },
    // 当selectLinksSet有更新时，更新发现链路的勾选
    selectLinksSet () {
      this.toggleLinksSelection()
    },
    commandContext (newVal, oldVal) {
      if (JSON.stringify(newVal) === '{}') {
        // this.$refs.singleTable.clearSelection()
        if (this.flag) {
          if (this.updateDeviceKey !== '') {
            this.handleDevice()
            this.discoveredDeviceKeysSet.delete(this.updateDeviceKey)
            EventBus.$emit('discoveryDevice', this.updateDeviceKey)
            this.flag = false
            this.updateDeviceKey = ''
          }
          if (this.updateLinkKey !== '') {
            this.handleLink()
            this.discoveredLinkKeysSet.delete(this.updateLinkKey)
            EventBus.$emit('discoveryLinkAll', this.updateLinkKey)
            this.flag = false
            this.updateLinkKey = ''
          }
        }
      }
      deep: true
    }
  },
  mounted () {
    EventBus.$on('checkDevice', this.handleCheckDevice)
    EventBus.$on('checkLink', this.handleCheckLink)
    EventBus.$on('discovery', this.handle)
    EventBus.$on('discoveryLink', this.handleLinkTo)
  },

  methods: {
    /**
     * @Description  : getDeviceType
     * @author       : ls
     * @date         : 2020/12/11 10:52
     * @param        :
     * @return       :
     */
    getDeviceType: function () {
      let _this = this
      DeviceService.getAllDeviceTypeCollection().then(result => {
        _this.deviceTypeList = result
      }).catch(err => {
        _this.InfoTip.errorTip(_this, err)
      })
    },
    /**
     * @Description  : handleDevice
     * @author       : ls
     * @date         : 2020/12/7 9:30
     * @param        :
     * @return       :
     */
    handleDevice: function () {
      let _this = this
      this.deviceList.splice(this.deviceList.findIndex(item => item.deviceKey === _this.updateDeviceKey), 1)
    },
    /**
     * @Description  : handleLink
     * @author       : ls
     * @date         : 2020/12/9 15:39
     * @param        :
     * @return       :
     */
    handleLink: function () {
      let _this = this
      this.linkList.splice(this.linkList.findIndex(item => item.linkKey === _this.updateLinkKey), 1)
    },
    /**
     * @Description  : handle
     * @author       : ls
     * @date         : 2020/12/4 17:36
     * @param        :
     * @return       :
     */
    handle: function (val) {
      this.flag = val
    },
    handleLinkTo: function (val) {
      this.flag = val
    },
    handleCheckDevice: function () {
      this.$refs.deviceTable.toggleRowSelection(this.deviceRow, true)
    },
    handleCheckLink: function () {
      this.$refs.linkTable.toggleRowSelection(this.linkRow, true)
    },
    /**
     * @Description  : update
     * @author       : ls
     * @date         : 2020/12/4 14:57
     * @param        :
     * @return       :
     */
    updateDeviceInit (row) {
      this.deviceRow = row
      this.createAndCopyTitle = this.$t('DeviceConfigurationManagement.updateDeviceInfo')
      this.createAndCopyInitList = row
      this.updateDeviceKey = row.deviceKey
      var arr = []
      arr.push(row)
      this.deviceSelect(arr, row)
      this.discoveryDeviceCommand.execute()
    },
    /**
     * @Description  : updateLinkInit
     * @author       : ls
     * @date         : 2020/12/8 9:34
     * @param        :
     * @return       :
     */
    updateLinkInit (row) {
      const {startDeviceKey, endDeviceKey} = row
      const notStartDeviceUnselectedNewDevice = !this.discoveredDeviceKeysSet.has(startDeviceKey)
      const notEndDeviceUnselectedNewDevice = !this.discoveredDeviceKeysSet.has(endDeviceKey)
      const flag = notStartDeviceUnselectedNewDevice && notEndDeviceUnselectedNewDevice
      if (!flag) {
        var tip = {
          message: '请先把网元保存到数据库中！',
          type: 'warning'
        }
        this.InfoTip.warningTip_alarm(this, tip)
        return
      }
      this.linkRow = row
      this.createAndCopyTitle = this.$t('LinkConfigurationManagement.updateLinkInfo')
      this.createAndCopyInitList = row
      this.updateLinkKey = row.linkKey
      var arr = []
      arr.push(row)
      this.linkSelect(arr, row)
      this.discoveryLinkCommand.execute()
    },
    formatterName: function (val) {
      return this.totalDevicesMap[val.startDeviceKey].displayName
    },
    formatterName1: function (val) {
      return this.totalDevicesMap[val.endDeviceKey].displayName
    },
    formatterDeviceType: function (val) {
      return this.deviceTypeList[val.deviceTypeKey].deviceTypeName
    },
    /**
     * @description 更新发现网元表格的勾选状态
     * @author weixin
     * @date 2020/08/19
     */
    toggleDevicesSelection () {
      // 清空所有勾选
      this.$refs.deviceTable.clearSelection()
      // 将在已选集合的网元勾选
      this.selectDevicesSet.forEach(deviceKey => {
        const row = this.discoveredDevicesMap[deviceKey]
        if (row) this.$refs.deviceTable.toggleRowSelection(row)
      })
    },

    handleTabClick: function () {
      if (this.activedName === 'first' && this.selectDevicesSet.size > 0) {
        this.$nextTick(function () {
          this.selectDevicesSet.forEach(deviceKey => {
            const row = this.discoveredDevicesMap[deviceKey]
            if (row) this.$refs.deviceTable.toggleRowSelection(row, true)
          })
        })
      }
      if (this.activedName === 'second' && this.selectLinksSet.size > 0) {
        this.$nextTick(function () {
          this.selectLinksSet.forEach(linkKey => {
            const row = this.discoveredLinksMap[linkKey]
            if (row) this.$refs.linkTable.toggleRowSelection(row, true)
          })
        })
      }
    },
    /**
     * @description 更新发现链路表格的勾选状态
     * @author weixin
     * @date 2020/08/19
     */
    toggleLinksSelection () {
      // 清空所有勾选
      this.$refs.linkTable.clearSelection()
      // 将在已选集合的链路勾选
      this.selectLinksSet.forEach(linkKey => {
        const row = this.discoveredLinksMap[linkKey]
        if (row) this.$refs.linkTable.toggleRowSelection(row)
      })
    },

    /**
     * @description 发现网元表格checkbox点击事件的响应函数
     * @param {Array} selection 已勾选的行的集合
     * @param {Object} row 当前勾选的行的值
     * @author weixin
     * @date 2020/08/20
     */
    deviceSelect (selection, row) {
      // 判断当前项的状态是勾选还是取消勾选
      const checked = selection.findIndex(device => device.deviceKey === row.deviceKey) !== -1
      // 更新拓扑图的标记
      EventBus.$emit('i-updated-device-check', new Set([row.deviceKey]), checked)
    },

    /**
     * @description 发现网元表格checkbox点击事件的响应函数
     * @param {Array} selection 已勾选的行的集合
     * @param {Object} row 当前勾选的行的值
     * @author weixin
     * @date 2020/08/20
     */
    linkSelect (selection, row) {
      // 判断当前项的状态是勾选还是取消勾选
      const checked = selection.findIndex(link => link.linkKey === row.linkKey) !== -1
      // 更新拓扑图的标记
      EventBus.$emit('i-updated-link-check', new Set([row.linkKey]), checked)
    },

    /**
     * @description 判断当前链路是否可勾选
     * @author weixin
     * @date 2020/08/24
     */
    isSelectable (row, index) {
      // 获取此链路两端的deviceKey
      const {startDeviceKey, endDeviceKey} = row
      // 当两端都不是未被选择的新发现的网元时，允许勾选此链路
      // const notStartDeviceUnselectedNewDevice = !this.discoveredDeviceKeysSet.has(startDeviceKey) || this.selectDevicesSet.has(startDeviceKey)
      // const notEndDeviceUnselectedNewDevice = !this.discoveredDeviceKeysSet.has(endDeviceKey) || this.selectDevicesSet.has(endDeviceKey)
      let noFlag = true
      for (let i = 0; i < this.discoveredDevicesList.length; i++) {
        if (this.discoveredDevicesList[i].deviceKey === startDeviceKey || this.discoveredDevicesList[i].deviceKey === endDeviceKey) {
          noFlag = false
          break
        }
      }
      return noFlag
      // const notStartDeviceUnselectedNewDevice = !this.discoveredDeviceKeysSet.has(startDeviceKey)
      // const notEndDeviceUnselectedNewDevice = !this.discoveredDeviceKeysSet.has(endDeviceKey)
      // return notStartDeviceUnselectedNewDevice && notEndDeviceUnselectedNewDevice
    },

    /**
     * @description 发现网元表格点击顶部checkbox的事件
     * @author weixin
     * @date 2020/08/21
     */
    deviceSelectAll (selection) {
      // 判断状态是全选还是全不选
      const checked = selection.length > 0
      // 更新拓扑图的标记
      EventBus.$emit('i-updated-device-check', this.discoveredDeviceKeysSet, checked)
    },

    /**
     * @description 发现链路表格点击顶部checkbox的事件
     * @author weixin
     * @date 2020/08/21
     */
    linkSelectAll (selection) {
      // 判断状态是全选还是全不选
      const checked = selection.length > 0
      // 更新拓扑图的标记
      var se = new Set()
      if (selection.length !== 0) {
        for (var i = 0; i < selection.length; i++) {
          if (this.discoveredLinkKeysSet.has(selection[i].linkKey)) {
            se.add(selection[i].linkKey)
          }
        }
        EventBus.$emit('i-updated-link-check', se, checked)
      } else {
        this.toggleLinksSelection()
        se.clear()
        EventBus.$emit('i-updated-link-check', this.discoveredLinkKeysSet, checked)
      }
      // EventBus.$emit('i-updated-link-check', se, checked)
      // EventBus.$emit('i-updated-link-check', this.discoveredLinkKeysSet, checked)
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
