<template>
  <div v-loading="!loaded && loading">
    <template v-if="loaded || !loading">
      <warning
        v-if="!loaded && !loading"
        @click="getBoundThirdPartyDevices"
      />
      <div
        v-else
        class="l-flex__auto u-overflow-x--auto"
      >
        <div class="c-link-state">
          <div
            v-for="item in items"
            :key="item.key"
            class="o-link-device has-bg"
            v-bind="getAttrs(item.key)"
          >
            <div class="o-link-device__name u-bold">{{ item.label }}</div>
          </div>
          <div
            v-for="line in lines"
            :key="line.key"
            class="o-line"
            :class="line.className"
          />
        </div>
      </div>
    </template>
  </div>
</template>

<script>
import { getBoundThirdPartyDevices } from '@/api/external'
import { ThirdPartyDevice } from '@/constant'
import { ScreenshotCache } from '@/utils/cache'

const KeyMap = {
  [ThirdPartyDevice.GATEWAY]: 'gateway',
  [ThirdPartyDevice.RECEIVING_CARD]: 'receive_card',
  [ThirdPartyDevice.SENDING_CARD]: 'sending_device',
  [ThirdPartyDevice.SCREEN]: 'led',
  [ThirdPartyDevice.LED_CAMERA]: 'led_camera',
  [ThirdPartyDevice.TRAFFIC_CAMERA]: 'traffic_camera'
}

export default {
  name: 'LinkState',
  props: {
    device: {
      type: Object,
      required: true
    },
    online: {
      type: [Boolean, String],
      default: false
    }
  },
  data () {
    return {
      items: [
        {
          label: '浪潮屏媒安播云平台',
          key: 'msr'
        },
        {
          label: '浪潮超高清媒体播控器',
          key: 'device'
        },
        {
          label: '浪潮物联网关',
          key: 'gateway'
        },
        {
          label: '发送控制设备',
          key: 'sending_device'
        },
        {
          label: '人流量监测摄像头',
          key: 'traffic_camera'
        },
        {
          label: 'LED屏监测摄像头',
          key: 'led_camera'
        },
        {
          label: '接收卡',
          key: 'receive_card'
        },
        {
          label: 'LED大屏',
          key: 'led'
        }
      ],
      lineFromeTo: {
        1: ['msr', 'device'],
        2: ['device', 'sending_device'],
        3: ['device', 'receive_card'],
        4: ['receive_card', 'led'],
        5: ['msr', 'gateway'],
        6: ['msr', 'led_camera', 'traffic_camera'],
        7: ['msr', 'traffic_camera'],
        8: ['msr', 'led_camera'],
        9: ['msr', 'led_camera'],
        10: ['gateway', 'led']
      },
      linkState: {
        msr: 0,
        device: this.online ? 0 : 1,
        led: this.online ? 0 : 1,
        gateway: 2,
        sending_device: 2,
        traffic_camera: 2,
        led_camera: 2,
        receive_card: 2
      },
      loading: true,
      loaded: false,
      base64: null
    }
  },
  computed: {
    lines () {
      const lineFromeTo = this.lineFromeTo
      const state = this.linkState
      return Object.keys(lineFromeTo).map(key => {
        const from = lineFromeTo[key][0]
        const to = lineFromeTo[key].slice(1)
        return {
          key: `line${key}`,
          className: [`l${key}`, state[from] === 0 && to.some(key => state[key] === 0) ? 'linked' : ''].join(' ')
        }
      })
    }
  },
  watch: {
    online () {
      this.init()
    }
  },
  created () {
    this.init()
    this.$timer = setInterval(this.init, 10000)
  },
  beforeDestroy () {
    if (this.online) {
      ScreenshotCache.unwatch(this.device.id)
    }
    clearInterval(this.$timer)
  },
  methods: {
    init () {
      if (this.online) {
        ScreenshotCache.watch(this.device, this.onScreenshotUpdate, 10000)
      } else {
        this.base64 = null
      }
      this.getBoundThirdPartyDevices()
    },
    onScreenshotUpdate ({ waiting, base64 }) {
      if (!waiting) {
        this.base64 = base64
      }
    },
    getBoundThirdPartyDevices () {
      this.loading = true
      getBoundThirdPartyDevices(this.device.id, true)
        .then(({ data }) => {
          const form = {
            msr: 0,
            device: this.online ? 0 : 1,
            led: this.online ? 0 : 1,
            gateway: 2,
            sending_device: 2,
            receive_card: 2,
            traffic_camera: 2,
            led_camera: 2
          }
          for (const item of data) {
            form[KeyMap[item.deviceType]] = item.status === 1 ? 0 : 1
          }
          this.linkState = form
          this.loaded = true
        })
        .finally(() => {
          this.loading = false
        })
    },
    getAttrs (key) {
      const value = this.linkState[key]
      let style = null
      switch (key) {
        case 'led':
          if (value === 0 && this.base64) {
            style = {
              backgroundImage: `url("${this.base64}")`
            }
          }
          break
        default:
          break
      }
      return {
        'class': [
          key,
          value === 0
            ? 'online'
            : value === 1
              ? 'offline'
              : 'unbind'
        ].join(' '),
        style
      }
    }
  }
}
</script>

<style lang="scss" scoped>
@mixin getPosition($left, $top, $width, $height) {
  top: $top;
  left: $left;
  width: $width;
  height: $height;
}

.c-link-state {
  position: relative;
  min-width: 1024px;
  min-height: 490px;
  overflow-x: auto;
}

.o-line {
  position: absolute;
  background-color: $border;

  &.linked {
    background-color: #026af2;
  }

  &.l1 {
    transform: skewY(-30deg);
    transform-origin: left;
    @include getPosition(180px, 178px, 122px, 1px);
  }

  &.l2 {
    @include getPosition(402px, 92px, 107px, 1px);
  }

  &.l3 {
    @include getPosition(638px, 92px, 107px, 1px);
  }

  &.l4 {
    @include getPosition(808px, 129px, 1px, 80px);
  }

  &.l5 {
    transform: skewY(30deg);
    transform-origin: left;
    @include getPosition(170px, 244px, 122px, 1px);
  }

  &.l6 {
    @include getPosition(234px, 209px, 258px, 1px);
  }

  &.l7 {
    @include getPosition(490px, 209px, 1px, 105px);
  }

  &.l8 {
    @include getPosition(490px, 314px, 52px, 1px);
  }

  &.l9 {
    @include getPosition(490px, 209px, 52px, 1px);
  }

  &.l10 {
    @include getPosition(402px, 369px, 268px, 1px);
  }
}

.o-link-device {
  position: absolute;
  z-index: 1;

  &__name {
    position: absolute;
    top: 100%;
    left: 50%;
    color: $black;
    font-size: 16px;
    line-height: 1;
    white-space: nowrap;
    transform: translateX(-50%);
  }

  &.unbind {
    background-image: url("~@/assets/linkState/icon_unbound.svg");
  }

  &.msr {
    @include getPosition(0, 42px, 242px, 236px);
    background-image: url("~@/assets/linkState/icon_msr.svg");
  }

  &.device {
    @include getPosition(270px, 0, 138px, 138px);

    &.online {
      background-image: url("~@/assets/linkState/icon_device_online.svg");
    }

    &.offline {
      background-image: url("~@/assets/linkState/icon_device_offline.svg");
    }
  }

  &.sending_device {
    @include getPosition(504px, 0, 138px, 138px);

    &.online {
      background-image: url("~@/assets/linkState/icon_sending_device_online.svg");
    }

    &.offline {
      background-image: url("~@/assets/linkState/icon_sending_device_offline.svg");
    }
  }

  &.receive_card {
    @include getPosition(740px, 0, 138px, 138px);

    &.online {
      background-image: url("~@/assets/linkState/icon_receive_card_online.svg");
    }

    &.offline {
      background-image: url("~@/assets/linkState/icon_receive_card_offline.svg");
    }

    .o-link-device__name {
      transform: translateX(8px);
    }
  }

  &.traffic_camera {
    @include getPosition(528px, 162px, 79px, 79px);
  }

  &.led_camera {
    @include getPosition(528px, 262px, 79px, 79px);
  }

  &.traffic_camera,
  &.led_camera {
    &.online {
      background-image: url("~@/assets/linkState/icon_camera_online.svg");
    }

    &.offline {
      background-image: url("~@/assets/linkState/icon_camera_offline.svg");
    }
  }

  &.gateway {
    @include getPosition(270px, 278px, 138px, 138px);

    &.online {
      background-image: url("~@/assets/linkState/icon_gateway_online.svg");
    }

    &.offline {
      background-image: url("~@/assets/linkState/icon_gateway_offline.svg");
    }
  }

  &.led {
    @include getPosition(670px, 209px, 352px, 198px);
    background-color: rgba(#000, 0.8);
    background-position: center center;
    background-size: contain;
    background-repeat: no-repeat;

    &.online {
      background-image: url("~@/assets/image_no_program.svg");
    }

    &.offline {
      background-image: url("~@/assets/image_offline.svg");
    }

    .o-link-device__name {
      top: -8px;
      left: auto;
      right: 0;
      bottom: auto;
      transform: translateY(-100%);
    }
  }
}
</style>
