<template>
  <view class="page">
    <view class="header-hero" :style="{ paddingTop: statusBarHeight + 'px' }">
      <view class="top-bar">
        <view class="top-left" @click="goBack">
          <AppIcon name="chevronLeft" size="sm" color="white" />
        </view>
        <view class="top-center">
          <text class="page-title">Printer</text>
          <LocationPicker />
        </view>
        <view class="top-right" @click="isMenuOpen = true">
          <AppIcon name="menu" size="sm" color="white" />
        </view>
      </view>
    </view>

    <view class="content">
      <!-- Printer type: Bluetooth | Built-in -->
      <view v-if="availablePrinterTypes.length > 1" class="type-tabs">
        <view
          v-if="isBluetoothModeAvailable"
          class="tab"
          :class="{ active: printerType === 'bluetooth' }"
          @click="switchType('bluetooth')"
        >
          <AppIcon name="bluetooth" size="sm" :color="printerType === 'bluetooth' ? 'white' : 'gray'" />
          <text class="tab-text">Bluetooth</text>
        </view>
        <view
          v-if="isBuiltinModeAvailable"
          class="tab"
          :class="{ active: printerType === 'builtin' }"
          @click="switchType('builtin')"
        >
          <AppIcon name="printer" size="sm" :color="printerType === 'builtin' ? 'white' : 'gray'" />
          <text class="tab-text">Built-in</text>
        </view>
      </view>

      <!-- Error -->
      <view v-if="errorMsg" class="error-banner">
        <AppIcon name="alert" size="sm" color="red" />
        <text class="error-text">{{ errorMsg }}</text>
      </view>

      <view class="debug-card">
        <text class="debug-title">Debug Status</text>
        <text class="debug-item">Current Mode: {{ debugInfo.currentMode }}</text>
        <text class="debug-item">Available Mode: {{ availablePrinterTypesLabel }}</text>
        <text class="debug-item">Device Model: {{ deviceIdentity.model || '-' }}</text>
        <text class="debug-item">Device Brand: {{ deviceIdentity.brand || '-' }}</text>
        <text class="debug-item">Device Product: {{ deviceIdentity.product || '-' }}</text>
        <text class="debug-item">Classic Module: {{ debugInfo.classicModuleReady ? 'Ready' : 'Not Ready' }}</text>
        <text class="debug-item">Native Plugin: {{ nativeDebug.available ? 'Ready' : 'Missing' }}</text>
        <text class="debug-item">Native Backend: {{ nativeDebug.backend || '-' }}</text>
        <text class="debug-item">Native Stage: {{ nativeDebug.stage || '-' }}</text>
        <text class="debug-item">Native Command Bytes: {{ nativeDebug.commandBytes || 0 }}</text>
        <text class="debug-item">Paired Count: {{ debugInfo.pairedCount }}</text>
        <text class="debug-item">Virtual BT Printer: {{ debugInfo.foundVirtualPrinter ? 'Found' : 'Not Found' }}</text>
        <text class="debug-item">Classic Scan: {{ debugInfo.lastClassicEvent }}</text>
        <text class="debug-item">BLE Scan: {{ debugInfo.lastBleEvent }}</text>
        <text v-if="debugInfo.lastBleError" class="debug-item debug-error">{{ debugInfo.lastBleError }}</text>
        <text v-if="nativeDebug.lastError" class="debug-item debug-error">{{ nativeDebug.lastError }}</text>
        <text v-if="debugInfo.locationServiceRequired" class="debug-item debug-warn">
          Android system Location service is OFF. Turn it on before BLE scan.
        </text>
      </view>

      <!-- Connected -->
      <view v-if="connectedDevice" class="connected-card">
        <view class="connected-header">
          <view class="connected-icon">
            <AppIcon :name="printerType === 'builtin' ? 'printer' : 'bluetooth'" size="md" color="white" />
          </view>
          <view class="connected-info">
            <text class="connected-name">{{ connectedDevice.name }}</text>
            <text class="connected-status">Connected</text>
          </view>
        </view>
        <view class="btn-test-print" :class="{ disabled: testPrinting }" @click="handleTestPrint">
          <AppIcon name="printer" size="sm" color="white" />
          <text class="btn-test-print-text">Test Print</text>
        </view>
        <view class="btn-disconnect" @click="handleDisconnect">
          <text class="btn-disconnect-text">Disconnect</text>
        </view>
      </view>

      <!-- Bluetooth: scan & list -->
      <template v-if="printerType === 'bluetooth'">
        <view class="section-header">
          <text class="section-title">Available Printers</text>
          <view class="btn-scan" :class="{ scanning: isScanning }" @click="handleScan">
            <AppIcon name="refresh" size="sm" :color="isScanning ? 'white' : 'primary'" />
            <text class="btn-scan-text">{{ isScanning ? 'Scanning...' : 'Scan' }}</text>
          </view>
        </view>

        <view v-if="isScanning && devices.length === 0" class="scanning-wrap">
          <view class="scan-anim">
            <AppIcon name="bluetooth" size="lg" color="blue" />
          </view>
          <text class="scan-text">Searching for nearby printers...</text>
        </view>

        <view v-else-if="!isScanning && devices.length === 0 && !connectedDevice" class="empty-wrap">
          <AppIcon name="bluetooth" size="lg" color="gray" />
          <text class="empty-title">No Devices Found</text>
          <text class="empty-desc">Turn on your Bluetooth printer and tap Scan.</text>
        </view>

        <view v-else class="device-list">
          <view
            v-for="dev in devices"
            :key="dev.deviceId"
            class="device-card"
            :class="{ connecting: connectingId === dev.deviceId }"
            @click="handleConnect(dev)"
          >
            <view class="device-icon printer">
              <AppIcon name="printer" size="md" color="blue" />
            </view>
            <view class="device-info">
              <text class="device-name">{{ dev.name || 'Unknown' }}</text>
              <text class="device-id">{{ dev.deviceId }}</text>
              <view class="device-meta">
                <text class="device-tag">Printer</text>
                <text v-if="dev.RSSI" class="device-rssi">Signal: {{ dev.RSSI }}dBm</text>
              </view>
            </view>
            <view v-if="connectingId === dev.deviceId" class="device-action">
              <text class="connecting-text">Connecting...</text>
            </view>
            <view v-else class="device-action">
              <AppIcon name="chevronRight" size="sm" color="gray" />
            </view>
          </view>
        </view>
      </template>

      <!-- Built-in: single option -->
      <template v-else>
        <view class="section-header">
          <text class="section-title">Built-in Printer</text>
        </view>
        <view class="builtin-card">
          <text class="builtin-desc">For TCP-built-in printers (localhost). If your all-in-one uses "Virtual BT Printer" Bluetooth, use Bluetooth mode above and connect it.</text>
          <view
            v-if="!connectedDevice || getPrinterType() !== 'builtin'"
            class="btn-builtin"
            @click="handleUseBuiltin"
          >
            <AppIcon name="printer" size="sm" color="white" />
            <text class="btn-builtin-text">Use Built-in Printer</text>
          </view>
        </view>
      </template>

      <view class="tips-card">
        <text class="tips-title">Troubleshooting</text>
        <text class="tips-item">1. Ensure the printer is powered on and in pairing mode</text>
        <text class="tips-item">2. On Android: enable Location (required for Bluetooth scan)</text>
        <text class="tips-item">3. Place the printer within 10 m and tap Scan again</text>
        <text class="tips-item">4. Devices with no name show as "Unknown Device"—you can still connect</text>
        <text class="tips-item">5. D320FAX (d320fax_295c): use Bluetooth mode, tap Scan—shows paired + nearby devices, no filtering</text>
        <text class="tips-item tips-item-last">6. Restart the printer or app if not visible</text>
      </view>
    </view>

    <SideMenu v-model="isMenuOpen" />
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import AppIcon from '../../components/AppIcon.vue'
import SideMenu from '../../components/SideMenu.vue'
import LocationPicker from '../../components/LocationPicker.vue'
import { getStatusBarHeight } from '../../utils/statusBar'
import { getDeviceIdentity } from '../../utils/deviceInfo'
import classicBluetooth from '../../utils/print/bluetoothTool.js'
import {
  getPrinterType,
  getAvailablePrinterTypes,
  clearPrinter,
  type PrinterType,
} from '../../utils/print/printerConnection'
import { ensureBluetoothPermissions } from '../../utils/print/bluetoothPermissions'
import {
  getNativeFastPrinterDebugInfo,
  getNativeFastPrinterState,
} from '../../utils/print/nativeFastPrinter'
import {
  connectBluetoothPrinter,
  describeDiscoveredPrinter,
  disconnectCurrentPrinter,
  getCurrentPrinterSummary,
  testPrintCurrentPrinter,
  useBuiltinPrinter,
} from '../../utils/print/manager/printerManager'

const statusBarHeight = getStatusBarHeight()
const isMenuOpen = ref(false)
const isScanning = ref(false)
const connectingId = ref('')
const errorMsg = ref('')
const btAdapterReady = ref(false)
const availablePrinterTypes = getAvailablePrinterTypes()
const availablePrinterTypesLabel = availablePrinterTypes.map(item => item === 'builtin' ? 'Built-in' : 'Bluetooth').join(' / ')
const deviceIdentity = getDeviceIdentity()
const storedPrinterType = getPrinterType()
const preferredPrinterType = (storedPrinterType && availablePrinterTypes.includes(storedPrinterType as PrinterType))
  ? storedPrinterType as PrinterType
  : availablePrinterTypes[0]
const printerType = ref<PrinterType | ''>(preferredPrinterType || 'bluetooth')
const currentPrinter = ref(getCurrentPrinterSummary())
const debugInfo = ref({
  currentMode: 'none',
  classicModuleReady: false,
  pairedCount: 0,
  foundVirtualPrinter: false,
  lastClassicEvent: 'idle',
  lastBleEvent: 'idle',
  lastBleError: '',
  locationServiceRequired: false,
})
const nativeDebug = ref(getNativeFastPrinterState() || {})

interface BtDevice {
  deviceId: string
  name: string
  RSSI?: number
  type?: 'ble' | 'classic' | 'dual' | 'unknown'
}

const devices = ref<BtDevice[]>([])
const discoveredIds = new Set<string>()
const isBluetoothModeAvailable = availablePrinterTypes.includes('bluetooth')
const isBuiltinModeAvailable = availablePrinterTypes.includes('builtin')

function refreshCurrentPrinter () {
  currentPrinter.value = getCurrentPrinterSummary()
  debugInfo.value.currentMode = currentPrinter.value.type || 'none'
}

async function refreshNativeDebug () {
  nativeDebug.value = getNativeFastPrinterState() || {}
  try {
    const info = await getNativeFastPrinterDebugInfo()
    nativeDebug.value = {
      ...nativeDebug.value,
      ...info,
    }
  } catch (_) {
    nativeDebug.value = getNativeFastPrinterState() || {}
  }
}

function hasPreferredClassicDeviceInList () {
  return devices.value.some((item: any) => {
    const name = String(item?.name || '').toLowerCase()
    const type = String(item?.type || '').toLowerCase()
    return name.includes('virtual bt printer') || type === 'classic' || type === 'dual'
  })
}

const connectedDevice = computed(() => {
  const summary = currentPrinter.value
  if (printerType.value === 'builtin' && summary.type === 'builtin') {
    return { name: summary.displayName, deviceId: summary.deviceId }
  }
  if (printerType.value === 'bluetooth' && summary.type === 'bluetooth') {
    return { name: summary.displayName, deviceId: summary.deviceId }
  }
  return null
})

function switchType (type: 'bluetooth' | 'builtin') {
  if (!availablePrinterTypes.includes(type)) return
  printerType.value = type
  if (type === 'bluetooth' && getPrinterType() === 'builtin') {
    clearPrinter()
    refreshCurrentPrinter()
  }
}

const goBack = () => uni.navigateBack()

const initBluetooth = (): Promise<void> => {
  return new Promise((resolve, reject) => {
    uni.openBluetoothAdapter({
      success: () => {
        btAdapterReady.value = true
        errorMsg.value = ''
        resolve()
      },
      fail: (err: any) => {
        btAdapterReady.value = false
        if (err.errCode === 10001 || (err.errMsg && err.errMsg.includes('not available'))) {
          errorMsg.value = 'Bluetooth is off. Turn it on in system settings.'
        } else {
          errorMsg.value = 'Bluetooth init failed: ' + (err.errMsg || 'Unknown error')
        }
        reject(err)
      },
    })
  })
}

const startBleScan = () => {
  uni.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: false,
    success: () => {
      isScanning.value = true
      errorMsg.value = ''
      debugInfo.value.lastBleEvent = 'scan running'
    },
    fail: (err: any) => {
      console.error('BLE startBluetoothDevicesDiscovery fail:', err)
      debugInfo.value.lastBleEvent = 'scan failed'
      debugInfo.value.lastBleError = err?.errMsg || 'BLE scan failed'
      if (err?.errCode === 10016 || err?.code === 10016) {
        debugInfo.value.locationServiceRequired = true
        errorMsg.value = 'Bluetooth scan failed: Android system Location service is turned off.'
      }
    },
  })
}

const stopDiscovery = () => {
  uni.stopBluetoothDevicesDiscovery({
    complete: () => {
      isScanning.value = false
    },
  })
  // #ifdef APP-PLUS
  const classic = classicBluetooth
  if (classic && classic.cancelClassicDiscovery) classic.cancelClassicDiscovery()
  // #endif
}

const onDeviceFound = (res: any) => {
  const foundDevices: any[] = res.devices || []
  for (const d of foundDevices) {
    if (discoveredIds.has(d.deviceId)) continue
    const name = (d.localName || d.name || '').trim()
    const displayName = name || 'Unknown Device'
    discoveredIds.add(d.deviceId)
    devices.value.push(describeDiscoveredPrinter({
      deviceId: d.deviceId,
      name: displayName,
      RSSI: d.RSSI,
      type: 'ble',
    }))
  }
  devices.value.sort((a, b) => (b.RSSI || -100) - (a.RSSI || -100))
}

/** 合并已缓存的 BLE 设备（uni.getBluetoothDevices 返回之前扫描到的设备，不过滤） */
function mergeCachedBleDevices () {
  uni.getBluetoothDevices({
    success: (res: any) => {
      const list = res.devices || []
      for (const d of list) {
        if (discoveredIds.has(d.deviceId)) continue
        const name = (d.localName || d.name || '').trim()
        discoveredIds.add(d.deviceId)
        devices.value.push(describeDiscoveredPrinter({
          deviceId: d.deviceId,
          name: name || 'Unknown Device',
          RSSI: d.RSSI,
          type: 'ble',
        }))
      }
      if (list.length > 0) devices.value.sort((a, b) => (b.RSSI || -100) - (a.RSSI || -100))
    },
  })
}

function addPairedDevices () {
  // #ifdef APP-PLUS
  const classic = classicBluetooth
  if (!classic || !classic.getPairedDevices) return
  try {
    const paired = classic.getPairedDevices()
    debugInfo.value.pairedCount = (paired || []).length
    debugInfo.value.foundVirtualPrinter = (paired || []).some((item: any) => String(item?.name || '').toLowerCase().includes('virtual bt printer'))
    for (const p of paired) {
      if (discoveredIds.has(p.deviceId)) continue
      discoveredIds.add(p.deviceId)
      devices.value.push(describeDiscoveredPrinter({
        deviceId: p.deviceId,
        name: p.name || 'Unknown Device',
        type: p.type || 'classic',
      }))
    }
    if (paired.length > 0) {
      debugInfo.value.lastClassicEvent = 'paired devices loaded'
      devices.value.sort((a, b) => (b.RSSI || -100) - (a.RSSI || -100))
    } else {
      debugInfo.value.lastClassicEvent = 'no paired devices'
    }
  } catch (e) {
    console.error('addPairedDevices error:', e)
    debugInfo.value.lastClassicEvent = 'load paired devices failed'
  }
  // #endif
}

function startClassicScan () {
  // #ifdef APP-PLUS
  const classic = classicBluetooth
  if (classic && classic.startClassicDiscovery) {
    try {
      classic.startClassicDiscovery(
        (dev: { name: string; deviceId: string; type: string }) => {
          debugInfo.value.lastClassicEvent = 'device found'
          if (discoveredIds.has(dev.deviceId)) return
          discoveredIds.add(dev.deviceId)
          devices.value.push(describeDiscoveredPrinter({
            deviceId: dev.deviceId,
            name: dev.name || 'Unknown Device',
            type: (dev.type as BtDevice['type']) || 'classic',
          }))
          devices.value.sort((a, b) => (b.RSSI || -100) - (a.RSSI || -100))
        },
        () => {
          debugInfo.value.lastClassicEvent = 'scan finished'
        },
      )
      isScanning.value = true
      debugInfo.value.lastClassicEvent = 'scan running'
    } catch (e) {
      console.error('Classic discovery failed', e)
      debugInfo.value.lastClassicEvent = 'scan failed'
    }
  } else {
    debugInfo.value.lastClassicEvent = 'classic module unavailable'
  }
  // #endif
}

const handleScan = async () => {
  if (isScanning.value) {
    stopDiscovery()
    return
  }
  errorMsg.value = ''
  devices.value = []
  discoveredIds.clear()
  debugInfo.value.lastBleError = ''
  debugInfo.value.locationServiceRequired = false
  debugInfo.value.lastClassicEvent = 'starting'
  debugInfo.value.lastBleEvent = 'starting'

  try {
    const permissionResult = await ensureBluetoothPermissions({ scan: true, connect: true })
    if (!permissionResult.ok) {
      errorMsg.value = permissionResult.message || 'Bluetooth permission denied.'
      return
    }
    await initBluetooth()

    addPairedDevices()
    startClassicScan()

    if (hasPreferredClassicDeviceInList()) {
      isScanning.value = false
      debugInfo.value.lastBleEvent = 'skipped (paired classic device found)'
      uni.showToast({ title: 'Using paired classic Bluetooth devices', icon: 'none' })
      return
    }

    mergeCachedBleDevices()
    await new Promise<void>((resolve) => {
      uni.getLocation({
        type: 'wgs84',
        success: () => resolve(),
        fail: () => resolve(),
      })
    })
    startBleScan()
    uni.showToast({ title: 'Scanning...', icon: 'none' })
    setTimeout(() => {
      if (isScanning.value) stopDiscovery()
    }, 20000)
  } catch (_) {
    if (!isScanning.value && devices.value.length === 0) {
      errorMsg.value = 'Bluetooth scan failed. Check if Bluetooth is enabled.'
    }
  }
}

const handleConnect = async (dev: BtDevice) => {
  if (connectingId.value) return
  connectingId.value = dev.deviceId
  errorMsg.value = ''

  if (isScanning.value) stopDiscovery()

  const permissionResult = await ensureBluetoothPermissions({ connect: true })
  if (!permissionResult.ok) {
    connectingId.value = ''
    errorMsg.value = permissionResult.message || 'Bluetooth permission denied.'
    return
  }

  try {
    await connectBluetoothPrinter(dev)
    refreshCurrentPrinter()
    await refreshNativeDebug()
    connectingId.value = ''
    uni.showToast({ title: 'Connected!', icon: 'success' })
  } catch (e: any) {
    await refreshNativeDebug()
    errorMsg.value = (e && e.message) ? e.message : 'Connection failed'
    connectingId.value = ''
  }
}

const handleUseBuiltin = () => {
  useBuiltinPrinter()
  refreshCurrentPrinter()
  uni.showToast({ title: 'Using built-in printer', icon: 'success' })
}

const testPrinting = ref(false)
const handleTestPrint = async () => {
  if (testPrinting.value) return
  testPrinting.value = true
  try {
    uni.showLoading({ title: 'Sending test job...', mask: true })
    await testPrintCurrentPrinter()
    await refreshNativeDebug()
    uni.hideLoading()
    uni.showToast({ title: 'Test print sent!', icon: 'success' })
  } catch (e: any) {
    await refreshNativeDebug()
    uni.hideLoading()
    const msg = (e && e.message) ? e.message : 'Please check printer connection.'
    if (msg === 'BUILTIN_PLUGIN_NOT_FOUND') {
      uni.showModal({
        title: 'Use Bluetooth Mode',
        content: 'For GP-D320FAX, switch to Bluetooth mode and tap Scan to connect (e.g. d320fax_295c or Virtual BT Printer). Built-in mode needs custom app packaging.',
        showCancel: false,
        success: () => { switchType('bluetooth') },
      })
    } else {
      uni.showModal({
        title: 'Print Failed',
        content: msg,
        showCancel: false,
      })
    }
  } finally {
    testPrinting.value = false
  }
}

const handleDisconnect = async () => {
  await disconnectCurrentPrinter()
  refreshCurrentPrinter()
  await refreshNativeDebug()
  uni.showToast({ title: 'Disconnected', icon: 'none' })
}

onMounted(() => {
  debugInfo.value.classicModuleReady = !!classicBluetooth
  refreshNativeDebug()
  uni.onBluetoothDeviceFound(onDeviceFound)
  uni.onBluetoothAdapterStateChange((res: any) => {
    if (!res.available) {
      btAdapterReady.value = false
      isScanning.value = false
      errorMsg.value = 'Bluetooth has been turned off.'
    } else {
      btAdapterReady.value = true
      errorMsg.value = ''
    }
  })
  printerType.value = preferredPrinterType || 'bluetooth'
  refreshCurrentPrinter()
})

onUnmounted(() => {
  if (isScanning.value) stopDiscovery()
  try {
    if (typeof uni.offBluetoothDeviceFound === 'function') {
      uni.offBluetoothDeviceFound()
    }
  } catch (_) {}
  try {
    if (typeof uni.offBluetoothAdapterStateChange === 'function') {
      uni.offBluetoothAdapterStateChange()
    }
  } catch (_) {}
  uni.closeBluetoothAdapter({ complete: () => {} })
})
</script>

<style scoped>
.page {
  min-height: 100vh;
  background: #f9fafb;
}

.header-hero {
  background: linear-gradient(135deg, var(--theme-primary), var(--theme-primary-dark));
  padding: 16rpx 32rpx 24rpx;
}

.top-bar {
  height: 96rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.top-left,
.top-right {
  width: 64rpx;
  height: 64rpx;
  border-radius: 999rpx;
  background: rgba(255, 255, 255, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
}

.top-center {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.page-title {
  font-size: 34rpx;
  font-weight: 600;
  color: #fff;
}

.content {
  padding: 32rpx;
}

.type-tabs {
  display: flex;
  gap: 16rpx;
  margin-bottom: 24rpx;
}

.tab {
  flex: 1;
  height: 72rpx;
  border-radius: 14rpx;
  border: 2rpx solid #e5e7eb;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8rpx;
}

.tab.active {
  background: var(--theme-primary);
  border-color: var(--theme-primary);
}

.tab-text {
  font-size: 28rpx;
  font-weight: 500;
  color: #6b7280;
}

.tab.active .tab-text {
  color: #fff;
}

.error-banner {
  display: flex;
  align-items: center;
  gap: 16rpx;
  padding: 20rpx 24rpx;
  background: #fef2f2;
  border-radius: 12rpx;
  margin-bottom: 24rpx;
}

.error-text {
  font-size: 26rpx;
  color: #b91c1c;
  flex: 1;
}

.connected-card {
  background: #fff;
  padding: 32rpx;
  border-radius: 20rpx;
  margin-bottom: 32rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
  border: 2rpx solid #4ade80;
}

.connected-header {
  display: flex;
  align-items: center;
  gap: 24rpx;
  margin-bottom: 24rpx;
}

.connected-icon {
  width: 80rpx;
  height: 80rpx;
  border-radius: 20rpx;
  background: var(--theme-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.connected-name {
  font-size: 32rpx;
  font-weight: 600;
  color: #111827;
  display: block;
  margin-bottom: 4rpx;
}

.connected-status {
  font-size: 26rpx;
  color: #16a34a;
  font-weight: 500;
}

.btn-test-print {
  width: 100%;
  height: 80rpx;
  background: var(--theme-primary);
  border-radius: 14rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12rpx;
  margin-bottom: 24rpx;
}
.btn-test-print.disabled {
  opacity: 0.6;
  pointer-events: none;
}
.btn-test-print-text {
  font-size: 28rpx;
  font-weight: 600;
  color: #fff;
  line-height: 1;
}

.btn-disconnect {
  width: 100%;
  height: 80rpx;
  background: #fff;
  border: 2rpx solid var(--theme-primary);
  border-radius: 14rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-disconnect-text {
  font-size: 28rpx;
  font-weight: 600;
  color: var(--theme-primary);
  line-height: 1;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24rpx;
}

.section-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #111827;
}

.btn-scan {
  display: flex;
  align-items: center;
  gap: 8rpx;
  height: 64rpx;
  padding: 0 24rpx;
  background: #fff;
  border: 2rpx solid #e5e7eb;
  border-radius: 14rpx;
}

.btn-scan-text {
  font-size: 26rpx;
  color: var(--theme-primary);
  font-weight: 500;
  line-height: 1;
}

.btn-scan.scanning {
  background: var(--theme-primary);
  border-color: var(--theme-primary);
}

.btn-scan.scanning .btn-scan-text {
  color: #fff;
}

.scanning-wrap,
.empty-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 80rpx 24rpx;
}

.scan-anim {
  width: 120rpx;
  height: 120rpx;
  background: #eff6ff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 24rpx;
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.1); opacity: 0.7; }
}

.scan-text,
.empty-desc {
  font-size: 28rpx;
  color: #6b7280;
}

.empty-title {
  font-size: 30rpx;
  font-weight: 600;
  color: #374151;
  margin-bottom: 12rpx;
}

.device-list {
  margin-bottom: 32rpx;
}

.device-card {
  background: #fff;
  padding: 28rpx 32rpx;
  border-radius: 16rpx;
  margin-bottom: 16rpx;
  display: flex;
  align-items: center;
  gap: 24rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
}

.device-card:active {
  background: #f9fafb;
}

.device-card.connecting {
  opacity: 0.7;
}

.device-icon {
  width: 72rpx;
  height: 72rpx;
  border-radius: 16rpx;
  background: #f3f4f6;
  display: flex;
  align-items: center;
  justify-content: center;
}

.device-icon.printer {
  background: #eff6ff;
}

.device-info {
  flex: 1;
  min-width: 0;
}

.device-name {
  font-size: 30rpx;
  font-weight: 600;
  color: #111827;
  display: block;
  margin-bottom: 4rpx;
}

.device-id {
  font-size: 22rpx;
  color: #9ca3af;
  display: block;
  margin-bottom: 6rpx;
}

.device-meta {
  display: flex;
  align-items: center;
  gap: 12rpx;
}

.debug-card {
  background: #fff7ed;
  border: 1rpx solid #fed7aa;
  border-radius: 20rpx;
  padding: 24rpx;
  margin-bottom: 24rpx;
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.debug-title {
  font-size: 28rpx;
  font-weight: 700;
  color: #9a3412;
}

.debug-item {
  font-size: 22rpx;
  color: #7c2d12;
}

.debug-error {
  color: #b91c1c;
}

.debug-warn {
  color: #92400e;
  font-weight: 600;
}

.device-tag {
  display: inline-block;
  font-size: 20rpx;
  color: var(--theme-primary);
  background: var(--theme-primary-light);
  padding: 2rpx 12rpx;
  border-radius: 6rpx;
  font-weight: 500;
}

.device-rssi {
  font-size: 20rpx;
  color: #9ca3af;
}

.device-action {
  flex-shrink: 0;
}

.connecting-text {
  font-size: 24rpx;
  color: var(--theme-primary);
  font-weight: 500;
}

.builtin-card {
  background: #fff;
  padding: 32rpx;
  border-radius: 16rpx;
  margin-bottom: 24rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
}

.builtin-desc {
  font-size: 28rpx;
  color: #6b7280;
  display: block;
  margin-bottom: 24rpx;
  line-height: 1.5;
}

.btn-builtin {
  height: 80rpx;
  background: var(--theme-primary);
  border-radius: 14rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12rpx;
}

.btn-builtin-text {
  font-size: 28rpx;
  font-weight: 600;
  color: #fff;
}

.tips-card {
  background: #fffbeb;
  border: 1rpx solid #fde68a;
  border-radius: 16rpx;
  padding: 32rpx;
}

.tips-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #92400e;
  display: block;
  margin-bottom: 16rpx;
}

.tips-item {
  font-size: 26rpx;
  color: #a16207;
  display: block;
  margin-bottom: 8rpx;
  line-height: 1.5;
}

.tips-item-last {
  margin-bottom: 0;
}
</style>
