<template>
  <div class="app-container tax-page">
    <el-alert
      v-if="showNewTabHint"
      title="当前页签未选择设备，请前往首页选择已登录设备后再操作"
      type="warning"
      show-icon
      :closable="false"
      class="mb16"
    />
    <el-alert
      v-else-if="!currentDeviceSn"
      title="请先在首页选择已登录设备并建立连接"
      type="warning"
      show-icon
      :closable="false"
      class="mb16"
    />
    <template v-if="canOperateDevice">
    <el-row type="flex" justify="space-between" align="middle" class="mb16">
      <el-col :span="16">
        <el-tag :type="wsConnected ? 'success' : 'info'" size="small">
          {{ wsConnected ? 'WebSocket 已连接' : 'WebSocket 未连接' }}
        </el-tag>
        <span class="bind-text">设备 SN：{{ currentDeviceSn }}</span>
      </el-col>
      <el-col :span="8" style="text-align: right">
        <el-button size="mini" @click="loadBind">刷新绑定</el-button>
        <el-button size="mini" type="primary" @click="reconnectWs">重连</el-button>
      </el-col>
    </el-row>

    <!-- 顶部参数行 -->
    <el-card shadow="never" class="mb16">
      <el-row :gutter="12" class="param-row">
        <el-col :xs="12" :sm="6" :md="4">
          <div class="field-label">接口号</div>
          <el-select v-model="form.interfaceNo" size="small" @change="onInterfaceNoChange">
            <el-option label="A" value="A" />
            <el-option label="B" value="B" />
          </el-select>
        </el-col>
        <el-col :xs="12" :sm="6" :md="4">
          <div class="field-label">枪号</div>
          <el-input-number v-model="form.gunNo" :min="1" :max="9" size="small" controls-position="right" @change="onGunNoChange" />
        </el-col>
        <el-col :xs="12" :sm="6" :md="4">
          <div class="field-label">新国标</div>
          <el-switch v-model="newStandardOn" active-text="启用" inactive-text="禁用" @change="onNewStandardChange" />
        </el-col>
        <el-col :xs="12" :sm="6" :md="4">
          <div class="field-label">新国标报税口</div>
          <el-input-number v-model="form.newNationalStandardTaxNo" :min="1" :max="9" size="small" controls-position="right" @change="onNewNationalStandardTaxNoChange" />
        </el-col>
      </el-row>
    </el-card>

    <el-row :gutter="16">
      <!-- 左侧：税控序列号 -->
      <el-col :xs="24" :md="10" :lg="8">
        <el-card shadow="hover" class="panel-card">
          <div slot="header" class="panel-title">税控序列号查询</div>
            <el-button type="primary" size="small" class="mb16" @click="queryTaxSerial">查询税控序列号</el-button>
          <div class="result-item"><span class="label">税控序列号：</span>{{ form.taxNo || '-' }}</div>
          <div class="result-item"><span class="label">厂家：</span>{{ form.manufacturer || '-' }}</div>
          <div class="result-item"><span class="label">枪个数：</span>{{ form.gunNumber != null ? form.gunNumber : '-' }}</div>
          <div class="result-item"><span class="label">执行结果：</span>
            <el-tag size="mini" :type="resultTag(form.queryTaxResult)">{{ form.queryTaxResult || '-' }}</el-tag>
          </div>
        </el-card>
      </el-col>

      <!-- 右侧：累计数据 -->
      <el-col :xs="24" :md="14" :lg="16">
        <el-card shadow="hover" class="panel-card">
          <div slot="header" class="panel-title">累计数据查询</div>
          <el-row :gutter="8" class="mb16 date-row">
            <el-col :span="8">
              <el-input-number v-model="queryYear" :min="2000" :max="2099" size="small" controls-position="right" @change="onQueryDateChange" />
              <span class="unit">年</span>
            </el-col>
            <el-col :span="8">
              <el-input-number v-model="queryMonth" :min="1" :max="12" size="small" controls-position="right" @change="onQueryDateChange" />
              <span class="unit">月</span>
            </el-col>
            <el-col :span="8">
              <el-input-number v-model="queryDay" :min="1" :max="31" size="small" controls-position="right" @change="onQueryDateChange" />
              <span class="unit">日</span>
            </el-col>
          </el-row>
          <el-button-group class="mb16 btn-group-wrap">
            <el-button type="primary" size="small" @click="queryAccumulated(BUTTON_TYPE.QUERY_CURRENT)">查当次及总累</el-button>
            <el-button type="primary" size="small" @click="queryAccumulated(BUTTON_TYPE.QUERY_DAY)">查日累</el-button>
            <el-button type="primary" size="small" @click="queryAccumulated(BUTTON_TYPE.QUERY_MONTH)">查月累</el-button>
          </el-button-group>
          <el-row :gutter="12">
            <el-col :xs="12" :sm="8"><div class="result-item"><span class="label">金额：</span>{{ formatNum(form.amount) }}</div></el-col>
            <el-col :xs="12" :sm="8"><div class="result-item"><span class="label">油量：</span>{{ formatNum(form.volume) }}</div></el-col>
            <el-col :xs="12" :sm="8"><div class="result-item"><span class="label">单价：</span>{{ formatNum(form.unitPrice) }}</div></el-col>
            <el-col :xs="12" :sm="8"><div class="result-item"><span class="label">是否密文：</span>{{ encryptionText }}</div></el-col>
            <el-col :xs="12" :sm="8"><div class="result-item"><span class="label">总金额：</span>{{ formatNum(form.totalAmount) }}</div></el-col>
            <el-col :xs="12" :sm="8"><div class="result-item"><span class="label">总油量：</span>{{ formatNum(form.totalVolume) }}</div></el-col>
            <el-col :span="24"><div class="result-item"><span class="label">执行结果：</span>
              <el-tag size="mini" :type="resultTag(form.queryAccumulatedResult)">{{ form.queryAccumulatedResult || '-' }}</el-tag>
            </div></el-col>
          </el-row>
        </el-card>
      </el-col>
    </el-row>
    </template>
  </div>
</template>

<script>
import { getTsbWsBind } from '@/api/tsb/ws'
import tsbWebSocket from '@/utils/tsbWebSocket'
const PAGE_CMD = 'common:tax'

/** 按钮操作类型 */
const BUTTON_TYPE = {
  QUERY: 'common:tax:query',
  QUERY_CURRENT: 'common:tax:queryCurrent',
  QUERY_DAY: 'common:tax:queryDay',
  QUERY_MONTH: 'common:tax:queryMonth'
}

/** 报税口页面展示字段（与接口文档 data 映射一致） */
const TAX_DISPLAY_FIELDS = [
  'interfaceNo',
  'gunNo',
  'newNationalStandard',
  'newNationalStandardTaxNo',
  'queryDate',
  'taxNo',
  'manufacturer',
  'gunNumber',
  'queryTaxResult',
  'amount',
  'volume',
  'unitPrice',
  'encryption',
  'totalAmount',
  'totalVolume',
  'queryAccumulatedResult'
]

function createDefaultForm() {
  const now = new Date()
  const m = String(now.getMonth() + 1).padStart(2, '0')
  const d = String(now.getDate()).padStart(2, '0')
  return {
    interfaceNo: 'A',
    gunNo: 1,
    newNationalStandard: 0,
    newNationalStandardTaxNo: 1,
    queryDate: `${now.getFullYear()}-${m}-${d}`,
    taxNo: '',
    manufacturer: '',
    gunNumber: null,
    queryTaxResult: '',
    amount: null,
    volume: null,
    unitPrice: null,
    encryption: null,
    totalAmount: null,
    totalVolume: null,
    queryAccumulatedResult: ''
  }
}

function createDefaultDateParts() {
  const now = new Date()
  return {
    queryYear: now.getFullYear(),
    queryMonth: now.getMonth() + 1,
    queryDay: now.getDate()
  }
}

export default {
  name: 'TsbTaxPage',
  props: {
    /** 工作区传入：固定绑定到该设备 SN，切换页签后不随 store 变化 */
    boundDeviceSn: {
      type: [Number, String],
      default: null
    }
  },
  data() {
    return {
      BUTTON_TYPE,
      bindInfo: {},
      wsConnected: false,
      newStandardOn: false,
      ...createDefaultDateParts(),
      form: createDefaultForm(),
      wsTimer: null
    }
  },
  computed: {
    ownerDeviceSn() {
      if (this.boundDeviceSn != null && this.boundDeviceSn !== '') {
        return this.boundDeviceSn
      }
      return this.$store.getters.tsbCurrentDeviceSn || tsbWebSocket.getCurrentDeviceSn()
    },
    currentDeviceSn() {
      return this.ownerDeviceSn
    },
    showNewTabHint() {
      return this.$store.getters.tsbSessionReady && this.$store.getters.tsbIsNewTabWithoutDevice && !this.currentDeviceSn
    },
    canOperateDevice() {
      const activeSn = this.$store.getters.tsbCurrentDeviceSn
      return !!this.ownerDeviceSn
        && String(activeSn) === String(this.ownerDeviceSn)
        && !this.showNewTabHint
    },
    encryptionText() {
      if (this.form.encryption === 1) return '是'
      if (this.form.encryption === 0) return '否'
      return '-'
    }
  },
  watch: {
    '$store.state.tsb.pageDataVersion'() {
      this.tryApplyWsPageData(false)
    },
    '$store.state.tsb.deviceSwitchVersion'() {
      if (String(this.$store.getters.tsbCurrentDeviceSn) === String(this.ownerDeviceSn)) {
        this.refreshPageFromStore()
      }
    }
  },
  created() {
    this.wsTimer = setInterval(() => {
      this.wsConnected = tsbWebSocket.isConnected()
    }, 1000)
    this.refreshPageFromStore()
  },
  activated() {
    this.refreshPageFromStore()
  },
  deactivated() {
    this.savePageCache()
  },
  beforeDestroy() {
    this.savePageCache()
    if (this.wsTimer) clearInterval(this.wsTimer)
  },
  methods: {
    pageCacheKey(deviceSn) {
      const sn = deviceSn != null ? deviceSn : this.ownerDeviceSn
      return sn != null ? `${String(sn)}::tax` : null
    },
    pageDataKey(deviceSn) {
      const sn = deviceSn != null ? deviceSn : this.ownerDeviceSn
      return sn != null ? `${String(sn)}::${PAGE_CMD}` : PAGE_CMD
    },
    refreshPageFromStore() {
      if (this.tryApplyWsPageData(true)) {
        return
      }
      if (this.restorePageCache()) {
        return
      }
      this.initPageData()
    },
    savePageCache(deviceSn) {
      const key = this.pageCacheKey(deviceSn)
      if (!key) {
        return
      }
      this.$store.commit('tsb/SET_DEVICE_PAGE_FORM', {
        key,
        data: {
          form: { ...this.form },
          queryYear: this.queryYear,
          queryMonth: this.queryMonth,
          queryDay: this.queryDay,
          newStandardOn: this.newStandardOn,
          initialized: true
        }
      })
    },
    restorePageCache(deviceSn) {
      const key = this.pageCacheKey(deviceSn)
      if (!key) {
        return false
      }
      const cached = this.$store.state.tsb.devicePageFormCache[key]
      if (!cached || !cached.initialized) {
        return false
      }
      this.form = { ...cached.form }
      this.queryYear = cached.queryYear
      this.queryMonth = cached.queryMonth
      this.queryDay = cached.queryDay
      this.newStandardOn = cached.newStandardOn
      return true
    },
    loadBind() {
      const deviceSn = this.currentDeviceSn
      if (!deviceSn) {
        this.bindInfo = {}
        return
      }
      const currentDevice = this.$store.getters.tsbCurrentDevice
      this.bindInfo = currentDevice || { deviceSn }
      getTsbWsBind(deviceSn, true).then(res => {
        this.bindInfo = { ...(currentDevice || {}), ...(res.data || {}), deviceSn }
      }).catch((err) => {
        this.bindInfo = currentDevice || { deviceSn }
        const msg = typeof err === 'string' ? err : (err && (err.message || err.msg))
        if (msg) {
          this.$message.error(msg)
        }
      })
    },
    reconnectWs() {
      const deviceSn = this.currentDeviceSn
      if (!deviceSn) {
        this.$message.warning('请先在首页选择设备')
        return
      }
      tsbWebSocket.reconnect().catch(msg => {
        this.$message.error(msg || '重连失败')
      })
    },
    /** WebSocket 推送进入：用 data 初始化；手动菜单进入：恢复默认值并下发 */
    initPageData() {
      if (this.tryApplyWsPageData(true)) {
        return
      }
      this.resetFormDefaults()
      if (this.canOperateDevice) {
        this.syncDefaultParamsToDevice()
      }
    },
    /** 手动进入：重置为默认值并同步到设备 */
    applyManualDefaults() {
      this.resetFormDefaults()
      if (this.canOperateDevice) {
        this.syncDefaultParamsToDevice()
      }
    },
    /** 从 store 应用 WebSocket 推送数据（按设备 SN 隔离，与当前激活页签无关） */
    tryApplyWsPageData(clearInitFlag) {
      const dataKey = this.pageDataKey()
      const data = this.$store.state.tsb.pageData[dataKey]
      if (!data) {
        return false
      }
      this.applyTaxData(data)
      if (clearInitFlag && this.$store.state.tsb.initFromWs[dataKey]) {
        this.$store.commit('tsb/CLEAR_WS_INIT', { cmdType: PAGE_CMD, deviceSn: this.ownerDeviceSn })
      }
      return true
    },
    resetFormDefaults() {
      const dateParts = createDefaultDateParts()
      this.queryYear = dateParts.queryYear
      this.queryMonth = dateParts.queryMonth
      this.queryDay = dateParts.queryDay
      this.form = createDefaultForm()
      this.newStandardOn = false
    },
    applyTaxData(data) {
      if (!data) {
        return
      }
      const defaults = createDefaultForm()
      TAX_DISPLAY_FIELDS.forEach((key) => {
        if (Object.prototype.hasOwnProperty.call(data, key)) {
          this.form[key] = data[key] ?? defaults[key]
        }
      })
      if (Object.prototype.hasOwnProperty.call(data, 'newNationalStandard')) {
        this.newStandardOn = data.newNationalStandard === 1
      }
      if (Object.prototype.hasOwnProperty.call(data, 'queryDate')) {
        this.parseQueryDate(data.queryDate)
      }
      this.savePageCache()
    },
    parseQueryDate(dateStr) {
      if (dateStr == null || dateStr === '') {
        return
      }
      const parts = dateStr.split('-')
      if (parts.length === 3) {
        this.queryYear = Number(parts[0])
        this.queryMonth = Number(parts[1])
        this.queryDay = Number(parts[2])
      }
    },
    updateQueryDate() {
      const m = String(this.queryMonth).padStart(2, '0')
      const d = String(this.queryDay).padStart(2, '0')
      this.form.queryDate = `${this.queryYear}-${m}-${d}`
    },
    /** 手动进入时下发默认参数区字段 */
    syncDefaultParamsToDevice() {
      this.updateQueryDate()
      const payload = {
        interfaceNo: this.form.interfaceNo,
        gunNo: this.form.gunNo,
        newNationalStandard: this.form.newNationalStandard,
        newNationalStandardTaxNo: this.form.newNationalStandardTaxNo,
        queryDate: this.form.queryDate
      }
      const send = () => tsbWebSocket.sendPageSync(PAGE_CMD, payload)
      if (send()) {
        return
      }
      let retries = 0
      const timer = setInterval(() => {
        if (send() || ++retries >= 10) {
          clearInterval(timer)
        }
      }, 500)
    },
    /** 字段变更：仅下发变更字段 */
    syncField(payload) {
      if (!this.canOperateDevice) {
        return
      }
      tsbWebSocket.sendPageSync(PAGE_CMD, payload)
    },
    onInterfaceNoChange(val) {
      this.syncField({ interfaceNo: val })
      this.savePageCache()
    },
    onGunNoChange(val) {
      this.syncField({ gunNo: val })
      this.savePageCache()
    },
    onNewStandardChange(val) {
      this.form.newNationalStandard = val ? 1 : 0
      this.syncField({ newNationalStandard: this.form.newNationalStandard })
      this.savePageCache()
    },
    onNewNationalStandardTaxNoChange(val) {
      this.syncField({ newNationalStandardTaxNo: val })
      this.savePageCache()
    },
    onQueryDateChange() {
      this.updateQueryDate()
      this.syncField({ queryDate: this.form.queryDate })
      this.savePageCache()
    },
    /** 按钮点击：下发参数区字段 + buttonType */
    buildButtonPayload(buttonType) {
      this.updateQueryDate()
      return {
        interfaceNo: this.form.interfaceNo,
        gunNo: this.form.gunNo,
        newNationalStandard: this.form.newNationalStandard,
        newNationalStandardTaxNo: this.form.newNationalStandardTaxNo,
        queryDate: this.form.queryDate,
        buttonType
      }
    },
    sendButtonAction(buttonType) {
      if (!this.canOperateDevice) {
        return
      }
      tsbWebSocket.sendPageSync(PAGE_CMD, this.buildButtonPayload(buttonType))
    },
    queryTaxSerial() {
      this.sendButtonAction(BUTTON_TYPE.QUERY)
    },
    queryAccumulated(buttonType) {
      this.sendButtonAction(buttonType)
    },
    formatNum(v) {
      return v == null || v === '' ? '-' : v
    },
    resultTag(text) {
      if (!text) return 'info'
      return text.indexOf('成功') >= 0 ? 'success' : 'danger'
    }
  }
}
</script>

<style scoped>
.tax-page .mb16 { margin-bottom: 16px; }
.field-label { font-size: 13px; color: #606266; margin-bottom: 6px; }
.bind-text { margin-left: 12px; color: #909399; font-size: 13px; }
.panel-card { min-height: 280px; }
.panel-title { font-weight: 600; }
.result-item { margin-bottom: 10px; font-size: 14px; line-height: 1.6; }
.result-item .label { color: #909399; }
.date-row .unit { margin-left: 4px; font-size: 13px; color: #606266; }
.btn-group-wrap { display: flex; flex-wrap: wrap; gap: 8px; }
.param-row >>> .el-select, .param-row >>> .el-input-number { width: 100%; }
</style>
