<template>
  <div class="opw-query">
    <el-card shadow="never" class="mb16">
      <el-row type="flex" align="middle" :gutter="12">
        <el-col :span="8">
          <span class="label">总罐数</span>
          <span class="value">{{ displayTotalTanks }}</span>
          <span class="unit">个</span>
        </el-col>
        <el-col :span="16" style="text-align: right">
          <el-button type="primary" size="mini" @click="queryA">A口查询</el-button>
          <el-button type="primary" size="mini" @click="queryB">B口查询</el-button>
          <el-button type="primary" size="mini" @click="query485">485查询</el-button>
        </el-col>
      </el-row>
    </el-card>

    <el-table :data="form.tankList" border size="small" max-height="360" class="mb16">
      <el-table-column
        v-for="col in tankColumns"
        :key="col.prop"
        :prop="col.prop"
        :label="col.label"
        :min-width="col.width"
        show-overflow-tooltip
      />
    </el-table>

    <el-row type="flex" justify="space-between" align="middle">
      <el-col :span="16">
        <span class="label">执行结果：</span>
        <el-tag size="mini" :type="resultTag(form.queryResult)">{{ form.queryResult || '-' }}</el-tag>
      </el-col>
      <el-col :span="8" style="text-align: right">
        <el-button size="mini" @click="viewRawLog">查看原始日志</el-button>
      </el-col>
    </el-row>

    <el-dialog title="原始日志" :visible.sync="logDialogVisible" width="520px" append-to-body>
      <el-input type="textarea" :rows="12" :value="form.rawLog || ''" readonly />
    </el-dialog>
  </div>
</template>

<script>
import tsbWebSocket from '@/utils/tsbWebSocket'
import { OPW_CMD, OPW_BUTTON, OPW_TANK_COLUMNS, applyPartialFields } from '@/utils/tsbOpwConfig'

const PAGE_CMD = OPW_CMD.QUERY
const DISPLAY_FIELDS = ['totalTankCount', 'queryResult', 'rawLog', 'tankList']

function createDefaultForm() {
  return {
    totalTankCount: null,
    queryResult: '',
    rawLog: '',
    tankList: []
  }
}

export default {
  name: 'TsbOpwQuery',
  props: {
    boundDeviceSn: { type: [Number, String], default: null }
  },
  data() {
    return {
      tankColumns: OPW_TANK_COLUMNS,
      form: createDefaultForm(),
      logDialogVisible: false
    }
  },
  computed: {
    ownerDeviceSn() {
      return this.boundDeviceSn
    },
    canOperateDevice() {
      const activeSn = this.$store.getters.tsbCurrentDeviceSn
      return String(activeSn) === String(this.ownerDeviceSn)
    },
    displayTotalTanks() {
      return this.form.totalTankCount != null && this.form.totalTankCount !== '' ? this.form.totalTankCount : '-'
    }
  },
  watch: {
    '$store.state.tsb.pageDataVersion'() {
      this.tryApplyWsPageData(false)
    },
    '$store.state.tsb.deviceSwitchVersion'() {
      if (String(this.$store.getters.tsbCurrentDeviceSn) === String(this.ownerDeviceSn)) {
        this.refreshPageFromStore()
      }
    }
  },
  activated() {
    this.refreshPageFromStore()
  },
  deactivated() {
    this.savePageCache()
  },
  methods: {
    pageCacheKey() {
      return this.ownerDeviceSn != null ? `${this.ownerDeviceSn}::opw-query` : null
    },
    pageDataKey() {
      return this.ownerDeviceSn != null ? `${this.ownerDeviceSn}::${PAGE_CMD}` : PAGE_CMD
    },
    savePageCache() {
      const key = this.pageCacheKey()
      if (!key) return
      this.$store.commit('tsb/SET_DEVICE_PAGE_FORM', {
        key,
        data: {
          form: JSON.parse(JSON.stringify(this.form)),
          logDialogVisible: this.logDialogVisible,
          initialized: true
        }
      })
    },
    restorePageCache() {
      const key = this.pageCacheKey()
      if (!key) return false
      const cached = this.$store.state.tsb.devicePageFormCache[key]
      if (!cached || !cached.initialized) return false
      this.form = JSON.parse(JSON.stringify(cached.form))
      if (Object.prototype.hasOwnProperty.call(cached, 'logDialogVisible')) {
        this.logDialogVisible = !!cached.logDialogVisible
      }
      return true
    },
    applyQueryData(data) {
      if (!data) return
      const defaults = createDefaultForm()
      applyPartialFields(this.form, data, DISPLAY_FIELDS, defaults)
      if (Object.prototype.hasOwnProperty.call(data, 'tankList') && Array.isArray(data.tankList)) {
        this.form.tankList = data.tankList
      }
      if (data.buttonType === OPW_BUTTON.VIEW_RAW_LOG) {
        this.logDialogVisible = true
      }
      this.savePageCache()
    },
    tryApplyWsPageData(clearInitFlag) {
      const data = this.$store.state.tsb.pageData[this.pageDataKey()]
      if (!data) return false
      this.applyQueryData(data)
      if (clearInitFlag && this.$store.state.tsb.initFromWs[this.pageDataKey()]) {
        this.$store.commit('tsb/CLEAR_WS_INIT', { cmdType: PAGE_CMD, deviceSn: this.ownerDeviceSn })
      }
      return true
    },
    refreshPageFromStore() {
      if (this.tryApplyWsPageData(true)) return
      if (this.restorePageCache()) return
      this.initPageData()
    },
    initPageData() {
      this.form = createDefaultForm()
      if (this.canOperateDevice) {
        this.syncDefaultParamsToDevice()
      }
      this.savePageCache()
    },
    syncDefaultParamsToDevice() {
      tsbWebSocket.sendPageSync(PAGE_CMD, {
        totalTankCount: null,
        queryResult: '',
        rawLog: '',
        tankList: []
      })
    },
    sendButtonAction(buttonType) {
      if (!this.canOperateDevice) return
      tsbWebSocket.sendPageSync(PAGE_CMD, { buttonType })
    },
    queryA() {
      this.sendButtonAction(OPW_BUTTON.QUERY_A)
    },
    queryB() {
      this.sendButtonAction(OPW_BUTTON.QUERY_B)
    },
    query485() {
      this.sendButtonAction(OPW_BUTTON.QUERY_485)
    },
    viewRawLog() {
      this.logDialogVisible = true
      this.savePageCache()
      this.sendButtonAction(OPW_BUTTON.VIEW_RAW_LOG)
    },
    resultTag(text) {
      if (!text) return 'info'
      return text.indexOf('成功') >= 0 ? 'success' : 'danger'
    }
  }
}
</script>

<style scoped>
.mb16 { margin-bottom: 16px; }
.label { color: #909399; margin-right: 4px; }
.value { font-weight: 600; margin-right: 4px; }
.unit { color: #606266; }
</style>
