<template>
  <div class="printer-manager">
    <el-card class="printer-card">
      <template #header>
        <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
          <span>打印机管理</span>
          <el-button type="primary" @click="refreshPrinters" :loading="loading">
            <el-icon>
              <Refresh />
            </el-icon>
            刷新打印机列表
          </el-button>
        </div>
      </template>

      <el-form label-width="140px" label-position="left" class="printer-form">
        <el-form-item label="条码打印机">
          <div class="printer-row">
            <el-select v-model="barcodePrinter" placeholder="请选择条码打印机" style="width: 400px" clearable>
              <el-option v-for="p in printers" :key="p.name" :label="p.name" :value="p.name" />
            </el-select>
            <el-button type="primary" @click="confirmBarcodePrinter">确定</el-button>
          </div>
        </el-form-item>

        <el-form-item label="快递单打印机">
          <div class="printer-row">
            <el-select v-model="expressPrinter" placeholder="请选择快递单打印机" style="width: 400px" clearable>
              <el-option v-for="p in printers" :key="p.name" :label="p.name" :value="p.name" />
            </el-select>
            <el-button type="primary" @click="confirmExpressPrinter">确定</el-button>
          </div>
        </el-form-item>
        <el-form-item label="小票纸大小">
          <div class="printer-row">
            <el-select v-model="paperSize" placeholder="请选择小票纸大小" style="width: 400px" clearable>
              <el-option label="60（长）*30（高）" value="60*30" />
              <el-option label="60（长）*40（高）" value="60*40" />
              <el-option label="40（长）*60（高）" value="40*60" />
            </el-select>
            <el-button type="primary" @click="confirmPaperSize">确定</el-button>
          </div>
        </el-form-item>
        <!-- TODO -->
        <el-form-item label="切换模式快捷键">
          <div class="printer-row">
            <el-input :model-value="'Alt+c'" disabled style="width: 200px" />
            <img v-if="barcodeImages['Alt+c']" :src="barcodeImages['Alt+c']" />
            <el-button type="primary" @click="handlePrintBarcode('Alt+c')">打印条码</el-button>
          </div>
        </el-form-item>
        <el-form-item label="拍照快捷键">
          <div class="printer-row">
            <el-input :model-value="'Alt+a'" disabled style="width: 200px" />
            <img v-if="barcodeImages['Alt+a']" :src="barcodeImages['Alt+a']" />
            <el-button type="primary" @click="handlePrintBarcode('Alt+a')">打印条码</el-button>
          </div>
        </el-form-item>
        <el-form-item label="创建波次快捷键">
          <div class="printer-row">
            <el-input :model-value="'Alt+x'" disabled style="width: 200px" />
            <img v-if="barcodeImages['Alt+x']" :src="barcodeImages['Alt+x']" />
            <el-button type="primary" @click="handlePrintBarcode('Alt+x')">打印条码</el-button>
          </div>
        </el-form-item>
        <el-form-item label="生成波次条形码快捷键">
          <div class="printer-row">
            <el-input :model-value="'Alt+b'" disabled style="width: 200px" />
            <img v-if="barcodeImages['Alt+b']" :src="barcodeImages['Alt+b']" />
            <el-button type="primary" @click="handlePrintBarcode('Alt+b')">打印条码</el-button>
          </div>
        </el-form-item>
      </el-form>



      <el-empty v-if="!loading && printers.length === 0" description="未检测到可用打印机" />
    </el-card>

    <el-card class="printer-card">
      <template #header>
        <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
          <span>摄像头配置</span>
          <el-button type="primary" @click="refreshCameras" :loading="cameraLoading">
            <el-icon>
              <Refresh />
            </el-icon>
            刷新摄像头列表
          </el-button>
        </div>
      </template>

      <el-form label-width="140px" label-position="left" class="printer-form">
        <el-form-item label="摄像头">
          <div class="printer-row">
            <el-select v-model="selectedCamera" placeholder="请选择摄像头" style="width: 400px" clearable>
              <el-option v-for="c in cameras" :key="c.deviceId" :label="c.label" :value="c.deviceId" />
            </el-select>
            <el-button type="primary" @click="confirmCamera">确定</el-button>
          </div>
        </el-form-item>
      </el-form>

      <el-empty v-if="!cameraLoading && cameras.length === 0" description="未检测到可用摄像头" />
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import { getSimplePrinterList, initLodop, createPrintTask } from '@/api/print'
import JsBarcode from 'jsbarcode'

const STORAGE_KEY_BARCODE = 'printer_barcode'
const STORAGE_KEY_EXPRESS = 'printer_express'
const STORAGE_KEY_PAPER_SIZE = 'printer_paper_size'
const STORAGE_KEY_CAMERA = 'printer_camera'

const loading = ref(false)
const printers = ref([])
const barcodePrinter = ref('')
const expressPrinter = ref('')
const paperSize = ref('')

const cameraLoading = ref(false)
const cameras = ref([])
const selectedCamera = ref('')

const shortcutItems = ['Alt+c', 'Alt+a', 'Alt+x', 'Alt+b']
const barcodeImages = reactive({})

shortcutItems.forEach(key => {
  barcodeImages[key] = ''
})

const fetchBarcodeImage = (text) => {
  try {
    const canvas = document.createElement('canvas')
    JsBarcode(canvas, text, {
      format: 'CODE128',
      fontSize: 14,
      margin: 5,
      displayValue: true,
      lineColor: '#000000',
      width: 1.5,
      height: 40
    })
    barcodeImages[text] = canvas.toDataURL('image/png')
  } catch {
    // ignore barcode load error
  }
}

/** 使用 C-Lodop 和 localStorage 中保存的打印机打印条码 */
const handlePrintBarcode = async (key) => {
  const imageUrl = barcodeImages[key]
  if (!imageUrl) {
    ElMessage.warning({ message: '条形码尚未生成，无法打印', customClass: 'scan-warning-message' })
    return
  }

  const printerName = localStorage.getItem(STORAGE_KEY_BARCODE)
  if (!printerName) {
    ElMessage.error({ message: '条码打印机未选择', customClass: 'scan-error-message' })
    return
  }

  try {
    const LODOP = await createPrintTask('barcode', { content: key })
    LODOP.SET_PRINTER_INDEX(printerName)
    LODOP.PRINT()
    ElMessage.success({ message: '打印任务已发送', duration: 1000, customClass: 'scan-success-message' })
  } catch (error) {
    ElMessage.error({ message: '打印失败：' + (error.message || '未知错误'), customClass: 'scan-error-message' })
  }
}

const confirmBarcodePrinter = () => {
  if (barcodePrinter.value) {
    localStorage.setItem(STORAGE_KEY_BARCODE, barcodePrinter.value)
    ElMessage.success({ message: '条码打印机已保存', duration: 1000, customClass: 'scan-success-message' })
  } else {
    localStorage.removeItem(STORAGE_KEY_BARCODE)
    ElMessage.success({ message: '条码打印机已清除', duration: 1000, customClass: 'scan-success-message' })
  }
}

const confirmPaperSize = () => {
  if (paperSize.value) {
    localStorage.setItem(STORAGE_KEY_PAPER_SIZE, paperSize.value)
    ElMessage.success({ message: '小票纸大小已保存', duration: 1000, customClass: 'scan-success-message' })
  }
}

const confirmExpressPrinter = () => {
  if (expressPrinter.value) {
    localStorage.setItem(STORAGE_KEY_EXPRESS, expressPrinter.value)
    ElMessage.success({ message: '快递单打印机已保存', duration: 1000, customClass: 'scan-success-message' })
  } else {
    localStorage.removeItem(STORAGE_KEY_EXPRESS)
    ElMessage.success({ message: '快递单打印机已清除', duration: 1000, customClass: 'scan-success-message' })
  }
}

const fetchCameras = async () => {
  cameraLoading.value = true
  try {
    const devices = await navigator.mediaDevices.enumerateDevices()
    cameras.value = devices.filter((d) => d.kind === 'videoinput').map((d) => ({
      deviceId: d.deviceId,
      label: d.label || `摄像头 ${d.deviceId.slice(0, 8)}`
    }))
  } catch {
    ElMessage.error({ message: '获取摄像头列表失败', customClass: 'scan-error-message' })
    cameras.value = []
  } finally {
    cameraLoading.value = false
  }
}

const refreshCameras = () => {
  fetchCameras()
}

const confirmCamera = () => {
  if (selectedCamera.value) {
    localStorage.setItem(STORAGE_KEY_CAMERA, selectedCamera.value)
    ElMessage.success({ message: '摄像头已保存', duration: 1000, customClass: 'scan-success-message' })
  } else {
    localStorage.removeItem(STORAGE_KEY_CAMERA)
    ElMessage.success({ message: '摄像头已清除', duration: 1000, customClass: 'scan-success-message' })
  }
}

const fetchPrinters = async () => {
  loading.value = true
  try {
    const list = await getSimplePrinterList()
    printers.value = list.map((name) => ({ name }))
  } catch (error) {
    ElMessage.error({ message: '获取打印机列表失败', customClass: 'scan-error-message' })
    printers.value = []
  } finally {
    loading.value = false
  }
}

const refreshPrinters = () => {
  fetchPrinters()
}

onMounted(() => {
  barcodePrinter.value = localStorage.getItem(STORAGE_KEY_BARCODE) || ''
  expressPrinter.value = localStorage.getItem(STORAGE_KEY_EXPRESS) || ''
  paperSize.value = localStorage.getItem(STORAGE_KEY_PAPER_SIZE) || ''
  selectedCamera.value = localStorage.getItem(STORAGE_KEY_CAMERA) || ''
  fetchPrinters()
  fetchCameras()

  shortcutItems.forEach(key => fetchBarcodeImage(key))
})
</script>

<style scoped>
.printer-manager {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0;
  font-size: 22px;
  color: #303133;
}

.printer-card {
  min-height: 200px;
}

.printer-form {
  max-width: 600px;
}

.printer-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.printer-form :deep(.el-form-item) {
  display: flex;
  align-items: center;
  margin-bottom: 18px;
}

.printer-form :deep(.el-form-item__label) {
  align-self: center;
  line-height: normal;
}
</style>
