<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="120px"
      v-loading="formLoading"
    >
      <el-form-item :label="t('TemplateManagement.PrintConfig.hostName')" prop="hostName">
        <el-input v-model="formData.hostName" :disabled="true" :placeholder="t('TemplateManagement.PrintConfig.placeholderHostName')" />
      </el-form-item>
      <el-form-item :label="t('TemplateManagement.PrintConfig.systemPrinterName')" prop="systemPrinterName">
<!--        <el-input v-model="formData.systemPrinterName" :placeholder="t('TemplateManagement.PrintConfig.placeholderSystemPrinterName')"  />-->
        <el-select
          v-model="formData.systemPrinterName"
          clearable
          filterable
          :placeholder="t('TemplateManagement.PrintConfig.placeholderSystemPrinterName')"
          class="hiprint-printer-select"
        >
          <el-option
            v-for="printer in printerList"
            :key="printer.name"
            :label="printer.name"
            :value="printer.name"
          />
        </el-select>
      </el-form-item>
      <el-form-item :label="t('TemplateManagement.PrintConfig.defaultStatus')" prop="isDefault">
        <el-switch v-model="formData.isDefault" />
      </el-form-item>
      <el-form-item :label="t('TemplateManagement.PrintConfig.isEnable')" prop="isEnabled">
        <el-switch v-model="formData.isEnable" />
      </el-form-item>
      <el-form-item :label="t('TemplateManagement.PrintConfig.remark')" prop="remark">
        <el-input v-model="formData.remark" :placeholder="t('TemplateManagement.PrintConfig.placeholderRemark')" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="handleClientPrint" type="primary" plain :disabled="formLoading">{{ t('TemplateManagement.PrintConfig.testPrint') }}</el-button>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('common.ok') }}</el-button>
      <el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { ConfigApi, ConfigVO } from '@/api/mes/printconfig/index'
import {
  autoConnect,
  defaultElementTypeProvider,
  hiwebSocket,
  hiprint
} from 'vue-plugin-hiprint'
/** 打印机配置 表单 */
defineOptions({ name: 'ConfigForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const printerList = ref<Array<{ name: string; [key: string]: any }>>([])
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const formData = ref({
  id: undefined,
  hostName: undefined,
  systemPrinterName: undefined,
  isDefault: undefined,
  isEnabled: undefined,
  remark: undefined,
  createdAt: undefined,
  updatedAt: undefined,
})
const formRules = reactive({
  hostName: [{ required: false, message: '主机名（如PACKING-PC-01），不可修改不能为空', trigger: 'blur' }],
  systemPrinterName: [{ required: true, message: '系统打印机名称，关联下拉选项不能为空', trigger: 'blur' }],
  isDefault: [{ required: false, message: '是否默认：0-否，1-是不能为空', trigger: 'blur' }],
  isEnabled: [{ required: false, message: '是否启用：0-禁用，1-启用不能为空', trigger: 'blur' }],
  createdAt: [{ required: false, message: '创建时间不能为空', trigger: 'blur' }],
  updatedAt: [{ required: false, message: '更新时间不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
let hiprintTemplate: any
const selectedPrinter = ref('')
const clientConnected = ref(false)
const clientPrinting = ref(false)
let hiprintInited = false
let printEventBound = false
let autoConnectTried = false
const clientConnecting = ref(false)
const clientHostStorageKey = 'hiprint-client-host'
const defaultClientHost = 'http://192.168.2.58:17521'
let item = localStorage.getItem(clientHostStorageKey);
const clientHost = ref(localStorage.getItem(clientHostStorageKey) || defaultClientHost)
const getHiwebSocket = () => {
  return ((hiwebSocket as any) || (window as any).hiwebSocket) as any
}
const syncClientState = (printersFromCallback?: Array<{ name: string; [key: string]: any }>) => {
  const socket = getHiwebSocket()
  clientConnected.value = !!socket?.opened
  const printers = printersFromCallback || hiprintTemplate?.getPrinterList?.() || socket?.printerList || []
  printerList.value = Array.isArray(printers) ? printers : []
  if (selectedPrinter.value && !printerList.value.some((printer) => printer.name === selectedPrinter.value)) {
    selectedPrinter.value = ''
  }
}

/** 打开弹窗 */
const open = async (type: string, host: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()
  formData.value.hostName = host
  syncClientState()
  // 修改时，设置数据
  if (id) {
    formLoading.value = true
    try {
      formData.value = await ConfigApi.getConfig(id)
    } finally {
      formLoading.value = false
    }
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  // 校验表单
  await formRef.value.validate()
  // 提交请求
  formLoading.value = true
  try {
    const data = formData.value as unknown as ConfigVO
    if (formType.value === 'create') {
      await ConfigApi.createConfig(data)
      message.success(t('common.createSuccess'))
    } else {
      await ConfigApi.updateConfig(data)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}
const printData = ref({
  orderNo: 'TEST-20231125-001',
  customerName: '测试客户',
  amount: 199.99,
  address: '北京市朝阳区测试街道123号'

});
const handleClientPrint = () => {
  if (!hiprintTemplate) {
    return
  }
  syncClientState()
  if (!clientConnected.value) {
    connectClient()
    message.warning('正在连接本地打印客户端，请连接成功后重试')
    return
  }
  clientPrinting.value = true
  try {
    hiprintTemplate.print2(printData.value, {
      printer: selectedPrinter.value,
      title: dialogTitle.value
    })
  } catch (error: any) {
    clientPrinting.value = false
    message.error(error?.message || '本地客户端打印失败')
  }
}
const applyClientHost = () => {
  const socket = getHiwebSocket()
  let host = normalizeClientHost()
  clientHost.value = host
  localStorage.setItem(clientHostStorageKey, host)
  if (!socket) {
    return false
  }
  if (socket?.host !== host) {
    socket?.stop?.()
    socket.host = host
  }
  return true
}

const normalizeClientHost = () => {
  const host = clientHost.value.trim()
  if (!host) {
    return defaultClientHost
  }
  if (/^https?:\/\//i.test(host)) {
    return host
  }
  return `http://${host}`
}
const refreshPrinterList = () => {
  let item = localStorage.getItem(clientHostStorageKey);
  message.success('本地打印客户端已连接'+item)
  if (!clientConnected.value) {
    applyClientHost()
    message.warning('请先连接本地打印客户端')
    return
  }
  const socket = getHiwebSocket()
  if (typeof socket?.refreshPrinterList === 'function') {
    socket.refreshPrinterList()
    window.setTimeout(syncClientState, 500)
    return
  }
  syncClientState()
}
const connectClient = () => {
  ensureInit()
  if (!applyClientHost()) {
    message.warning('打印客户端连接对象未初始化，请刷新页面后重试')
    return
  }
  clientConnecting.value = true
  autoConnect((status: boolean, msg?: string) => {
    clientConnecting.value = false
    clientConnected.value = !!status
    syncClientState()
    if (status) {
      message.success('本地打印客户端已连接')
      refreshPrinterList()
      return
    }
    message.warning(msg || '未连接到本地打印客户端，请确认 electron-hiprint 已启动')
  })
}

const ensureInit = () => {
  if (hiprintInited) {
    return
  }
  hiprint.init({
    host: normalizeClientHost(),
    providers: [defaultElementTypeProvider()]
  })
  hiprintInited = true
}
/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    hostName: undefined,
    systemPrinterName: undefined,
    isDefault: undefined,
    isEnabled: undefined,
    remark: undefined,
    createdAt: undefined,
    updatedAt: undefined,
  }
  formRef.value?.resetFields()
}
</script>
