<template>
  <ElDialog
    v-model="visible"
    title="单件打单"
    fullscreen
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :before-close="handleClose"
    style="top: 60px"
    modal-class="pod-make-order-dialog"
    @close="onClose"
  >
    <template #header>
      <span class="customize-title">
        <span>{{ '单件打单' }}</span>
        <span style="margin-left: 10px"></span>
      </span>
    </template>
    <div style="display: flex">
      <el-form style="flex: 1" :inline="true" @submit.prevent>
        <div style="display: flex">
          <div style="flex: 1">
            <div>
              <el-form-item label="">
                <el-select
                  v-model="warehouseId"
                  filterable
                  placeholder="请选择仓库"
                  clearable
                  @change="handleWarehouseChange"
                >
                  <el-option
                    v-for="item in warehouseList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="">
                <el-select
                  v-model="sheetPrinter"
                  :placeholder="ttChecked ? '物流面单' : '面单打印机'"
                  clearable
                  filterable
                  style="width: 150px"
                  @change="handlePrinterChange"
                >
                  <el-option
                    v-for="(item, index) in deviceList"
                    :key="index"
                    :label="item"
                    :value="item"
                  ></el-option>
                </el-select>
              </el-form-item>
              <el-form-item v-if="checked || ttChecked" label="">
                <el-select
                  v-model="labelPrinter"
                  :placeholder="ttChecked ? '装箱单打印机' : '商品标签打印机'"
                  clearable
                  filterable
                  style="width: 150px"
                >
                  <el-option
                    v-for="(item, index) in deviceList"
                    :key="index"
                    :label="item"
                    :value="item"
                  ></el-option>
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-input
                  ref="testingInputRef"
                  v-model="barcode"
                  style="width: 400px"
                  placeholder="请输入生产单号/ 主SKU"
                  @keyup.enter="barcodeInput"
                ></el-input>
              </el-form-item>

              <el-form-item>
                <el-button type="primary" @click="barcodeInput">
                  查询
                </el-button>
              </el-form-item>
              <el-form-item>
                <el-checkbox v-model="autoPrint">自动打印</el-checkbox>
              </el-form-item>
            </div>
            <div>
              <el-form-item label-width="90px" label="物流跟踪号:">
                <span
                  style="width: 164px; display: inline-block"
                  class="beyondContent"
                >
                  {{ testingData?.trackingNumber }}
                </span>
              </el-form-item>

              <el-form-item label-width="90px" label="店铺单号:">
                <span
                  style="width: 164px; display: inline-block"
                  class="beyondContent"
                >
                  {{ testingData?.shopNumber }}
                </span>
              </el-form-item>

              <el-form-item label-width="90px" label="商品总数量:">
                <span style="width: 164px; display: inline-block">
                  {{ testingData?.purchaseNumber }}
                </span>
              </el-form-item>
              <!-- <el-form-item label-width="90px" label="拣货数量:">
                <span style="width: 164px; display: inline-block">
                  {{ testingData?.pickingNumber }}
                </span>
              </el-form-item> -->
              <el-form-item label-width="90px" label="订单号:">
                <span style="width: 164px; display: inline-block">
                  {{ testingData?.factoryOrderNumber }}
                </span>
              </el-form-item>
              <el-form-item label-width="90px" label="物流公司:">
                <span style="width: 164px; display: inline-block">
                  {{ testingData.company }}
                </span>
              </el-form-item>
              <el-form-item label-width="90px" label="物流方式:">
                <span
                  style="
                    width: 164px;
                    display: inline-block;
                    overflow: hidden;
                    white-space: nowrap;
                    text-overflow: ellipsis;
                  "
                >
                  {{ testingData.logisticsWayName }}
                </span>
              </el-form-item>
              <el-form-item label-width="90px" label="发货备注:">
                <span
                  :title="testingData?.remark"
                  style="width: 663px; color: red; display: inline-block"
                >
                  {{ testingData?.remark }}
                </span>
              </el-form-item>
            </div>
            <div class="table-content">
              <TableView
                ref="productTable"
                :paginated-data="testingData?.productList || []"
                :columns="podOrderDetailsColumns"
                highlight-current-row
                @row-click="handleRowClick"
              >
                <template #image="{ row }">
                  <div style="display: flex; flex-wrap: nowrap">
                    <div
                      v-for="img in row.productMark !== 'normal' &&
                      row.productMark !== 'custom_normal'
                        ? row.previewImgs
                        : [{ url: row.variantImage }]"
                      :key="img"
                      style="cursor: pointer; margin-right: 5px; flex: 1"
                      @click.stop="handleCurrentChange(img.url)"
                    >
                      <img v-if="img.url" :src="img.url" alt="" />
                    </div>
                  </div>
                </template>
                <!-- <template #printResult="{ row }">
                  <p>{{ row.printTagResult }}</p>
                  <el-button
                    size="small"
                    type="primary"
                    @click="printTemu(testingData, 1)"
                  >
                    打印标签
                  </el-button>
                </template> -->
              </TableView>
            </div>
          </div>
          <div
            style="
              margin-left: 10px;
              display: flex;
              flex-direction: column;
              height: 88vh;
            "
          >
            <div
              style="
                position: relative;
                width: 520px;
                border: 1px solid #ddd;
                background: rgb(50 50 50);
                border-radius: 5px;
                padding: 10px 15px;
                box-sizing: border-box;
                font-size: 16px;
                color: #fff;
                overflow: hidden;
              "
            >
              <span
                v-if="
                  testingData.productList && testingData.productList.length > 1
                "
                style="font-size: 16px; color: #666"
                class="multiple_pieces"
              >
                <span
                  style="
                    position: absolute;
                    z-index: 2;
                    color: #fff;
                    left: -20px;
                  "
                >
                  多
                </span>
              </span>
              <p>
                <el-button
                  v-if="
                    testingData.pickingNumber &&
                    testingData.purchaseNumber &&
                    testingData.pickingNumber === testingData.purchaseNumber
                  "
                  type="primary"
                  @click="print(testingData)"
                >
                  手动打印
                </el-button>
                <el-button type="primary" @click="printFile(testingData)">
                  打印面单
                </el-button>
                <el-button type="success" @click="orderCompleted">
                  打单完成
                </el-button>
              </p>
            </div>
            <div
              style="display: flex; flex: 1; flex-shrink: 0; overflow: hidden"
            >
              <div
                style="
                  min-width: 520px;
                  overflow-y: scroll;
                  height: 97.5%;
                  margin-top: 15px;
                  border: 1px solid #ececec;
                "
              >
                <img :src="coverImage" alt="" />
              </div>
            </div>
          </div>
        </div>
      </el-form>
    </div>
  </ElDialog>
</template>

<script setup lang="ts">
import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
import useLodop from '@/utils/hooks/useLodop'
import TableView from '@/components/TableView.vue'
import { OrderData, ProductList, IorderItem } from '@/types/api/podMakeOrder'
// import { PackingData } from '@/types/api/podCnOrder'
import useUserStore from '@/store/user'
import {
  getSingleQueryApi,
  submitInspectionApi,
  getPrintLogisticLabelApi,
} from '@/api/podCnOrder'
const { getCLodop } = useLodop()
import useOrderStore from '@/store/cnOrder'
import { WarehouseListData } from '@/types/index'
const orderStore = useOrderStore()
const boxList = computed(() => orderStore.podBoxList)
const podOrderDetailsColumns = computed(() => [
  {
    label: '图片',
    prop: 'image',
    width: 300,
    slot: 'image',
    align: 'center',
    fixed: 'left',
  },
  {
    label: '生产单号',
    prop: 'podJomallCnNo',
    width: 200,
    align: 'center',
  },
  {
    label: 'variant SKU',
    prop: 'variantSku',
    width: 200,
    align: 'center',
  },
  {
    label: '库存SKU',
    prop: 'thirdSkuCode',
    width: 200,
    align: 'center',
  },
  {
    label: '商品名称',
    prop: 'productName',
    align: 'center',
  },

  {
    label: '购买数量',
    prop: 'purchaseNumber',
    width: 90,
    align: 'center',
  },
  // {
  //   label: '拣货数量',
  //   prop: 'count',
  //   width: 90,
  //   align: 'center',
  // },
  // 动态列：根据 checked 显隐
  // ...(checked.value
  //   ? [
  //       {
  //         label: '打印结果',
  //         prop: 'printTagResult',
  //         width: 120,
  //         headerAlign: 'center',
  //         align: 'center',
  //         slot: 'printResult',
  //       },
  //     ]
  //   : []),
])
const noObj = ref<Record<string, OrderData>>({})
const checked = ref<boolean>(false)
const autoPrint = ref<boolean>(false)
const ttChecked = ref<boolean>(false)
const barcode = ref<string>('')
const testingData = ref<OrderData>({})
const coverImage = ref<string>('')
const deviceList = ref<string[]>([])
const sheetPrinter = ref<string>('')
const labelPrinter = ref<string>('')
const boxIndex = ref<number | null>(null)
const currentCode = ref<string>('')
const warehouseId = ref<string>('')
const _warehouseId = ref<string>('')
const props = defineProps<{
  modelValue: boolean
  printOrder: (data: OrderData, callback: (status: boolean) => void) => void
  // printOrderOne?: () => void // 单个打印
  warehouseList: WarehouseListData[]
  /**
   * 可复用注入：单件打单查询接口
   * - 默认：CN 的 getSingleQueryApi
   */
  queryApi?: (
    code: string,
    factoryNo: number,
    warehouseId: number | string,
  ) => Promise<{ code: number; data: OrderData }>
  /**
   * 可复用注入：单件打单完成接口
   * - 默认：CN 的 submitInspectionApi
   * - 入参 data 与 CN 组件内部 orderParamList 映射保持一致（{id, version?}数组）
   */
  submitCompleteApi?: (
    data: { id: number; version?: number }[],
    warehouseId: number | string,
  ) => Promise<{ code: number; message?: string }>
  /**
   * 可复用注入：获取打印面单（返回 data.filePath 或 data.fileData，或直接返回字符串路径）
   * - 默认：CN 的 getPrintLogisticLabelApi
   */
  printLabelApi?: (id?: number) => Promise<{ code: number; data: unknown }>
  /**
   * 可复用注入：orderParamList 映射成提交给接口的数组
   * - 默认：包含 version（dataVersion）
   */
  mapOrderParamListToSubmitItems?: (
    orderParamList: IorderItem[],
  ) => { id: number; version?: number }[]
  /**
   * 仓库选择的 sessionStorage key
   * - 默认：locaclCnSingel
   */
  warehouseSessionKey?: string
}>()
const emit = defineEmits<{
  (e: 'update:modelValue', v: boolean): void
  (e: 'refresh'): void
  (e: 'set-printer', v: string): void
}>()
const visible = computed({
  get() {
    return props.modelValue
  },
  set(value: boolean) {
    emit('update:modelValue', value)
  },
})
watch(visible, async (value: boolean) => {
  if (value) {
    currentCode.value = ''
    coverImage.value = ''
    testingData.value = {}
    noObj.value = {}
    checked.value = false
    const sessionKey = props.warehouseSessionKey ?? 'locaclCnSingel'
    const localRaw = sessionStorage.getItem(sessionKey)
    const localId = localRaw ? JSON.parse(localRaw) : ''
    /* 先找一次，确认本地值是否存在于列表 */
    const hit = props.warehouseList.find((w) => w.id === localId)
    warehouseId.value = hit ? localId : props.warehouseList[0].id
    _warehouseId.value = hit ? localId : props.warehouseList[0].id
    initPrintDevice()
    inputActive()
    const locaclPrinter = localStorage.getItem('sheetPrinter')

    if (locaclPrinter) sheetPrinter.value = JSON.parse(locaclPrinter)

    emit('set-printer', sheetPrinter.value)
  }
})
watch(
  () => testingData.value,
  (val) => {
    if (val && val.productList?.length)
      val.productList.forEach((el) => {
        if (!el.previewImgs) el.previewImgs = JSON.parse(el.imageAry)
      })
  },
  { deep: true },
)
const initPrintDevice = () => {
  const lodop = getCLodop(null, null)
  if (!lodop) return
  const arr = []
  // 获取打印机数量
  const length = lodop.GET_PRINTER_COUNT()
  for (let i = 0; i < length; i++) {
    // 根据设备序号获取设备名
    const name = lodop.GET_PRINTER_NAME(i)
    arr.push(name)
  }
  console.log('arr', arr, lodop.GET_PRINTER_NAME(1))
  // 获取默认打印机
  sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
  deviceList.value = arr
}
const handleWarehouseChange = (value: string) => {
  const sessionKey = props.warehouseSessionKey ?? 'locaclCnSingel'
  sessionStorage.setItem(sessionKey, JSON.stringify(value))
}
function keyDown(e: KeyboardEvent) {
  const e1 = e || (window.event as KeyboardEvent)
  if (![37, 38, 39, 40].includes(e1.keyCode)) return
  const t = e1.target as HTMLElement | null
  if (
    t?.closest?.(
      'input, textarea, select, [contenteditable="true"], [role="textbox"]',
    )
  ) {
    return
  }
  e1.stopPropagation()
  e1.preventDefault()
  let idx = boxIndex.value ?? 0
  const len = boxList.value?.length || 0
  if (e1.keyCode === 37) idx -= 1 // 左
  if (e1.keyCode === 38) idx -= 10 // 上
  if (e1.keyCode === 39) idx += 1 // 右
  if (e1.keyCode === 40) idx += 10 // 下
  if (idx < 1 || idx > len) return
  boxIndex.value = idx
}

watch(
  visible,
  (v) => {
    if (v) {
      window.addEventListener('keydown', keyDown)
    } else {
      window.removeEventListener('keydown', keyDown)
    }
  },
  { immediate: true },
)

onUnmounted(() => {
  window.removeEventListener('keydown', keyDown)
})

const testingInputRef = ref<HTMLInputElement | null>(null)
async function inputActive() {
  await nextTick()
  ;(testingInputRef.value as HTMLInputElement)?.focus()
}
const handleRowClick = (row: ProductList) => {
  coverImage.value = row.previewImgs?.[0]?.url || ''
  inputActive()
}
const handleCurrentChange = (url: string) => {
  if (url) {
    coverImage.value = url || ''
  }
}
function playAudio(name: string) {
  const audio = new Audio()
  audio.src = new URL(`@/assets/audio/${name}.mp3`, import.meta.url).href
  audio.play()
}

const isLock = ref<boolean>(false)
async function barcodeInput() {
  const code = barcode.value.trim()
  if (!code) {
    ElMessage.warning('请录入生产单号或SKU')
    playAudio('picking_warning')
    await inputActive()
    return
  }
  if (code.startsWith('JMSC') || code.startsWith('GCSC')) {
    ElMessage.warning('暂不支持满印订单')
    return
  }
  if (isLock.value) {
    barcode.value = ''
    await inputActive()
    return
  }

  barcode.value = ''
  isLock.value = true
  console.log('noObj', noObj.value)

  /* 如果存在未提交数据，先提交再拉新包裹 */
  const keys = Object.keys(noObj.value)
  if (keys.length) {
    const pending = noObj.value[+keys[0]]
    console.log('pending', pending)

    await submitInspection(pending, async () => {
      noObj.value = {}
    })
  }
  await inputActive()
  await getPackingData(code)

  isLock.value = false
}
async function submitInspection(objs?: OrderData, callback?: () => void) {
  const result = objs ? objs : testingData.value
  const factoryNo = userStore.user?.factory.id
  if (!factoryNo) {
    return
  }
  const orderParamList = result?.orderParamList ?? []
  const data = props.mapOrderParamListToSubmitItems
    ? props.mapOrderParamListToSubmitItems(orderParamList as IorderItem[])
    : (orderParamList as IorderItem[]).map((item) => ({
        id: item.id,
        version: item.dataVersion,
      }))
  try {
    const submitFn = props.submitCompleteApi ?? submitInspectionApi
    const res = await submitFn(data, warehouseId.value)
    if (res.code !== 200) return
    ElMessage.success(res.message)
    coverImage.value = ''
    testingData.value = {}
    isLock.value = false
    callback?.()
  } catch (e) {
    console.error(e)
    isLock.value = false
  }
}
const userStore = useUserStore()
const productTable = ref()
async function getPackingData(code: string) {
  // const data: PackingData = {}
  const arr = code.split('_')
  if (arr.length >= 4) code = arr[3]

  // if (code.startsWith('PSCD')) data.podProductionNo = code
  // else if (/^\d{16}$/.test(code)) data.jomallCustomNo = code // 16 位数字
  // else if (code.startsWith('JMSC') || code.startsWith('GCSC'))
  // data.jomallPsdCustomNo = code
  // else if (code.startsWith('S-')) data.jomallCustomNo = code
  if (code.includes('JMPSC') || code.startsWith('GCPS')) {
    code = code.replace(/^([A-Z]+-)*([A-Z]+-[\d-]+)$/, (_, __, p) => p)
  }
  // data.podJomallNo = code
  // } else data.sku = code

  const loading = ElLoading.service({ background: 'rgba(0, 0, 0, 0.3)' })
  currentCode.value = code
  const factoryNo = userStore.user?.factory.id
  if (!factoryNo) {
    isLock.value = false
    barcode.value = ''
    return
  }
  try {
    const queryFn = props.queryApi ?? getSingleQueryApi
    const res = await queryFn(code, factoryNo, warehouseId.value)
    if (res.code === 200) {
      testingData.value = res.data
      const { productList = [] } = res.data
      const pickingNumber = productList.reduce(
        (prev: number, product: ProductList) => {
          return prev + (product.count || 0)
        },
        0,
      )
      testingData.value.pickingNumber = pickingNumber
      const list = productList
      if (list.length) {
        await nextTick()
        coverImage.value = list[0].previewImgs?.[0]?.url || ''
        productTable.value?.setCurrentRow(list[0])
      }
      isLock.value = false
      if (autoPrint.value) await printFile(testingData.value)
    }
  } catch (e) {
    console.error(e)
    playAudio('picking_search_error')
    isLock.value = false
  } finally {
    loading.close()
  }
}
async function printFile(data: OrderData) {
  // await props.printOrderOne(data)
  await printOrderOne(data)
  noObj.value[data.id as number] = data
  await inputActive()
}
function printOrderOne(item: OrderData): Promise<void> {
  return new Promise((resolve) => {
    // /* 已有文件路径 / 数据 → 直接打印 */
    // if (item.filePath || item.fileData) {
    //   props.printOrder(item, (v) => {
    //     // item.printStatus = v
    //     console.log('printOrder', v)
    //     resolve()
    //   })
    //   return
    // }

    /* 无文件 → 先拉取再打印 */
    const loading = ElLoading.service({ background: 'rgba(0,0,0,.3)' })
    const printFn = props.printLabelApi ?? getPrintLogisticLabelApi
    printFn(item.id)
      .then((res) => {
        loading.close()
        const payload = res.data ?? {}
        if (typeof payload === 'string') {
          item.filePath = payload
        } else {
          const filePayload = payload as {
            filePath?: string
            fileData?: string
          }
          if (typeof filePayload.filePath === 'string') {
            item.filePath = filePayload.filePath
          } else if (typeof filePayload.fileData === 'string') {
            item.fileData = filePayload.fileData
          } else {
            ElMessage.error('获取打印面单失败')
            return
          }
        }
        props.printOrder(item, (v) => {
          // item.printStatus = v
          console.log('printOrder', v)
          resolve()
        })
      })
      .catch(() => loading.close())
  })
}
async function orderCompleted() {
  try {
    await ElMessageBox.alert('确定打单完成吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
    })
    await submitInspection(undefined, inputActive)
  } catch {
    await inputActive()
  }
}
const handlePrinterChange = (value: string) => {
  emit('set-printer', value)
}
function print(data: OrderData) {
  const idx = boxIndex.value!
  props.printOrder(data, (status: boolean) => {
    const item = boxList.value?.find((v) => v.box === idx)
    if (item?.data) {
      item.data.printResult = status ? '打印成功' : '打印失败'
    }
    // orderStore.setPodBoxList({
    //   boxList: item ? item.data : null,
    //   box: idx,
    //   warehouseId: warehouseId.value,
    // })
    inputActive()
  })
}
const handleClose = (done: () => void) => {
  done()
}
const onClose = () => {
  emit('refresh')
}
</script>

<style scoped lang="scss">
::v-deep .el-form-item {
  margin-bottom: 0 !important;
}
.table-content {
  height: 670px;
  overflow: auto;
}
.pod-make-order-dialog {
  .el-dialog {
    display: flex;
    flex-direction: column;
    height: calc(100% - 60px);
  }
  .el-dialog__body {
    flex: 1;
    overflow: hidden;
  }
  $primary-bg: #819aff;
  $active-bg: #ff9900;
  $badge-color: red;
  $text-light: #ddd;
  $box-size: 50px;
  $box-height: 46px;
  $border-radius: 5px;

  .box_list {
    margin-left: 10px;
    height: calc(100vh - 130px);
    overflow: auto;
    padding: 5px;
    position: relative;
    width: 470px;

    li {
      float: left;
      border: 1px solid #ddd;
      cursor: pointer;
      width: $box-size;
      font-size: 18px;
      line-height: 30px;
      height: $box-height;
      text-align: center;
      box-sizing: border-box;
      border-radius: $border-radius;
      position: relative;
      margin-right: 10px;
      margin-bottom: 8px;

      &:not(.isNull) {
        background: $primary-bg;
        color: #fff;
      }

      &.active {
        background: $active-bg;
        color: #fff;
        transform: scale(1.2);
      }

      &.badge::after {
        position: absolute;
        content: '';
        right: 4px;
        top: 4px;
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background-color: $badge-color;
      }
    }

    .number {
      position: absolute;
      bottom: 3px;
      left: 0;
      right: 0;
      text-align: center;
      font-size: 12px;
      line-height: 14px;
      color: $text-light;
    }
  }

  .multiple_pieces {
    position: absolute;
    top: 0;
    right: 0;
    color: #fff;

    &::after {
      position: absolute;
      top: -31px;
      right: -30px;
      content: '';
      border-width: 30px;
      border-style: solid;
      border-color: transparent transparent $badge-color transparent;
      transform: rotate(45deg);
    }
  }

  .box-list-item {
    position: relative;
  }

  .box-hour {
    position: absolute;
    top: -8px;
    right: 5%;
    font-size: 12px;
    color: $badge-color;
    font-weight: bold;
    cursor: pointer;
  }

  .skuImageContent {
    display: flex;
    justify-content: center;
    align-items: center;

    span {
      display: inline-block;
      background: #f56c6c;
      width: 20px;
      height: 20px;
      border-radius: 11px;
      line-height: 20px;
      margin-left: 3px;
      color: white;
      text-align: center;
    }
  }

  .beyondContent {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .customize-title {
    display: flex;
    align-items: center;
  }
}
</style>
