<template>
  <div class="flex flex-col items-stretch w-[24cm] max-w-[24cm]">
    <div class="flex justify-between">
      <div class="mb-2">
        <el-tooltip
          content="其实二维码在提交SO后就会自动刷新, 除非你点了右边的Clean QR Code"
        >
          <el-button
            class="custom-button"
            @click="reGenerateQrCode"
          >
            Generate QR Code
          </el-button>
        </el-tooltip>
        <el-tooltip content="除非你不想打印二维码">
          <el-button @click="qrcodeVisible = false">Clean QR Code</el-button>
        </el-tooltip>
      </div>
      <div>
        <el-button
          type="danger"
          @click="clean"
        >
          Clean Input Job
        </el-button>
        <el-tooltip content="确认下面的预览内容没问题再点打印">
          <el-button
            class="custom-button"
            :loading="printing"
            @click="onBtnPrint"
          >
            Print Page
          </el-button>
        </el-tooltip>
      </div>
    </div>
    <div class="">
      <el-form inline>
        <el-form-item
          v-if="scene === 'SO'"
          label="QR Code Content"
          class="text-left w-[100%]"
        >
          <div
            class="el-input el-input__wrapper el-input__inner cursor-not-allowed hover:cursor-not-allowed"
          >
            {{ selectedContent.map((i) => i.Reference).join(';') }}
          </div>
        </el-form-item>

        <el-form-item
          label="Total Page"
          style="width: 20%"
          prop="total"
        >
          <el-input
            v-model.number="total"
            :type="'number'"
          ></el-input>
        </el-form-item>
        <el-form-item
          label="Text direction"
          style="width: 15%"
          prop="rotated"
        >
          <el-switch v-model="rotated"></el-switch>
        </el-form-item>
        <el-form-item
          label="Page width(CM)"
          style="width: 20%"
          prop="pageWidth"
        >
          <el-input
            v-model.number="pageWidth"
            :type="'number'"
          ></el-input>
        </el-form-item>
        <el-form-item
          label="Page Height(CM)"
          style="width: 20%"
          prop="pageHeight"
        >
          <el-input
            v-model.number="pageHeight"
            :type="'number'"
          ></el-input>
        </el-form-item>

        <el-form-item
          label="Font Size"
          style="width: 50%"
        >
          <el-slider
            v-model="pdfFontSize"
            :step="1"
          ></el-slider>
        </el-form-item>
        <el-form-item
          style="width: 100%"
          label="箱唛"
        >
          <el-input
            v-model="mai"
            type="textarea"
          ></el-input>
        </el-form-item>
        <div class="flex gap-1">
          <div
            v-for="(item, index) in logoList"
            :key="item"
            class="w-[60px] h-[60px] bg-contain bg-center bg-no-repeat cursor-pointer"
            :style="{ backgroundImage: `url(${item})` }"
            @click="selectlogo(index)"
          ></div>
        </div>
      </el-form>
    </div>
    <br />
    <div class="flex flex-wrap">
      <div
        v-for="i in total"
        :key="i"
        :style="{
          width: `${pageWidth}cm`,
          height: `${pageHeight}cm`,
        }"
        class="pdf-wrap relative border border-solid border-gray-200 mb-2 mr-2"
      >
        <div
          :id="`pdfItem-${i}`"
          :ref="(el) => setElement(el, i)"
          class="pdf-area w-[100%] h-[100%] relative text-center p-4 flex flex-col items-stretch justify-center"
          :class="{}"
          :style="{
            width: rotated ? `${pageHeight}cm` : `${pageWidth}cm`,
            height: rotated ? `${pageWidth}cm` : `${pageHeight}cm`,
            transformOrigin: 'top left',
            transform: rotated ? 'rotate(90deg)' : '',
            right: rotated ? `-${pageWidth}cm` : '',
          }"
        >
          <!-- bottom: rotated ? `-${(i - 1) * (pageWidth - pageHeight)}cm` : '', -->
          <div
            class="mai font-medium break-all mb-4"
            :style="{
              fontSize: `${pdfFontSize}pt`,
            }"
            @dblclick="ElMessage.info('hello')"
          >
            {{ mai }}
          </div>

          <div class="flex justify-center">
            <div class="font-medium text-5xl">{{ i }} / {{ total }}</div>
          </div>
          <div class="flex gap-1 absolute bottom-4 left-4">
            <div
              v-for="item in selectedLogo"
              :key="item"
              class="w-[90px] h-[90px] bg-contain bg-center bg-no-repeat"
              :style="{ backgroundImage: `url(${item})` }"
            ></div>
          </div>
          <div
            v-show="qrcodeVisible"
            class="qrcode absolute bottom-4 right-4 w-[110px] h-[110px] border border-solid border-gray-400"
          >
            <img
              v-show="qrcodeURL.length"
              style="width: 100%; height: auto"
              :src="qrcodeURL"
              alt="qr-code"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<!-- todo 后续so search如果有更新, 引用这个组件. -->
<script setup lang="ts">
import {
  defineComponent,
  defineProps,
  nextTick,
  ref,
  watch,
  computed,
} from 'vue'
import {
  ElMessage,
  ElInput,
  ElButton,
  ElForm,
  ElFormItem,
  ElSlider,
  ElTooltip,
  ElSwitch,
} from 'element-plus'
import jspdf from 'jspdf'
import qrcode from 'qrcode'
import html2canvas from 'html2canvas'
import debounce from 'lodash.debounce'
defineComponent({
  name: 'ComponentPrint',
})
const { content = [], scene = 'SO', autoOpenQRCode = true } = defineProps<{
  content: any[]
  scene?: string
  autoOpenQRCode?: boolean
}>()
let selectedContent = ref([] as any[])
const mai = ref('')
watch(
  () => content,
  () => {
    selectedContent.value = content.slice()
    if (scene === 'SO') {
      mai.value = selectedContent.value
        .map((c: any) => `${c.Reference}_${c.Contract_Title}`)
        .join('; ')
    } else if (scene === 'QC') {
      mai.value = selectedContent.value.join('')
    }
    if (mai.value.length && autoOpenQRCode) {
      nextTick(() => {
        reGenerateQrCode()
      })
    }
  },
  { deep: true, immediate: true },
)

const clean = () => {
  mai.value = ''
  selectedContent.value = []
}
let qrcodeVisible = ref(false)
let qrcodeURL = ref('')
async function reGenerateQrCode() {
  await qrcode.toDataURL(
    mai.value,
    { errorCorrectionLevel: 'H' },
    function (err: any, url: any) {
      qrcodeURL.value = url
    },
  )
  qrcodeVisible.value = true
}

const pdfList = ref({} as any)
const setElement = (el: any, index: number) => {
  pdfList.value[`${index}`] = el
}
const getLogoPath = (path: string) => {
  return new URL(path, import.meta.url).href
}

const logoList = ref([] as any[])

async function getLogoList() {
  (
    [
      getLogoPath('/assets/label/heavy.png'),
      getLogoPath('/assets/label/keep_dry.png'),
      getLogoPath('/assets/label/place_up.png'),
      getLogoPath('/assets/label/care.png'),
      getLogoPath('/assets/label/glass.png'),
    ] as string[]
  ).forEach((i: string, index: number) => {
    fetch(i)
      .then((res) => res.blob())
      .then((blob) => (logoList.value[index] = URL.createObjectURL(blob)))
  })
}
getLogoList()

const selectlogo = (index: number) => {
  const i = selectedLogoIndex.value.indexOf(index)
  if (i > -1) {
    selectedLogoIndex.value.splice(i, 1)
  } else {
    selectedLogoIndex.value.push(index)
  }
}
let selectedLogoIndex = ref([] as number[])
let selectedLogo = computed(() =>
  logoList.value.filter((i: any, index: number) =>
    selectedLogoIndex.value.includes(index),
  ),
)

let total = ref(1 as number)
let pdfFontSize = ref(32)
let pageWidth = ref(20) // 目标pdf的页宽
let pageHeight = ref(10) // 目标pdf的页高
/**
 * 宽大于等于高
 */
let orientation = computed(() => pageWidth.value >= pageHeight.value)
let rotated = ref(false)
let pdf: any = null
let printing = ref(false)
const reGeneratePDF = debounce(function () {
  printing.value = true
  pdf = null
  pdf = new jspdf({
    orientation: orientation.value ? 'l' : 'p',
    unit: 'cm',
    format: [pageWidth.value, pageHeight.value],
  })
  const pool = []
  for (const key in pdfList.value) {
    if (Object.prototype.hasOwnProperty.call(pdfList.value, key)) {
      pool.push(generatePDF(pdfList.value[key], key))
    }
  }
  Promise.all(pool).then(() => {
    printing.value = false
  })
}, 300)

watch(
  [
    total,
    mai,
    pdfFontSize,
    pageWidth,
    pageHeight,
    qrcodeVisible,
    rotated,
    selectedLogo,
  ],
  () => {
    nextTick(() => reGeneratePDF())
  },
)
async function onBtnPrint() {
  let fileName = ''
  switch (scene) {
    case 'QC':
      fileName = ''
      break
    default:
      fileName = selectedContent.value.map((i: any) => i.Reference).join('_')
  }
  window.open(
    // @ts-ignore 照着jspdf文档搬的...ts报错
    pdf.output('bloburl', {
      fileName,
    }),
  )
}
function generatePDF(pdfItem: HTMLElement, key: string) {
  return html2canvas(pdfItem, {
    allowTaint: true,
    useCORS: true,
    backgroundColor: '#fff', // 一定要设背景颜色，否则有的浏览器就会变花，比如Edge
    scale: 3, // 缩放倍率调整清晰度
  }).then((canvas) => {
    const width = canvas.width
    const height = canvas.height
    const image = new Image()
    const target = document.createElement('canvas')
    target.height = height
    target.width = width
    image.onload = function () {
      const ctx = target.getContext('2d')
      ctx?.drawImage(image, 0, 0)
      if (Number(key) > 1) pdf.addPage()
      pdf.addImage(
        target.toDataURL('image/jpeg', 1.0),
        'JPEG',
        0,
        0,
        pageWidth.value,
        pageHeight.value,
      )
    }
    image.src = canvas.toDataURL('image/jpeg', 1.0)
  })
}
</script>

<style scoped></style>
