<template>
  <el-dialog
    v-model="dialogVisible"
    :title="fastKey === 'detail' ? '查看详情' : '快捷生产'"
    top="140px"
    :fullscreen="true"
    :close-on-click-modal="false"
    @opened="onOpened"
    @close="emit('close')"
  >
    <div class="detail-div">
      <div class="detail-content">
        <div class="left">
          <div class="left-images">
            <el-carousel
              v-if="detail?.imgList.length > 0"
              style="height: 100%"
              :autoplay="false"
              indicator-position="none"
            >
              <el-carousel-item
                v-for="(item, index) in detail?.imgList"
                :key="index"
                style="height: 100%"
              >
                <div class="left-image">
                  <b v-show="item?.title && item?.url">
                    {{ item?.title }}
                    <span
                      v-if="item?.id"
                      style="
                        text-decoration: underline;
                        cursor: pointer;
                        color: blue;
                      "
                    >
                      （DID：{{ item?.id }}）
                    </span>
                  </b>
                  <img :src="item.url" alt="" />
                </div>
              </el-carousel-item>
            </el-carousel>
          </div>
        </div>
        <div class="right">
          <div v-if="fastKey === 'fastProduction'" class="input">
            <el-input
              ref="trackingNumberRef"
              v-model="TrackingNumber"
              :placeholder="placeholderText"
              style="width: 660px; margin-right: 10px"
              clearable
              @keydown.enter="trackCodeInput()"
            ></el-input>
            <el-button type="primary" @click="trackCodeInput()">
              查询
            </el-button>
          </div>
          <div class="div-text">
            <div class="div-content">
              <div :title="String(detail?.userMark)" class="div-item">
                <span style="font-size: 18px">客户</span>
                <p style="color: red; font-size: 30px">
                  {{ detail?.userMark }}
                </p>
              </div>
              <div
                :title="String(detail?.factoryOrderNumber)"
                class="div-item"
                style="margin-top: 14px"
              >
                <span style="font-size: 18px">订单号</span>
                <p style="color: red; font-size: 22px">
                  {{ detail?.factoryOrderNumber }}
                </p>
              </div>
            </div>
          </div>
          <div class="div-text">
            <b v-if="!showOperationNoRow">生产单信息</b>
            <b v-else>操作单信息</b>
            <div class="div-content">
              <div
                v-if="showOperationNoRow"
                :title="String(operationNoDisplay)"
                class="div-item"
              >
                <span>操作单号</span>
                <p>{{ operationNoDisplay }}</p>
              </div>
              <div
                v-else
                :title="detail?.factorySubOrderNumber"
                class="div-item"
              >
                <span>生产单号</span>
                <p>
                  {{ detail?.factorySubOrderNumber }}
                </p>
              </div>
              <div
                v-if="!showOperationNoRow"
                :title="detail?.thirdSubOrderNumber || ''"
                class="div-item"
              >
                <span>第三方生产单号</span>
                <p>
                  {{ detail?.thirdSubOrderNumber }}
                </p>
              </div>
              <div :title="String(detail?.craftName)" class="div-item">
                <span>生产工艺</span>
                <p>
                  {{ detail?.craftName }}
                </p>
              </div>
              <div :title="detail?.baseSku" class="div-item">
                <span>基版</span>
                <p>{{ detail?.baseSku }}</p>
              </div>

              <div :title="detail?.variantSku" class="div-item">
                <span>变体SKU</span>
                <p>{{ detail?.variantSku }}</p>
              </div>
              <div
                :title="
                  String(showOperationNoRow ? detail?.quantity : detail?.num)
                "
                class="div-item"
              >
                <span>数量</span>
                <p>{{ showOperationNoRow ? detail?.quantity : detail?.num }}</p>
              </div>

              <div :title="String(detail?.size)" class="div-item">
                <span>尺寸</span>
                <p>{{ detail?.size }}</p>
              </div>
              <div
                v-if="detail?.sizeType"
                :title="String(detail?.sizeType)"
                class="div-item"
              >
                <span>尺码类型</span>
                <p>
                  {{ sizeList.find((i) => i.value === detail.sizeType)?.name }}
                </p>
              </div>

              <div :title="detail?.shopNumber ?? ''" class="div-item">
                <span>店铺单号</span>
                <p>{{ detail?.shopNumber ?? '' }}</p>
              </div>

              <div :title="detail?.createTime" class="div-item">
                <span>创建时间</span>
                <p>{{ detail?.createTime }}</p>
              </div>
            </div>
          </div>

          <div class="btn">
            <div
              :style="{
                visibility: fastKey === 'fastProduction' ? 'visible' : 'hidden',
              }"
              class="btn-sure"
            >
              <el-button
                style="width: 100%; height: 100%; font-size: 18px"
                size="large"
                type="success"
                @click="changeStatus"
              >
                生产完成
              </el-button>
              <div class="check">
                <el-checkbox v-model="isAutoSure"> 自动完成上一单 </el-checkbox>
              </div>
            </div>
            <div class="btn-down">
              <div class="check">
                <el-checkbox v-model="isDownloadImage" size="large">
                  扫码下载素材
                </el-checkbox>
              </div>
              <el-button
                style="width: 100%; height: 100%; font-size: 18px"
                type="primary"
                size="large"
                @click="handleDownload"
              >
                下载素材
              </el-button>
            </div>
          </div>
          <div
            class="div-text"
            style="
              flex: 1;
              flex-shrink: 0;
              display: flex;
              flex-direction: column;
            "
          >
            <div
              v-if="Array.isArray(detail?.note) && detail.note.length"
              style="height: 100%"
              class="div-content"
            >
              <b style="position: absolute; top: -12px">客户留言信息</b>
              <div
                v-for="(item, index) in detail?.note"
                :key="index"
                class="div-item"
              >
                <span>{{ item.prop }}:</span>
                <p>
                  {{ item.value }}
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </el-dialog>
</template>
<script setup lang="tsx">
import {
  productionQueryApi,
  getSubOrderBySubOrderNumber,
  downloadMaterialApi,
} from '@/api/podCnOrder'
import { cardImages, PodOrderRes } from '@/types/api/podCnOrder'
import { showConfirm } from '@/utils/ui'
import { filePath } from '@/api/axios'
import { computed, ref, watch } from 'vue'
import { BaseRespData } from '@/types/api'
interface HistoryDataItem {
  orderNumber: string
  finished: boolean
}

export type FastProductionDetail = PodOrderRes & {
  operationNo?: string | null
  quantity?: number | null
  podOrderNo?: string | null
  podOrderProductId?: number | null
}
const trackingNumberRef = ref()
const historyData = ref<HistoryDataItem[]>([])
const placeholderText = ref('')
const sendNum = ref(0)
const isDownloadImage = ref(false)
const isAutoSure = ref(true)
const emptyDetail = (): FastProductionDetail => ({
  id: -1,
  podJomallOrderCnId: -1,
  imgList: [] as cardImages[],
})
const detail = ref<FastProductionDetail>(emptyDetail())
const dialogVisible = ref(false)
// 尺码类型表
const sizeList = ref<{ name: string; value: number }[]>([
  { name: '正常码', value: 1 },
  { name: '大码', value: 2 },
])
// 通过import动态导入音频文件
const audios = {
  weight_warning: new URL('@/assets/audio/weight_warning.mp3', import.meta.url)
    .href,
  weight_success: new URL('@/assets/audio/weight_success.mp3', import.meta.url)
    .href,
  weight_repeat: new URL('@/assets/audio/weight_repeat.mp3', import.meta.url)
    .href,
  weight_search_error: new URL(
    '@/assets/audio/weight_search_error.mp3',
    import.meta.url,
  ).href,
  weight_search_success: new URL(
    '@/assets/audio/weight_search_success.mp3',
    import.meta.url,
  ).href,
}
const TrackingNumber = ref('')
const props = withDefaults(
  defineProps<{
    type?: number
    detailVisible?: boolean
    detailData?: Record<string, unknown> | null
    fastKey?: string
    historyStorageKey?: string
    trackingPlaceholder?: string
    isNewOrder?: boolean
    queryApi?: (orderNumber: string) => Promise<{ data?: unknown }>
    completeApi?: (
      ids: number[],
      detail: Record<string, unknown>,
    ) => Promise<unknown>
    downloadApi?: (
      ids: number[],
    ) => Promise<{ code?: number; message?: string }>
    /** 打开弹框时「自动完成上一单」的初始勾选；默认 false，与原有 podCN 快捷生产一致 */
    defaultAutoSure?: boolean
    /** 为 true 时展示「操作单号」一行，数据字段为 `operationNo`（不影响 podCN 默认） */
    showOperationNoRow?: boolean
    /** 查询无数据时的提示 */
    notFoundMessage?: string
    /** 未生产完成提醒里对单号的称呼，如「生产单号」「操作单号」 */
    pendingOrderLabel?: string
    /** 未扫码时的提示 */
    pleaseScanTip?: string
    /** 扫码输入为空时音频/提示文案 */
    searchInputAudioTip?: string
  }>(),
  {
    type: 0,
    detailVisible: false,
    detailData: null,
    fastKey: '',
    isNewOrder: false,
    historyStorageKey: 'historyCnData',
    trackingPlaceholder:
      '扫描枪输入生产单号，录入下一单本单自动生产完成，最后一单扫两次完成生产',
    defaultAutoSure: true,
    showOperationNoRow: false,
    notFoundMessage: '生产单不存在',
    pendingOrderLabel: '生产单号',
    pleaseScanTip: '请扫码生产单号',
    searchInputAudioTip: '请录入生产单号',
    queryApi: (orderNumber: string) => getSubOrderBySubOrderNumber(orderNumber),
    completeApi: (ids: number[], detailData: Record<string, unknown>) =>
      productionQueryApi(ids[0], Number(detailData.podJomallOrderCnId || -1)),
    downloadApi: (ids: number[]) => downloadMaterialApi(ids),
  },
)
const emit = defineEmits(['update:detailVisible', 'close', 'onSuccess'])

const historyKeyFromDetail = (d: FastProductionDetail): string => {
  const raw = d as unknown as Record<string, unknown>
  const op = raw.operationNo
  if (op !== undefined && op !== null && String(op).trim() !== '') {
    return String(op)
  }
  return String(d.factorySubOrderNumber ?? '')
}

const operationNoDisplay = computed(() => {
  const raw = detail.value as unknown as Record<string, unknown>
  const v = raw.operationNo
  if (v === undefined || v === null) return ''
  return String(v)
})

const parseImages = (value: unknown): cardImages[] => {
  if (!value) return []
  if (Array.isArray(value)) {
    return value
      .filter((item) => !!item?.url)
      .map((item, index) => ({
        title: String(item?.title || ''),
        url: String(item?.url || ''),
        sort: Number(item?.sort ?? index + 1),
        id: item?.id,
      }))
  }
  if (typeof value === 'string') {
    const source = value.trim()
    if (!source) return []
    if (source.startsWith('http')) {
      return source.split(',').map((url, index) => ({
        title: '',
        url: url.trim(),
        sort: index + 1,
      }))
    }
    try {
      const parsed = JSON.parse(source)
      if (Array.isArray(parsed)) {
        return parsed
          .filter((item) => !!item?.url)
          .map((item, index) => ({
            title: String(item?.title || ''),
            url: String(item?.url || ''),
            sort: Number(item?.sort ?? index + 1),
            id: item?.id,
          }))
      }
    } catch (_e) {
      return []
    }
  }
  return []
}

const normalizeDetail = (value: unknown): FastProductionDetail => {
  const raw = (value || {}) as Record<string, unknown>
  const d = JSON.parse(JSON.stringify(raw)) as Record<string, unknown>
  if (typeof d.note === 'string') {
    try {
      d.note = JSON.parse(d.note)
    } catch (_e) {
      d.note = []
    }
  }
  if (!Array.isArray(d.note)) d.note = []
  const imageSource = d.imageAry || d.designImages || d.imgList
  d.imgList = parseImages(imageSource)
  return d as unknown as FastProductionDetail
}

watch(
  () => props.detailVisible,
  (newVal: boolean) => {
    dialogVisible.value = newVal
    detail.value = { id: -1, podJomallOrderCnId: -1, imgList: [] }
    if (newVal) {
      const history = localStorage.getItem(props.historyStorageKey)
      historyData.value = history ? JSON.parse(history) : []

      const len = historyData.value
      if (len.length > 0 && props.fastKey === 'fastProduction') {
        confirmQuery(len, 0)
      }
      placeholderText.value = props.trackingPlaceholder

      trackingNumberRef.value && trackingNumberRef.value.focus()

      TrackingNumber.value = ''
      isAutoSure.value = props.defaultAutoSure
      sendNum.value = 0
    }
  },
)
watch(
  () => props.detailData,
  (newVal) => {
    detail.value = {
      id: -1,
      podJomallOrderCnId: -1,
      imgList: [],
    }
    if (newVal && Object.keys(newVal).length > 0) {
      detail.value = normalizeDetail(newVal)
    }
  },
  { deep: true },
)
const confirmQuery = (len: HistoryDataItem[], i: number) => {
  const el = len[i]
  showConfirm(
    `${props.pendingOrderLabel} ${el.orderNumber} 未生产完成，取消则不提醒?`,
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    },
  )
    .then(async () => {
      TrackingNumber.value = el.orderNumber
      await trackCodeInput()
      await setData(el.orderNumber)
      ElMessage.success('生产完成')
      if (len[i + 1]) {
        confirmQuery(len, i + 1)
      }
    })
    .catch(() => {
      const index = historyData.value.findIndex(
        (item: HistoryDataItem) => item.orderNumber === el.orderNumber,
      )
      if (index >= 0) {
        historyData.value.splice(index, 1)
        localStorage.setItem(
          props.historyStorageKey,
          JSON.stringify(historyData.value),
        )
      }
      if (len[i + 1]) {
        confirmQuery(len, i + 1)
      }
      trackingNumberRef.value && trackingNumberRef.value.focus()
    })
}

const changeStatus = async () => {
  if (!detail.value || Object.keys(detail.value).length <= 1) {
    return ElMessage.warning(props.pleaseScanTip)
  }
  showConfirm('确定生产完成？', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    setData(historyKeyFromDetail(detail.value))
  })
}
const setData = async (orderNumber: string) => {
  if (!detail.value || detail.value?.id === -1) return
  try {
    const id = detail.value.id
    const res = (await props.completeApi(
      [id],
      detail.value as unknown as Record<string, unknown>,
    )) as unknown as BaseRespData<
      {
        factoryOrderNumber?: number
        id: number
        message?: string
        status?: boolean
      }[]
    >
    if (orderNumber) {
      const index = historyData.value.findIndex(
        (el: HistoryDataItem) => el.orderNumber === orderNumber,
      )
      if (index >= 0) {
        // 扫单完成删除
        historyData.value.splice(index, 1)
        localStorage.setItem(
          props.historyStorageKey,
          JSON.stringify(historyData.value),
        )
      }
    }
    emit('onSuccess', res.data)
    playAudio('weight_success')
    detail.value = {
      id: -1,
      podJomallOrderCnId: -1,
      imgList: [] as cardImages[],
    }
    TrackingNumber.value = ''
    isDownloadImage.value = false
    trackingNumberRef.value && trackingNumberRef.value.focus()
  } catch (e) {
    console.error(e)
    detail.value = {
      id: -1,
      podJomallOrderCnId: -1,
      imgList: [] as cardImages[],
    }
    trackingNumberRef.value && trackingNumberRef.value.focus()
    playAudio('weight_search_error')
  }
}

const handleDownload = () => {
  if (
    !detail.value ||
    Object.keys(detail.value).length <= 1 ||
    detail.value.id == -1
  ) {
    return ElMessage.warning(props.pleaseScanTip)
  }
  download()
}
const download = async () => {
  if (detail.value && detail.value?.id != -1) {
    try {
      const id = props.isNewOrder
        ? detail.value.podOrderProductId as number
        : detail.value.id
      if (id !== undefined) {
        try {
          const res = await props.downloadApi([id])
          if (res.code !== 200) return
          // window.open(filePath + res.message)
          const a = document.createElement('a')
          a.href = filePath + res.message
          a.download = res.message!
          a.target = '_blank'
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
        } catch (e) {
          console.error(e)
        }
      }
    } catch (e) {
      // showError(e)
      console.error(e)
    }
  }
}
type AudioKey = keyof typeof audios // 创建一个类型，确保 key 只能是 audios 对象的键之一
const playAudio = (key: AudioKey, message?: string) => {
  let text = ''
  switch (key) {
    case 'weight_search_success':
      text = ''
      break
    case 'weight_search_error':
      text = props.searchInputAudioTip
      break
    case 'weight_success':
      text = ''
      break
    case 'weight_repeat':
      text = '称重复录入'
      break
    default:
      text = '请录入跟踪号或重量'
      break
  }
  if (message || text) ElMessage.warning(message || text)
  const audio = new Audio()
  if (audios[key]) {
    audio.src = audios[key] // 获取对应 key 的音频路径
    audio.play().catch((err) => console.error('Audio play failed:', err)) // 捕获音频播放失败的错误
  } else {
    console.error(`No audio found for key: ${key}`)
  }
}

const trackCodeInput = async () => {
  if (!TrackingNumber.value) {
    playAudio('weight_search_error', props.searchInputAudioTip)
    trackingNumberRef.value && trackingNumberRef.value.focus()
    return
  }
  const item = historyData.value.find(
    (el: HistoryDataItem) => el.orderNumber === TrackingNumber.value,
  )
  if (!item) {
    // 记录扫单
    historyData.value.push({
      orderNumber: TrackingNumber.value,
      finished: false,
    })
    localStorage.setItem(
      props.historyStorageKey,
      JSON.stringify(historyData.value),
    )
  }

  const orderNumber = TrackingNumber.value

  if (isAutoSure.value) {
    await setData(
      historyData.value[historyData.value.length - 1].orderNumber || '',
    )
  }

  try {
    const res = await props.queryApi(orderNumber)
    if (!res.data) {
      return ElMessage.error(props.notFoundMessage)
    }
    detail.value = normalizeDetail(res.data)

    if (isDownloadImage.value) {
      download()
    }
    playAudio('weight_search_success')

    trackingNumberRef.value && trackingNumberRef.value.focus()
    TrackingNumber.value = ''
  } catch (e) {
    console.error(e)
    trackingNumberRef.value && trackingNumberRef.value.focus()
    TrackingNumber.value = ''
  }
}
const onOpened = () => {
  trackingNumberRef.value && trackingNumberRef.value.focus()
}
</script>
<style lang="scss" scoped>
.sure-btn {
  position: absolute;
  right: 62px;
  top: 14px;
}

.detail-div {
  display: flex;
  height: 100%;
  flex-direction: column;
  justify-content: space-between;

  .detail-images {
    .scroll-list {
      background: #ececec;
      display: flex;
      height: 100px;
      width: 100%;
      padding: 5px;

      .scroll-content {
        margin-left: 10px;
        overflow-x: auto;
        overflow-y: hidden;
        flex: 1;
        display: flex;
        flex-wrap: nowrap;
        flex-shrink: 0;

        .scroll-item {
          height: 100%;
          min-width: 100px;
          background: white;
          margin-right: 5px;
        }
      }

      .img-title {
        display: flex;
        flex-direction: column;
        justify-content: center;
        background: white;
        padding: 10px;

        b {
          text-align: center;
          color: black;
          font-weight: bold;
          font-size: 16px;
          margin-bottom: 15px;
        }

        .id {
          display: flex;
          align-items: center;
          padding: 3px 5px;
          background: #ececec;
          justify-content: center;

          img {
            width: 15px;
            margin-right: 8px;
          }
        }
      }
    }
  }

  .detail-content {
    display: flex;
    width: 100%;
  }

  .right {
    width: 730px;
    height: 100%;
    display: flex;
    flex-direction: column;

    .btn {
      margin: 20px 0;
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 50px;
      width: 100%;

      .btn-sure,
      .btn-down {
        width: 49%;
        position: relative;

        .check {
          position: absolute;
          width: 144px;
          height: 100%;
          background: transparent;
          display: flex;
          align-items: center;
          justify-content: center;
          right: 0;
          top: 1px;
        }
      }
    }

    .div-text {
      .div-content {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        align-items: flex-start;
        padding: 15px 10px;
        box-sizing: border-box;

        .div-item {
          width: 50%;
          margin-bottom: 10px;
          display: flex;
          align-items: center;

          p {
            font-weight: 400;
            color: black;
          }

          span {
            display: inline-block;
            text-align: right;
            width: 120px;
          }

          span::after {
            content: ':';
            margin: 0 3px;
          }
        }
      }

      b {
        position: relative;
        background: white;
        top: 9px;
        left: 13px;
        padding: 0 10px;
        font-size: 18px;
        color: black;
        z-index: 3;
      }

      .div-content {
        position: relative;
        border: 1px solid #ececec;
      }
    }

    .input {
      display: flex;
      align-items: center;
      margin: 30px 0;
    }
  }

  .left {
    flex: 1;
    flex-shrink: 0;
    margin-right: 20px;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;

    .left-image {
      display: flex;
      height: 100%;
      flex-direction: column;
      justify-content: center;

      img {
        height: auto;
        width: 100%;
        max-height: 90%;
        object-fit: contain;
      }

      b {
        color: black;
        font-size: 18px;
        margin-bottom: 15px;
      }
    }

    .left-images {
      display: flex;
      width: 95%;
      height: 100%;
      flex-direction: column;

      b {
        color: black;
        text-align: center;
        margin-bottom: 15px;
      }
    }
  }
}

.left-images {
  :deep(.el-carousel__container) {
    height: 100%;
  }
  :deep(.el-dialog__title) {
    font-weight: bold;
    font-size: 37px;
    color: black;
    position: relative;
    left: 47%;
    top: 13px;
  }
}

.btn {
  position: relative;

  :deep(.el-button) {
    span {
      position: relative;
      left: -30px;
    }
  }

  .check {
    :deep(.el-checkbox__inner) {
      background-color: transparent !important;
      border-color: white !important;
      width: 12px;
      height: 12px;
    }

    :deep(.el-checkbox__inner::after) {
      left: 3px;
    }

    :deep(.el-checkbox__label) {
      padding-left: 5px;
      font-size: 12px;
      color: white !important;
    }
  }
}
.warning {
  font-size: 18px;
  font-weight: bold;
  color: #ff9900;
  margin-left: 10px;
  cursor: pointer;
}
</style>
