<template>
  <ele-modal
    title="打码"
    :visible.sync="visible"
    v-if="visible"
    width="40%"
    :maxable="true"
    append-to-body
  >
    <div class="encoding-dialog">
      <div class="encoding-header">
        <el-button type="primary" size="small" @click="batchEncoding">
          批量打码
        </el-button>
        <el-button size="small" @click="refresh">刷新</el-button>
        <el-button type="warning" size="small" @click="batchBarcodeEncoding">
          批量条码打码
        </el-button>
      </div>

      <div class="encoding-content" v-if="mode === 'qrcode'">
        <div v-for="(item, index) in batchList" :key="index" class="batch-card">
          <div class="card-header">
            <span class="card-title">{{
              item.partName || item.productName || '产品标识卡'
            }}</span>
          </div>
          <div class="card-body">
            <div class="info-area">
              <div class="info-row">
                <span class="label">产品编码</span>
                <span class="value">{{ item.productCode || '-' }}</span>
              </div>
              <div class="info-row">
                <span class="label">{{
                  sourceType == 'jobBom' ? '单件码' : '合格证号'
                }}</span>
                <span class="value">{{
                  (sourceType == 'jobBom'
                    ? item.engrave
                    : item.certificateNo) || '-'
                }}</span>
              </div>
              <div class="info-row">
                <span class="label">零(部)件编码</span>
                <span class="value">{{ item.partCode || '-' }}</span>
              </div>
              <div class="info-row">
                <span class="label">零(部)件名称</span>
                <span class="value">{{ item.partName || '-' }}</span>
              </div>
              <div class="info-row">
                <span class="label">本厂批次号</span>
                <span class="value">{{ item.batchNo || '-' }}</span>
              </div>
              <div class="info-row">
                <span class="label">{{
                  sourceType == 'jobBom' ? '数量' : '本批数量'
                }}</span>
                <span class="value">{{ item.feedQuantity || '-' }}</span>
              </div>
              <template v-if="sourceType !== 'jobBom'">
                <div class="info-row">
                  <span class="label">原厂批号</span>
                  <span class="value">{{ item.originalBatchNo || '-' }}</span>
                </div>
                <div class="info-row">
                  <span class="label">原厂合格证号</span>
                  <span class="value">{{
                    item.originalCertificateNo || '-'
                  }}</span>
                </div>
              </template>
            </div>
            <div class="qr-area">
              <div class="qr-box">
                <img
                  v-if="item.qrCodeUrl"
                  :src="item.qrCodeUrl"
                  alt="二维码"
                  class="qr-img"
                />
              </div>
            </div>
          </div>
        </div>
      </div>

      <div class="encoding-content" v-if="mode === 'barcode'">
        <div
          v-for="(item, index) in batchList"
          :key="'bar-' + index"
          class="barcode-card"
        >
          <div class="barcode-card-header">
            <span class="barcode-card-title">
              {{ item.partName || item.productName || '产品标识' }}
            </span>
          </div>
          <div class="barcode-meta">
            <div class="meta-item">
              <span class="meta-label">型号：</span>
              <span class="meta-value">{{ item.model || '-' }}</span>
            </div>
            <div class="meta-item">
              <span class="meta-label">规格：</span>
              <span class="meta-value">{{ item.specification || '-' }}</span>
            </div>
          </div>
          <div class="barcode-wrap">
            <canvas :ref="'barcode_' + index"></canvas>
          </div>
          <div class="barcode-raw" v-if="item.codeStr !== item.barcodeValue">
            {{ item.codeStr }}
          </div>
        </div>
      </div>
    </div>

    <div slot="footer">
      <el-button size="small" @click="printPreview">打印预览</el-button>
      <el-button size="small" @click="close">关闭</el-button>
    </div>
  </ele-modal>
</template>

<script>
  import QRCode from 'qrcode';
  import JsBarcode from 'jsbarcode';

  export default {
    name: 'EncodingDialog80x40',
    data() {
      return {
        visible: false,
        workOrderList: [],
        batchList: [],
        mode: 'qrcode',
        sourceType: 'default'
      };
    },
    methods: {
      open(workOrders, type) {
        this.visible = true;
        this.mode = 'qrcode';
        this.sourceType = type || 'default';
        this.workOrderList = workOrders || [];
        this.buildBatchList();
      },

      close() {
        this.visible = false;
        this.batchList = [];
      },

      buildBatchList() {
        const isJobBom = this.sourceType === 'jobBom';
        const sanitize = (v) => String(v == null ? '' : v).replace(/;/g, '');
        this.batchList = this.workOrderList.map((item) => {
          const productCode = item.topCategoryCode || '';
          const partCode = isJobBom
            ? item.categoryCode || ''
            : item.productCode || '';
          const partName = isJobBom ? item.name || '' : item.productName || '';
          const batchNo = item.batchNo || '';
          const feedQuantity = isJobBom
            ? (item.feedQuantity || item.quantity || item.planQuantity || '') +
              (item.unit || '')
            : (item.formingNum || '') + (item.unit || '');
          const originalBatchNo = item.originalBatchNo || '';
          const certificateNo = item.certificateNo || '';
          const originalCertificateNo = item.originalCertificateNo || '';
          const codeStr = isJobBom
            ? [
                item.categoryCode,
                item.batchNo,
                item.extInfo && item.extInfo.engrave
              ]
                .filter(Boolean)
                .join('-')
            : [
                productCode,
                partCode,
                partName,
                batchNo,
                originalBatchNo,
                certificateNo,
                originalCertificateNo,
                feedQuantity
              ]
                .map(sanitize)
                .join(';');
          const barcodeValue = isJobBom
            ? codeStr
            : [productCode, partCode, batchNo, certificateNo]
                .map((v) =>
                  String(v == null ? '' : v).replace(/[^\x20-\x7E]/g, '')
                )
                .filter(Boolean)
                .join('-') ||
              productCode ||
              partCode ||
              'NA';
          return {
            productCode,
            productName: item.topCategoryName || '',
            partCode,
            partName,
            batchNo,
            feedQuantity,
            codeStr,
            barcodeValue,
            qrCodeUrl: '',
            model: isJobBom
              ? item.modelType || item.model || ''
              : item.model || '',
            specification: item.specification || '',
            engrave: item.extInfo && item.extInfo.engrave,
            originalBatchNo,
            certificateNo,
            originalCertificateNo
          };
        });

        if (this.mode === 'qrcode') {
          this.generateQRCodes();
        } else {
          this.$nextTick(() => {
            this.generateBarcodes();
          });
        }
      },

      generateQRCodes() {
        this.batchList.forEach((item, index) => {
          const content = item.codeStr || item.productCode || String(index);
          QRCode.toDataURL(content, { width: 200, margin: 1 })
            .then((url) => {
              this.$set(this.batchList[index], 'qrCodeUrl', url);
            })
            .catch((err) => {
              console.error('QRCode生成失败:', err);
            });
        });
      },

      generateBarcodes() {
        this.batchList.forEach((item, index) => {
          const refKey = 'barcode_' + index;
          const canvasArr = this.$refs[refKey];
          if (canvasArr && canvasArr[0]) {
            const content = item.barcodeValue || item.productCode || 'NA';
            try {
              JsBarcode(canvasArr[0], content, {
                format: 'CODE128',
                width: 2,
                height: 50,
                displayValue: false,
                margin: 4,
                background: '#ffffff',
                lineColor: '#1f2329'
              });
            } catch (err) {
              console.error('Barcode生成失败:', err, content);
            }
          }
        });
      },

      refresh() {
        this.buildBatchList();
      },

      batchEncoding() {
        this.mode = 'qrcode';
        this.$nextTick(() => {
          this.generateQRCodes();
        });
      },

      batchBarcodeEncoding() {
        this.mode = 'barcode';
        this.$nextTick(() => {
          this.generateBarcodes();
        });
      },

      printPreview() {
        const printContent = this.$el.querySelector('.encoding-content');
        if (!printContent) return;

        let html = printContent.innerHTML;

        if (this.mode === 'barcode') {
          const container = document.createElement('div');
          container.innerHTML = html;
          const canvases = this.$el.querySelectorAll(
            '.encoding-content canvas'
          );
          const imgPlaceholders = container.querySelectorAll('canvas');
          canvases.forEach((canvas, i) => {
            if (imgPlaceholders[i]) {
              const img = document.createElement('img');
              img.src = canvas.toDataURL('image/png');
              img.style.width = '72mm';
              img.style.height = '14mm';
              imgPlaceholders[i].parentNode.replaceChild(
                img,
                imgPlaceholders[i]
              );
            }
          });
          html = container.innerHTML;
        }

        const printWindow = window.open('', '_blank');
        printWindow.document.write(`
          <html>
            <head>
              <title>打码打印预览</title>
              <style>
                @page {
                  size: 80mm 40mm;
                  margin: 0;
                }
                * { box-sizing: border-box; margin: 0; padding: 0; }
                html, body {
                  font-family: 'Microsoft Yahei', Arial, sans-serif;
                  width: 80mm;
                  margin: 0;
                  padding: 0;
                  color: #1f2329;
                  -webkit-print-color-adjust: exact;
                  print-color-adjust: exact;
                }
                .encoding-content { width: 80mm; }
                .batch-card {
                  width: 80mm;
                  height: 40mm;
                  padding: 1.5mm;
                  page-break-after: always;
                  page-break-inside: avoid;
                  break-inside: avoid;
                  overflow: hidden;
                  display: flex;
                  flex-direction: column;
                }
                .batch-card:last-child { page-break-after: avoid; }
                .batch-card > .card-header,
                .batch-card > .card-body {
                  width: 100%;
                }
                .card-header {
                  min-height: 5mm;
                  background: #1f2329;
                  color: #fff;
                  display: flex;
                  align-items: center;
                  justify-content: space-between;
                  padding: 0.5mm 2mm;
                  border-radius: 0.8mm 0.8mm 0 0;
                  flex-shrink: 0;
                }
                .card-header .card-title {
                  flex: 1;
                  font-size: 7pt;
                  font-weight: 700;
                  letter-spacing: 0.2mm;
                  line-height: 1.2;
                  word-break: break-all;
                  white-space: nowrap;
                  overflow: hidden;
                  text-overflow: ellipsis;
                }
                .card-body {
                  flex: 1;
                  border: 1px solid #000;
                  border-top: none;
                  border-radius: 0 0 0.8mm 0.8mm;
                  display: flex;
                  align-items: stretch;
                  overflow: hidden;
                }
                .info-area {
                  flex: 1;
                  display: flex;
                  flex-direction: column;
                  border-right: 1px solid #000;
                }
                .info-row {
                  flex: 1;
                  display: flex;
                  align-items: center;
                  border-bottom: 1px dashed #c0c4cc;
                  padding: 0 1.2mm;
                  min-height: 0;
                }
                @media print {
                  .info-row {
                    border-bottom: none;
                    background-image: linear-gradient(
                      to right,
                      #000 50%,
                      transparent 50%
                    );
                    background-size: 2px 1px;
                    background-repeat: repeat-x;
                    background-position: left bottom;
                  }
                  .info-row:last-child { background-image: none; }
                }
                .info-row:last-child { border-bottom: none; }
                .info-row .label {
                  width: 16mm;
                  font-size: 5pt;
                  color: #606266;
                  flex-shrink: 0;
                  line-height: 1.1;
                  height: 100%;
                  display: flex;
                  align-items: center;
                  background-image: linear-gradient(
                    to bottom,
                    #000 50%,
                    transparent 50%
                  );
                  background-size: 1px 2px;
                  background-repeat: repeat-y;
                  background-position: right top;
                }
                .info-row .value {
                  flex: 1;
                  font-size: 5pt;
                  font-weight: 600;
                  color: #1f2329;
                  word-break: break-all;
                  line-height: 1.1;
                  padding-left: 1.2mm;
                }
                .qr-area {
                  width: 22mm;
                  display: flex;
                  flex-direction: column;
                  align-items: center;
                  justify-content: center;
                  padding: 0.8mm;
                  background: #fafbfc;
                }
                .qr-box {
                  width: 18mm;
                  height: 18mm;
                  padding: 0.4mm;
                  background: #fff;
                  border: 1px solid #000;
                  border-radius: 0.5mm;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                }
                .qr-img { width: 100%; height: 100%; }
                .barcode-card {
                  width: 80mm;
                  height: 40mm;
                  padding: 0;
                  display: flex;
                  flex-direction: column;
                  page-break-after: always;
                  overflow: hidden;
                  border: 1px solid #000;
                  border-radius: 0.8mm;
                }
                .barcode-card:last-child { page-break-after: avoid; }
                .barcode-card-header {
                  display: flex;
                  align-items: center;
                  justify-content: space-between;
                  padding: 0.8mm 2mm;
                  background: #1f2329;
                  color: #fff;
                }
                .barcode-card-title {
                  flex: 1;
                  font-size: 7pt;
                  font-weight: 700;
                  letter-spacing: 0.2mm;
                  text-align: left;
                  word-break: break-all;
                  white-space: nowrap;
                  overflow: hidden;
                  text-overflow: ellipsis;
                }
                .barcode-meta {
                  display: flex;
                  justify-content: center;
                  gap: 4mm;
                  padding: 1mm 2mm 0.5mm;
                  flex-wrap: wrap;
                  font-size: 6.5pt;
                }
                .barcode-meta .meta-item { display: inline-flex; align-items: center; }
                .barcode-meta .meta-label { color: #606266; margin-right: 0.6mm; }
                .barcode-meta .meta-value { color: #1f2329; font-weight: 600; }
                .barcode-wrap { margin: 0 auto; text-align: center; padding: 0.5mm; }
                .barcode-wrap img { width: 72mm; height: 14mm; image-rendering: pixelated; }
                .barcode-raw {
                  margin-top: 0.5mm;
                  padding: 0 2mm;
                  font-size: 5.5pt;
                  color: #606266;
                  text-align: center;
                  word-break: break-all;
                  line-height: 1.2;
                }
              </style>
            </head>
            <body>${html}</body>
          </html>
        `);
        printWindow.document.close();
        printWindow.onload = function () {
          setTimeout(() => {
            printWindow.print();
          }, 300);
        };
      }
    }
  };
</script>

<style lang="scss" scoped>
  .encoding-dialog {
    .encoding-header {
      display: flex;
      align-items: center;
      margin-bottom: 16px;
      gap: 10px;
    }

    .encoding-content {
      max-height: 60vh;
      overflow-y: auto;
    }

    .batch-card {
      margin-bottom: 16px;
      border-radius: 6px;
      overflow: hidden;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
      border: 1px solid #ebeef5;
      background: #fff;

      .card-header {
        min-height: 32px;
        background: linear-gradient(90deg, #1f2329 0%, #2c3138 100%);
        color: #fff;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 6px 12px;

        .card-title {
          flex: 1;
          font-size: 13px;
          font-weight: 600;
          letter-spacing: 1px;
          line-height: 1.4;
          word-break: break-all;
        }
      }

      .card-body {
        display: flex;
        align-items: stretch;
      }

      .info-area {
        flex: 1;
        display: flex;
        flex-direction: column;
        border-right: 1px dashed #dcdfe6;
      }

      .info-row {
        flex: 1;
        display: flex;
        align-items: center;
        padding: 4px 8px;
        border-bottom: 1px solid #f2f3f5;
        min-height: 22px;

        &:last-child {
          border-bottom: none;
        }

        .label {
          width: 70px;
          font-size: 10px;
          color: #909399;
          flex-shrink: 0;
        }

        .value {
          flex: 1;
          font-size: 10px;
          color: #1f2329;
          font-weight: 500;
          word-break: break-all;
        }
      }

      .qr-area {
        width: 110px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 8px;
        background: #fafbfc;

        .qr-box {
          width: 86px;
          height: 86px;
          padding: 4px;
          background: #fff;
          border: 1px solid #ebeef5;
          border-radius: 4px;
          display: flex;
          align-items: center;
          justify-content: center;

          .qr-img {
            width: 100%;
            height: 100%;
          }
        }
      }
    }

    .barcode-card {
      position: relative;
      border: 1px solid #ebeef5;
      border-radius: 8px;
      padding: 0 0 16px;
      margin-bottom: 16px;
      text-align: center;
      background: #fff;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
      overflow: hidden;

      .barcode-card-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 8px 14px;
        background: linear-gradient(90deg, #1f2329 0%, #2c3138 100%);
        color: #fff;

        .barcode-card-title {
          font-size: 14px;
          font-weight: 600;
          letter-spacing: 1px;
          text-align: left;
          flex: 1;
          word-break: break-all;
        }
      }

      .barcode-meta {
        display: flex;
        justify-content: center;
        gap: 20px;
        padding: 10px 14px 4px;
        flex-wrap: wrap;

        .meta-item {
          display: flex;
          align-items: center;
          font-size: 12px;

          .meta-label {
            color: #909399;
            margin-right: 6px;
          }

          .meta-value {
            color: #1f2329;
            font-weight: 600;
          }
        }
      }

      .barcode-wrap {
        margin: 6px auto 4px;
        display: flex;
        justify-content: center;
        padding: 4px 12px;
        background: #fff;

        canvas {
          max-width: 100%;
        }
      }

      .barcode-raw {
        margin-top: 4px;
        padding: 0 14px;
        font-size: 11px;
        color: #909399;
        word-break: break-all;
        line-height: 1.5;
      }
    }
  }
</style>
