<template>
  <div class="tsb-device-shell">
    <div v-if="!currentDeviceSn" class="workspace-empty app-container">
      <el-empty description="请从首页选择已登录设备">
        <el-button type="primary" size="small" @click="goHomeIndex">前往首页</el-button>
      </el-empty>
    </div>

    <template v-else>
      <div class="device-tabs-bar">
        <div
          v-for="item in openedDevices"
          :key="item.deviceSn"
          class="device-tab"
          :class="{ active: isActiveTab(item) }"
          @click="switchDevice(item)"
        >
          <span class="tab-label">SN {{ item.deviceSn }}</span>
          <i
            class="el-icon-close tab-close"
            @click.stop="closeDevice(item)"
          />
        </div>
        <el-button type="text" size="mini" class="add-device-btn" @click="goHomeIndex">
          <i class="el-icon-plus" /> 选择设备
        </el-button>
      </div>

      <div v-if="!isHomePage" class="sub-toolbar">
        <el-button type="text" icon="el-icon-back" @click="goDeviceHome">返回功能菜单</el-button>
        <span class="sub-title">{{ subPageTitle }}</span>
        <span class="sub-sn">设备 SN：{{ currentDeviceSn }}</span>
      </div>

      <keep-alive>
        <component :is="panelComponent" :key="panelCacheKey" :bound-device-sn="currentDeviceSn" />
      </keep-alive>
    </template>
  </div>
</template>

<script>
import tsbWebSocket from '@/utils/tsbWebSocket'
import { ensureWorkspaceTag } from '@/utils/tsbWorkspaceNav'
import { buildDeviceSession, clearTsbDeviceSession, hasTsbDeviceSession, saveTsbDeviceSession } from '@/utils/tsbDeviceSession'
import DeviceHome from './home'
import TaxPage from '@/views/app-common/tax/index'

const PANEL_COMPONENTS = {
  home: DeviceHome,
  tax: TaxPage
}

const PANEL_TITLES = {
  home: '设备功能',
  tax: '报税口'
}

export default {
  name: 'TsbDeviceShell',
  components: { DeviceHome, TaxPage },
  computed: {
    openedDevices() {
      return this.$store.getters.tsbOpenedDevices || []
    },
    currentDeviceSn() {
      return this.$store.getters.tsbCurrentDeviceSn
    },
    currentPanel() {
      return this.$store.getters.tsbCurrentPanel
    },
    isHomePage() {
      return this.currentPanel === 'home'
    },
    subPageTitle() {
      return PANEL_TITLES[this.currentPanel] || ''
    },
    panelComponent() {
      return PANEL_COMPONENTS[this.currentPanel] || DeviceHome
    },
    panelCacheKey() {
      return `${this.currentDeviceSn}-${this.currentPanel}`
    }
  },
  created() {
    if (!hasTsbDeviceSession() || !this.openedDevices.length) {
      this.$store.commit('tsb/SET_SESSION_CHECKED', false)
      this.$tab.closeOpenPage({ path: '/index' })
      return
    }
    this.ensureWsConnected()
    ensureWorkspaceTag()
  },
  activated() {
    if (!hasTsbDeviceSession() || !this.openedDevices.length) {
      return
    }
    this.ensureWsConnected()
    ensureWorkspaceTag()
  },
  methods: {
    ensureWsConnected() {
      const device = this.$store.getters.tsbCurrentDevice
      if (!device || device.deviceSn == null) {
        return
      }
      if (!tsbWebSocket.isConnected()) {
        tsbWebSocket.ensureCurrentDeviceConnection()
      }
    },
    isActiveTab(device) {
      return String(device.deviceSn) === String(this.currentDeviceSn)
    },
    switchDevice(device) {
      if (this.isActiveTab(device)) {
        return
      }
      tsbWebSocket.switchToDevice(device).catch(() => {})
    },
    closeDevice(device) {
      const closingCurrent = this.isActiveTab(device)
      const panelMap = { ...this.$store.state.tsb.devicePanelMap }
      delete panelMap[device.deviceSn]
      this.$store.commit('tsb/SET_DEVICE_PANEL_MAP', panelMap)
      this.$store.commit('tsb/REMOVE_OPENED_DEVICE', device.deviceSn)
      this.$store.commit('tsb/CLEAR_DEVICE_PAGE_FORM', String(device.deviceSn))
      tsbWebSocket.disconnectDevice(device.deviceSn)
      tsbWebSocket.onDeviceTabClosed(device.deviceSn)
      const remaining = this.$store.getters.tsbOpenedDevices
      if (!remaining.length) {
        clearTsbDeviceSession()
        tsbWebSocket.releaseWorkspaceSession()
        this.$store.commit('tsb/SET_SESSION_CHECKED', false)
        this.$tab.closeOpenPage({ path: '/index' })
        return
      }
      const current = this.$store.getters.tsbCurrentDevice
      saveTsbDeviceSession(buildDeviceSession(current, remaining, panelMap))
      if (closingCurrent) {
        const next = remaining[remaining.length - 1]
        tsbWebSocket.switchToDevice(next).catch(() => {})
      }
    },
    goDeviceHome() {
      const sn = this.currentDeviceSn
      if (sn != null) {
        this.$store.commit('tsb/SET_DEVICE_PANEL', { deviceSn: sn, panel: 'home' })
        this.persistPanelMap()
      }
    },
    goHomeIndex() {
      this.$router.push('/index')
    },
    persistPanelMap() {
      saveTsbDeviceSession(buildDeviceSession(
        this.$store.getters.tsbCurrentDevice,
        this.$store.getters.tsbOpenedDevices,
        this.$store.state.tsb.devicePanelMap
      ))
    }
  }
}
</script>

<style scoped lang="scss">
.tsb-device-shell {
  min-height: 100%;
}
.workspace-empty {
  padding-top: 48px;
}
.device-tabs-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 12px;
  background: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
}
.device-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
  font-size: 13px;
  transition: all 0.2s;
  &.active {
    color: #409eff;
    border-color: #409eff;
    background: #ecf5ff;
  }
}
.tab-close {
  font-size: 12px;
  color: #909399;
  &:hover {
    color: #f56c6c;
  }
}
.add-device-btn {
  margin-left: 4px;
}
.sub-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  border-bottom: 1px solid #ebeef5;
  background: #fff;
}
.sub-title {
  font-weight: 600;
  font-size: 14px;
}
.sub-sn {
  margin-left: auto;
  color: #909399;
  font-size: 13px;
}
</style>
