import { ElMessage } from 'element-plus'
import useLodop, { LODOPObject } from '@/utils/hooks/useLodop.ts'

const { getCLodop } = useLodop()
const lodopCall = async (fn: (lodop: LODOPObject) => string) => {
  if (!window._lodop) {
    window._lodop = getCLodop(null, null)
    if (window._lodop) {
      window._lodop.On_Return_Remain = true
      window._lodop.SET_PRINT_MODE('CATCH_PRINT_STATUS', true)
      window._lodopCallback = {}
      window._lodop.On_Return = function (id, value) {
        const cb = window._lodopCallback[id]
        if (!cb) return
        delete window._lodopCallback[id]
        cb(value)
      }
    }
  }

  return new Promise((resolve) => {
    let id
    if (window._lodop) {
      id = fn(window._lodop)
    }
    window._lodopCallback[id || 0] = resolve
  })
}
function downloadPDF(url: string) {
  if (!/^https?:/i.test(url)) return url
  let xhr,
    arrybuffer = false,
    dataArray = null
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest()
  } else {
    xhr = new window.ActiveXObject('MSXML2.XMLHTTP')
  }
  xhr.open('GET', url, false) //同步方式
  if (xhr.overrideMimeType)
    try {
      xhr.responseType = 'arraybuffer'
      arrybuffer = true
    } catch (err) {
      xhr.overrideMimeType('text/plain; charset=x-user-defined')
    }
  xhr.send(null)
  const data = xhr.response || xhr.responseBody
  if (typeof Uint8Array !== 'undefined') {
    if (arrybuffer) {
      dataArray = new Uint8Array(data)
    } else {
      dataArray = new Uint8Array(data.length)
      for (let i = 0; i < dataArray.length; i++) {
        dataArray[i] = data.charCodeAt(i)
      }
    }
  } else {
    dataArray = window.VBS_BinaryToArray(data).toArray() //兼容IE低版本
  }
  const digits =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
  let strData = ''
  for (let i = 0, ii = dataArray.length; i < ii; i += 3) {
    if (isNaN(dataArray[i])) break
    const b1 = dataArray[i] & 0xff,
      b2 = dataArray[i + 1] & 0xff,
      b3 = dataArray[i + 2] & 0xff
    const d1 = b1 >> 2,
      d2 = ((b1 & 3) << 4) | (b2 >> 4)
    const d3 = i + 1 < ii ? ((b2 & 0xf) << 2) | (b3 >> 6) : 64
    const d4 = i + 2 < ii ? b3 & 0x3f : 64
    strData +=
      digits.substring(d1, d1 + 1) +
      digits.substring(d2, d2 + 1) +
      digits.substring(d3, d3 + 1) +
      digits.substring(d4, d4 + 1)
  }
  return strData
}

export const print = async (url: string,printDevice:string) => {
  const lodop = getCLodop(null, null) //调用getLodop获取LODOP对象
  if (!lodop) return
  lodop.PRINT_INIT('打印内容')
  // SET_PRINTER_INDEX 指定打印设备
  const setPrintRes = lodop.SET_PRINTER_INDEX(printDevice)
  if (!setPrintRes) {
    ElMessage.warning('设置面单打印机出错')
    return
  }
  lodop.ADD_PRINT_PDF(0, 0, '100%', '100%', downloadPDF(url))
  console.log(lodop)
  if (lodop.CVERSION) {
    const startTime = Date.now()
    const jobCode = await lodopCall((lodop: LODOPObject) => {
      lodop.SET_PRINT_MODE('CATCH_PRINT_STATUS', true)
      return lodop.PRINT()
    })

    console.log('[LODOP] job ' + jobCode)
    // eslint-disable-next-line no-constant-condition
    while (true) {
      const ok = await lodopCall((lodop: LODOPObject) =>
        lodop.GET_VALUE('PRINT_STATUS_OK', jobCode),
      )
      if (ok == 1) {
        // 打印状态：成功
        return
      }
      // 如果打印状态表示未成功或者返回了空，继续获取任务是否存在
      const exist = await lodopCall((lodop: LODOPObject) =>
        lodop.GET_VALUE('PRINT_STATUS_EXIST', jobCode),
      )
      console.log(
        '[LODOP] PRINT_STATUS OK,EXIST',
        jobCode,
        ok,
        exist,
        `(${Date.now() - startTime}ms)`,
      )
      if (exist == 0) {
        // 任务不存在了
        return
      }

      await new Promise((r) => setTimeout(r, 500))
      if (Date.now() - startTime >= 30000) {
        ElMessage.error('打印超时(30秒)')
        return
      }
    }
  } else {
    lodop.PRINT()
  }
}
