<template>
  <div class="barcode-3col-layout">
    <!-- 预览区 -->
    <div class="barcode-preview-col">
      <div class="preview-toolbar">
        <span>缩放：</span>
        <el-slider v-model="previewScale" :min="0.3" :max="2" :step="0.01" style="width:180px;display:inline-block;" />
        <span style="margin-left:8px;">{{ Math.round(previewScale*100) }}%</span>
      </div>
      <div class="iframe-wrapper" :style="iframeWrapperStyle">
        <iframe ref="previewIframe" class="barcode-iframe" frameborder="0" :style="iframeStyle"></iframe>
      </div>
    </div>
    <!-- 右侧控制+设置区 -->
    <div class="barcode-right-col">
      <!-- 控制区 -->
      <div class="barcode-control-bar">
        <el-tabs v-model="activeTab" stretch>
          <el-tab-pane label="排版设置" name="layout" />
          <el-tab-pane label="条码明细" name="detail" />
        </el-tabs>
      </div>
      <!-- 设置区 -->
      <div class="barcode-settings-panel">
        <el-form v-if="activeTab==='layout'" label-width="80px" size="small" label-position="top">
          <el-form-item label="每行数量">
            <el-input-number v-model="perRow" :min="1" :max="10" />
          </el-form-item>
          <el-form-item label="条码宽度">
            <el-input-number v-model="barcodeWidth" :min="60" :max="600" />
          </el-form-item>
          <el-form-item label="条码高度">
            <el-input-number v-model="barcodeHeight" :min="20" :max="200" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handlePrint">打印</el-button>
          </el-form-item>
        </el-form>
        <el-form v-else label-width="80px" size="small" label-position="top">
          <el-form-item label="条码明细">
            <el-table :data="barcodeConfigs" size="mini" border style="width:100%;">
              <el-table-column label="条码内容" prop="code" width="90" align="center" show-overflow-tooltip>
                <template slot-scope="scope">
                  <el-input type="textarea" v-model="scope.row.code" size="mini" :autosize="{ minRows: 1, maxRows: 3 }" placeholder="请输入条码内容" />
                </template>
              </el-table-column>
              <el-table-column label="数量" width="180" align="center">
                <template slot-scope="scope">
                  <el-input-number v-model.number="scope.row.count" :min="1" :max="100" size="mini" />
                </template>
              </el-table-column>
              <el-table-column label="下方文字模板" align="center">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.textTpl" size="mini" placeholder="如 箱号" />
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
// import JsBarcode from 'jsbarcode';
import QRCode from 'qrcode';
export default {
  name: 'BarcodeGenerator',
  props: {
    barcodes: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      perRow: 3,
      barcodeWidth: 180,
      barcodeHeight: 180, // 二维码建议宽高一致
      barcodeConfigs: [], // [{code, count, textTpl}]
      previewScale: 1, // 预览缩放比例
      activeTab: 'layout'
    };
  },
  computed: {
    expandedBarcodes() {
      let arr = [];
      this.barcodeConfigs.forEach(cfg => {
        for (let i = 0; i < (cfg.count || 1); i++) {
          arr.push(cfg.code);
        }
      });
      return arr;
    },
    expandedBarcodeTexts() {
      let arr = [];
      this.barcodeConfigs.forEach(cfg => {
        for (let i = 0; i < (cfg.count || 1); i++) {
          // 模板替换 {{n}}
          let text = cfg.textTpl || cfg.code;
          text = text.replace(/\{\{n\}\}/g, i + 1);
          arr.push(text);
        }
      });
      return arr;
    },
    expandedBarcodeTableData() {
      return this.expandedBarcodes.map((code, idx) => ({ code, text: this.expandedBarcodeTexts[idx] }));
    },
    barcodeRows() {
      const rows = [];
      const arr = this.expandedBarcodes;
      for (let i = 0; i < arr.length; i += this.perRow) {
        rows.push(arr.slice(i, i + this.perRow));
      }
      return rows;
    },
    barcodeTextRows() {
      const rows = [];
      const arr = this.expandedBarcodeTexts;
      for (let i = 0; i < arr.length; i += this.perRow) {
        rows.push(arr.slice(i, i + this.perRow));
      }
      return rows;
    },
    iframeStyle() {
      return {
        transform: `scale(${this.previewScale})`,
        'transform-origin': 'top left',
        width: '794px',
        height: 'auto',
        overflow: 'hidden',
        background: '#fff',
        border: 'none',
        display: 'block'
      };
    },
    iframeWrapperStyle() {
      return {
        width: `${794 * this.previewScale}px`,
        minHeight: `${1123 * this.previewScale}px`,
        overflow: 'auto',
        background: '#f8f8f8',
        padding: '16px 0',
        display: 'flex',
        justifyContent: 'center'
      };
    }
  },
  watch: {
    barcodes: {
      handler(newVal) {
        // 初始化barcodeConfigs
        this.barcodeConfigs = newVal.map((b, i) => {
          const old = this.barcodeConfigs[i] || {};
          return {
            code: b,
            count: old.count || 1,
            textTpl: typeof old.textTpl === 'string' ? old.textTpl : b
          };
        });
        this.$nextTick(this.renderPreviewIframe);
      },
      immediate: true
    },
    barcodeConfigs: {
      handler() { this.$nextTick(this.renderPreviewIframe); },
      deep: true
    },
    perRow() { this.$nextTick(this.renderPreviewIframe); },
    barcodeWidth() { this.$nextTick(this.renderPreviewIframe); },
    barcodeHeight() { this.$nextTick(this.renderPreviewIframe); },
    previewScale() {}
  },
  methods: {
    getBarcodeId(row, col) {
      return `barcode-canvas-${row}-${col}`;
    },
    getBarcodeText(row, col, code) {
      if (
        this.barcodeTextRows[row] &&
        typeof this.barcodeTextRows[row][col] !== 'undefined' &&
        this.barcodeTextRows[row][col] !== null &&
        this.barcodeTextRows[row][col] !== ''
      ) {
        return this.barcodeTextRows[row][col];
      }
      return code;
    },
    getPrintHtml() {
      let html = `
        <html>
          <head>
            <title>打印二维码</title>
            <style>
              body { margin: 0; padding: 0; background: #fff; }
              .barcode-list { width: 794px; margin: 0 auto; background: #fff; }
              .barcode-row { display: flex; margin-bottom: 24px; }
              .barcode-item { flex: 1; text-align: center; }
              .barcode-text { margin-top: 8px; font-size: 14px; }
              html, body { overflow-x: hidden; }
            </style>
          </head>
          <body>
            <div class="barcode-list">
      `;
      this.barcodeRows.forEach((row, rowIndex) => {
        html += '<div class="barcode-row">';
        row.forEach((code, colIndex) => {
          const id = this.getBarcodeId(rowIndex, colIndex);
          const text = this.getBarcodeText(rowIndex, colIndex, code);
          html += `<div class="barcode-item">
            <canvas id="${id}" width="${this.barcodeWidth}" height="${this.barcodeHeight}"></canvas>
            <div class="barcode-text">${text}</div>
          </div>`;
        });
        html += '</div>';
      });
      html += '</div></body></html>';
      return html;
    },
    async renderPreviewIframe() {
      const iframe = this.$refs.previewIframe;
      if (!iframe) return;
      const doc = iframe.contentDocument || iframe.contentWindow.document;
      doc.open();
      doc.write(this.getPrintHtml());
      doc.close();
      // 渲染二维码
      setTimeout(async () => {
        for (let rowIndex = 0; rowIndex < this.barcodeRows.length; rowIndex++) {
          const row = this.barcodeRows[rowIndex];
          for (let colIndex = 0; colIndex < row.length; colIndex++) {
            const code = row[colIndex];
            const id = this.getBarcodeId(rowIndex, colIndex);
            const el = doc.getElementById(id);
            if (el) {
              await QRCode.toCanvas(el, code, {
                width: this.barcodeWidth,
                height: this.barcodeHeight,
                margin: 0
              });
            }
          }
        }
      }, 50);
    },
    handlePrint() {
      const iframe = this.$refs.previewIframe;
      if (!iframe) return;
      iframe.contentWindow.focus();
      iframe.contentWindow.print();
    }
  },
  mounted() {
    this.barcodeConfigs = this.barcodes.map(b => ({ code: b, count: 1, textTpl: b }));
    this.renderPreviewIframe();
  }
};
</script>

<style scoped>
.barcode-3col-layout {
  display: flex;
  flex-direction: row;
  width: 100%;
  min-height: 400px;
}
.barcode-preview-col {
  flex: 1 1 0;
  min-width: 0;
  background: #fff;
  border-right: 1px solid #eee;
  padding: 24px 0 24px 24px;
  display: flex;
  flex-direction: column;
}
.barcode-right-col {
  width: 420px;
  min-width: 320px;
  display: flex;
  flex-direction: column;
  background: #fafbfc;
}
.barcode-control-bar {
  border-bottom: 1px solid #eee;
  background: #fafbfc;
  padding: 0 16px;
}
.barcode-settings-panel {
  flex: 1;
  padding: 16px;
  overflow: auto;
}
.preview-toolbar {
  margin-bottom: 12px;
  display: flex;
  align-items: center;
}
.iframe-wrapper {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  background: #f8f8f8;
  overflow-x: auto;
}
.barcode-iframe {
  width: 794px;
  min-height: 1123px;
  border: none;
  background: #fff;
  border-radius: 4px;
  display: block;
}
</style>
