<template>
  <div style="display: flex; gap: 20px; padding: 20px; width: 100%; box-sizing: border-box;">
    <!-- 左侧：原有导出功能区域 -->
    <div style="flex: 1; max-width: 700px;">
      <!-- 导出配置区域 -->
      <div class="config-container"
        style="margin-bottom: 20px; padding: 16px; border: 1px solid #e6e6e6; border-radius: 8px;">
        <div style="font-size: 16px; font-weight: 600; margin-bottom: 12px;">导出配置</div>

        <!-- 清晰度配置 -->
        <div class="config-item" style="margin-bottom: 10px; display: flex; align-items: center;">
          <label style="width: 120px; font-size: 14px; color: #333;">导出清晰度：</label>
          <input v-model.number="config.renderScale" type="number" min="1.0" max="4.0" step="0.1" style="width: 120px;"
            placeholder="如：1.5/2.0/3.0" @blur="validateRenderScale" />
          <span style="margin-left: 8px; font-size: 12px; color: #666;">
            范围：1.0-4.0（值越高越清晰，导出越慢）
          </span>
        </div>

        <!-- 单次导出数量配置 -->
        <div class="config-item" style="display: flex; align-items: center;">
          <label style="width: 120px; font-size: 14px; color: #333;">单次导出数量：</label>
          <input v-model.number="config.pageSize" type="number" min="1" max="200" style="width: 120px;"
            placeholder="如：10/50/100" @blur="validatePageSize" @change="replanTask" />
          <span style="margin-left: 8px; font-size: 12px; color: #666;">
            范围：1-200（建议不超过100，避免卡顿）
          </span>
        </div>
      </div>

      <!-- 导出按钮：批量导出所有未完成任务 -->
      <button @click="handleExportAll" :disabled="exportLoading || taskPlan.totalTask === 0 || hasRunningTask"
        style="padding: 8px 16px; cursor: pointer; margin-bottom: 20px;">
        {{ exportLoading ? '导出中...' : '批量导出所有未完成任务' }}
      </button>

      <!-- 单批导出进度条 -->
      <div v-if="showProgress" class="progress-container" style="margin-bottom: 20px; width: 100%; max-width: 600px;">
        <div class="progress-text" style="margin-bottom: 8px; font-size: 14px; color: #666;">
          当前批次进度：{{ currentIndex }}/{{ totalCount }} ({{ progress }}%)
        </div>
        <div class="progress-bar-bg"
          style="width: 100%; height: 8px; background: #f5f5f5; border-radius: 4px; overflow: hidden;">
          <div class="progress-bar" style="height: 100%; background: #409eff; transition: width 0.3s ease;"
            :style="{ width: `${progress}%` }"></div>
        </div>
      </div>

      <!-- 预览组件 -->
      <OuterTagPreview ref="outerTagPreview" :content="current" />
      <!-- 临时渲染容器【已修复：解决留白核心样式】 -->
      <div ref="tempTagContainer"
        style="position: fixed; top: -9999px; left: -9999px; z-index: -9999; width: 794px; padding: 10px; box-sizing: border-box; overflow: hidden !important;">
      </div>
    </div>

    <!-- 右侧：任务规划+进度展示区域 -->
    <div style="flex: 0 0 400px; padding: 16px; border: 1px solid #e6e6e6; border-radius: 8px; height: fit-content;">
      <!-- 任务概览 -->
      <div style="font-size: 16px; font-weight: 600; margin-bottom: 16px;">
        任务规划（总数量：{{ taskPlan.totalCount }}）
      </div>

      <!-- 任务统计 -->
      <div style="display: flex; gap: 16px; margin-bottom: 20px; font-size: 14px;">
        <div>
          <div style="color: #666; margin-bottom: 4px;">总任务数</div>
          <div style="font-size: 20px; font-weight: 600; color: #333;">{{ taskPlan.totalTask }}</div>
        </div>
        <div>
          <div style="color: #666; margin-bottom: 4px;">已完成</div>
          <div style="font-size: 20px; font-weight: 600; color: #67c23a;">{{ taskPlan.completedTask }}</div>
        </div>
        <div>
          <div style="color: #666; margin-bottom: 4px;">进行中</div>
          <div style="font-size: 20px; font-weight: 600; color: #409eff;">{{ taskPlan.runningTask }}</div>
        </div>
      </div>

      <!-- 总进度条 -->
      <div style="margin-bottom: 20px;">
        <div style="display: flex; justify-content: space-between; font-size: 12px; color: #666; margin-bottom: 8px;">
          <span>整体导出进度</span>
          <span>{{ taskPlan.totalProgress }}%</span>
        </div>
        <div style="width: 100%; height: 8px; background: #f5f5f5; border-radius: 4px; overflow: hidden;">
          <div style="height: 100%; background: #67c23a; transition: width 0.3s ease;"
            :style="{ width: `${taskPlan.totalProgress}%` }"></div>
        </div>
      </div>

      <!-- 当前任务详情 -->
      <div style="margin-bottom: 20px; padding: 12px; background: #f0f9ff; border-radius: 6px;">
        <div style="font-size: 14px; font-weight: 600; color: #333; margin-bottom: 8px;">当前任务详情</div>
        <div v-if="currentTask.idx > 0" style="font-size: 13px; line-height: 1.6;">
          <div>任务序号：{{ currentTask.idx }}/{{ taskPlan.totalTask }}</div>
          <div>处理范围：{{ currentTask.startNum }} - {{ currentTask.endNum }} 条</div>
          <div>当前进度：{{ currentTask.progress }}%</div>
          <div>状态：<span :style="{ color: currentTask.statusColor }">{{ currentTask.statusText }}</span></div>
        </div>
        <div v-else style="font-size: 13px; color: #666;">暂无进行中的任务</div>
      </div>

      <!-- 任务列表 -->
      <div style="max-height: 400px; overflow-y: auto;">
        <div v-for="(task, idx) in taskList" :key="idx"
          style="padding: 10px; border: 1px solid #e6e6e6; border-radius: 6px; margin-bottom: 8px;" :style="{
            borderColor: task.status === 'running' ? '#409eff' : task.status === 'completed' ? '#67c23a' : '#e6e6e6',
            background: task.status === 'running' ? '#f0f9ff' : 'transparent'
          }">
          <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;">
            <span style="font-size: 14px; font-weight: 500;">任务 {{ idx + 1 }}</span>
            <span :style="{ color: task.statusColor }">{{ task.statusText }}</span>
          </div>
          <div style="font-size: 12px; color: #666; margin-bottom: 6px;">
            处理范围：{{ task.startNum }} - {{ task.endNum }} 条
          </div>
          <div
            style="width: 100%; height: 6px; background: #f5f5f5; border-radius: 3px; overflow: hidden; margin-bottom: 8px;">
            <div style="height: 100%; transition: width 0.3s ease;" :style="{
              width: `${task.progress}%`,
              background: task.status === 'running' ? '#409eff' : task.status === 'completed' ? '#67c23a' : '#ccc'
            }"></div>
          </div>
          <!-- 单个任务执行按钮 -->
          <button @click="handleRunSingleTask(task.idx)"
            :disabled="exportLoading || task.status === 'running' || task.status === 'completed'"
            style="padding: 4px 8px; font-size: 12px; border: none; border-radius: 4px; cursor: pointer; background: #409eff; color: white;">
            {{ task.status === 'failed' ? '重新执行' : '执行任务' }}
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import OuterTagPreview from './LabelRender/OuterTagPreview.vue';
import { listMaterialCoil } from "@/api/wms/coil";
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
import { Message } from 'element-ui';

export default {
  name: 'ToolPanel',
  components: {
    OuterTagPreview
  },
  data() {
    return {
      list: [],          // 当前批次数据
      current: {},       // 当前预览数据
      exportLoading: false, // 全局导出加载状态
      showProgress: false,  // 单批进度条显示
      progress: 0,       // 单批进度百分比
      currentIndex: 0,   // 单批当前处理索引
      totalCount: 0,     // 当前批次总数

      // 导出配置
      config: {
        renderScale: 1.2, // 清晰度
        pageSize: 50      // 单次导出数量
      },

      // 任务规划数据
      taskPlan: {
        totalCount: 0,    // 总数据量（接口返回的res.total）
        totalTask: 0,     // 总任务数（Math.ceil(totalCount/pageSize)）
        completedTask: 0, // 已完成任务数
        runningTask: 0,   // 进行中任务数
        totalProgress: 0  // 整体进度百分比
      },
      taskList: [],       // 任务列表（每个任务的详情）
      currentTask: {      // 当前任务详情
        idx: 0,           // 任务序号
        startNum: 0,      // 起始条数
        endNum: 0,        // 结束条数
        progress: 0,      // 当前任务进度
        status: 'pending',// 状态：pending/running/completed/failed
        statusText: '未开始',
        statusColor: '#909399'
      },
      pdfDoc: null, // 全局PDF实例，支持追加内容
    }
  },
  computed: {
    // 是否有任务正在执行
    hasRunningTask() {
      return this.taskPlan.runningTask > 0;
    }
  },
  mounted() {
    this.fetchTotalData(); // 先获取总数量，规划任务
  },
  methods: {
    // ========== 配置校验 ==========
    validateRenderScale() {
      let scale = this.config.renderScale;
      if (!scale || isNaN(scale)) {
        this.config.renderScale = 1.5;
        Message.warning('清晰度请输入1.0-4.0之间的数字，已重置为默认值1.5');
        return;
      }
      if (scale < 1.0) this.config.renderScale = 1.0;
      else if (scale > 4.0) this.config.renderScale = 4.0;
    },

    validatePageSize() {
      let size = this.config.pageSize;
      if (!size || isNaN(size) || size < 1) {
        this.config.pageSize = 10;
        Message.warning('每页数量请输入1-200之间的正整数，已重置为默认值10');
        return;
      }
      if (size > 200) this.config.pageSize = 200;
    },

    // ========== 任务规划核心逻辑 ==========
    async fetchTotalData() {
      try {
        const res = await listMaterialCoil({
          status: 0,
          dataType: 1,
          materialType: '成品',
          itemType: 'product',
          selectType: 'raw_material',
          itemName: '冷硬卷',
          pageSize: 1,    // 仅获取总数量，pageSize设为1
          pageNum: 1
        });

        // 初始化任务规划
        this.taskPlan.totalCount = res.total || 0;
        this.taskPlan.totalTask = Math.ceil(this.taskPlan.totalCount / this.config.pageSize);
        this.initTaskList(); // 初始化任务列表
      } catch (err) {
        console.error('获取总数据量失败：', err);
        Message.error('获取数据总量失败，请刷新重试');
      }
    },

    initTaskList() {
      this.taskList = [];
      for (let i = 0; i < this.taskPlan.totalTask; i++) {
        const startNum = i * this.config.pageSize + 1;
        const endNum = Math.min((i + 1) * this.config.pageSize, this.taskPlan.totalCount);
        this.taskList.push({
          idx: i + 1,          // 任务序号
          startNum,            // 起始条数
          endNum,              // 结束条数
          progress: 0,         // 任务进度
          status: 'pending',   // 状态：pending/running/completed/failed
          statusText: '未开始',
          statusColor: '#909399'
        });
      }
      this.taskPlan.completedTask = 0;
      this.taskPlan.runningTask = 0;
      this.taskPlan.totalProgress = 0;
      this.currentTask = { idx: 0, startNum: 0, endNum: 0, progress: 0, status: 'pending', statusText: '未开始', statusColor: '#909399' };
      this.pdfDoc = null;
    },

    replanTask() {
      this.validatePageSize();
      this.taskPlan.totalTask = Math.ceil(this.taskPlan.totalCount / this.config.pageSize);
      this.initTaskList();
      Message.success(`已重新规划任务！单次导出${this.config.pageSize}条，总计${this.taskPlan.totalTask}个任务`);
    },

    updateTaskStatus(taskIdx, status, progress = 0) {
      const task = this.taskList[taskIdx - 1];
      if (!task) return;

      task.status = status;
      task.progress = progress;
      switch (status) {
        case 'running':
          task.statusText = '进行中';
          task.statusColor = '#409eff';
          this.currentTask = { ...task };
          break;
        case 'completed':
          task.statusText = '已完成';
          task.statusColor = '#67c23a';
          break;
        case 'failed':
          task.statusText = '失败';
          task.statusColor = '#f56c6c';
          break;
        default:
          task.statusText = '未开始';
          task.statusColor = '#909399';
      }

      this.taskPlan.completedTask = this.taskList.filter(t => t.status === 'completed').length;
      this.taskPlan.runningTask = this.taskList.filter(t => t.status === 'running').length;
      const totalCompleted = this.taskList.reduce((sum, t) => sum + (t.progress / 100) * (t.endNum - t.startNum + 1), 0);
      this.taskPlan.totalProgress = Math.round((totalCompleted / this.taskPlan.totalCount) * 100);
    },

    // ========== 核心导出逻辑 ==========
    async handleExportAll() {
      if (this.exportLoading || this.hasRunningTask) return;
      if (this.taskPlan.totalCount === 0) {
        Message.warning('暂无外标签数据可导出');
        return;
      }

      try {
        this.exportLoading = true;
        // 初始化PDF 动态尺寸【核心修改】
        this.pdfDoc = new jsPDF({
          unit: 'mm',
          orientation: 'portrait',
          format: [0, 0]
        });

        const uncompletedTasks = this.taskList.filter(t => t.status !== 'completed');
        if (uncompletedTasks.length === 0) {
          Message.info('所有任务均已完成，无需导出');
          this.exportLoading = false;
          return;
        }

        for (const task of uncompletedTasks) {
          await this.runSingleTaskCore(task.idx);
        }

        const fileName = `外标签批量导出_${new Date().toLocaleString().replace(/[/: ]/g, '-')}.pdf`;
        this.pdfDoc.save(fileName);
        Message.success(`PDF批量导出成功！共完成${uncompletedTasks.length}个任务，总计${this.taskPlan.totalCount}条数据`);

      } catch (err) {
        console.error('批量导出失败：', err);
        Message.error('批量导出失败，请查看控制台');
      } finally {
        this.exportLoading = false;
        this.showProgress = false;
        this.progress = 0;
        this.currentIndex = 0;
      }
    },

    async handleRunSingleTask(taskIdx) {
      if (this.exportLoading || this.hasRunningTask) {
        Message.warning('有任务正在执行中，请等待完成后再操作');
        return;
      }

      try {
        this.exportLoading = true;
        // 初始化PDF 动态尺寸【核心修改】
        if (!this.pdfDoc) {
          this.pdfDoc = new jsPDF({
            unit: 'mm',
            orientation: 'portrait',
            format: [0, 0]
          });
        }

        await this.runSingleTaskCore(taskIdx);

        const fileName = `外标签任务${taskIdx}_导出_${new Date().toLocaleString().replace(/[/: ]/g, '-')}.pdf`;
        this.pdfDoc.save(fileName);
        Message.success(`任务${taskIdx}导出成功！处理范围：${this.taskList[taskIdx - 1].startNum}-${this.taskList[taskIdx - 1].endNum}条`);

      } catch (err) {
        console.error(`任务${taskIdx}执行失败：`, err);
        Message.error(`任务${taskIdx}执行失败，请查看控制台`);
        this.updateTaskStatus(taskIdx, 'failed');
      } finally {
        this.exportLoading = false;
        this.showProgress = false;
        this.progress = 0;
        this.currentIndex = 0;
      }
    },

    // 单个任务执行核心逻辑【修复后：彻底解决多页尺寸异常】
    async runSingleTaskCore(taskIdx) {
      this.updateTaskStatus(taskIdx, 'running', 0);

      const pageNum = taskIdx;
      const res = await listMaterialCoil({
        status: 0,
        dataType: 1,
        materialType: '成品',
        itemType: 'product',
        selectType: 'raw_material',
        pageSize: this.config.pageSize,
        pageNum
      });

      this.list = res.rows || [];
      this.totalCount = this.list.length;
      if (this.totalCount === 0) {
        this.updateTaskStatus(taskIdx, 'completed', 100);
        return;
      }

      this.showProgress = true;
      this.currentIndex = 0;
      this.progress = 0;

      for (let index = 0; index < this.list.length; index++) {
        this.current = this.list[index];
        await this.waitForDOMRender();

        const previewComponent = this.$refs.outerTagPreview;
        await this.waitForAllResources(previewComponent.$el);

        // 克隆DOM到临时容器
        const tempContainer = this.$refs.tempTagContainer;
        const renderedDOM = previewComponent.$el.cloneNode(true);
        tempContainer.innerHTML = '';
        tempContainer.appendChild(renderedDOM);

        // 修复克隆DOM丢失样式问题
        const labelDom = tempContainer.querySelector('.label-container');
        if (labelDom) {
          labelDom.style.width = '100%';
          labelDom.style.maxWidth = '100%';
          labelDom.style.boxSizing = 'border-box';
          labelDom.style.overflow = 'hidden';
        }

        await this.waitForDOMRender();
        this.copyCanvasContent(previewComponent.$el, tempContainer);

        if (!tempContainer.firstChild) {
          console.warn(`任务${taskIdx}第${index + 1}个标签DOM为空`, this.list[index]);
          this.updateProgress(index + 1);
          continue;
        }

        // 生成高清Canvas
        const canvas = await html2canvas(tempContainer, {
          scale: this.config.renderScale,
          backgroundColor: '#ffffff',
          useCORS: true,
          width: tempContainer.offsetWidth,
          height: tempContainer.offsetHeight,
          windowWidth: tempContainer.offsetWidth * this.config.renderScale,
          windowHeight: tempContainer.offsetHeight * this.config.renderScale,
          logging: false,
          allowTaint: true,
          taintTest: false,
          scrollX: 0,
          scrollY: 0,
          letterRendering: true,
          imageTimeout: 10000
        });

        // 裁剪画布极细空白
        const cropCanvas = this.cropCanvasWhiteSpace(canvas);

        // 计算当前标签的实际尺寸（每次都重新计算，避免缓存错误）
        const canvasWidth = cropCanvas.width / this.config.renderScale;
        const canvasHeight = cropCanvas.height / this.config.renderScale;
        const imgWidthMM = canvasWidth * (25.4 / 96);
        const imgHeightMM = canvasHeight * (25.4 / 96);
        const currentPageFormat = [imgWidthMM, imgHeightMM];

        // ========== 修复核心：正确设置PDF页面尺寸 ==========
        const totalPdfPages = this.pdfDoc.internal.getNumberOfPages();
        // 情况1：PDF是“初始空白页”（仅1页且尺寸为0）→ 修改初始页尺寸
        if (totalPdfPages === 1 && this.pdfDoc.internal.pageSize.getWidth() === 0) {
          this.pdfDoc.setPage(1);
          this.pdfDoc.internal.pageSize.setWidth(imgWidthMM);
          this.pdfDoc.internal.pageSize.setHeight(imgHeightMM);
        }
        // 情况2：其他所有情况→ 新增页面并使用当前标签的尺寸
        else {
          this.pdfDoc.addPage(currentPageFormat, 'portrait');
        }

        // 图片0边距填充当前页面
        const currentPageNum = this.pdfDoc.internal.getNumberOfPages();
        this.pdfDoc.setPage(currentPageNum); // 切换到当前页面
        this.pdfDoc.internal.pageSize.setWidth(imgWidthMM);
        this.pdfDoc.internal.pageSize.setHeight(imgHeightMM);
        this.pdfDoc.addImage(cropCanvas.toDataURL('image/png', 1.0), 'PNG', 0, 0, imgWidthMM, imgHeightMM);

        // 更新进度
        this.updateProgress(index + 1);
        this.updateTaskStatus(taskIdx, 'running', this.progress);
      }

      this.updateTaskStatus(taskIdx, 'completed', 100);
    },

    // ========== 新增+保留 所有辅助方法 ==========
    cropCanvasWhiteSpace(canvas) {
      const ctx = canvas.getContext('2d');
      const width = canvas.width;
      const height = canvas.height;
      const imageData = ctx.getImageData(0, 0, width, height);
      const data = imageData.data;

      let left = width, top = height, right = 0, bottom = 0;
      let pixelIndex, alpha;

      for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
          pixelIndex = (y * width + x) * 4;
          alpha = data[pixelIndex + 3];
          if (alpha > 0) {
            left = Math.min(left, x);
            top = Math.min(top, y);
            right = Math.max(right, x);
            bottom = Math.max(bottom, y);
          }
        }
      }

      const cropWidth = right - left + 1;
      const cropHeight = bottom - top + 1;
      if (cropWidth <= 0 || cropHeight <= 0) return canvas;

      const newCanvas = document.createElement('canvas');
      newCanvas.width = cropWidth;
      newCanvas.height = cropHeight;
      const newCtx = newCanvas.getContext('2d');
      newCtx.drawImage(canvas, left, top, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
      return newCanvas;
    },

    async waitForAllResources(element) {
      const images = element.querySelectorAll('img');
      const imgPromises = Array.from(images).map(img =>
        img.complete ? Promise.resolve() : new Promise(resolve => {
          img.onload = resolve;
          img.onerror = resolve;
        })
      );
      await Promise.all(imgPromises);
      await document.fonts.ready;
      await this.waitForQRCodeRender(element);
      await new Promise(resolve => setTimeout(resolve, 300));
    },

    async waitForQRCodeRender(element) {
      const qrCanvasList = element.querySelectorAll('canvas');
      if (qrCanvasList.length === 0) return;

      const qrLoadPromises = Array.from(qrCanvasList).map(canvas => {
        return new Promise(resolve => {
          const checkInterval = setInterval(() => {
            const ctx = canvas.getContext('2d');
            if (!ctx) {
              clearInterval(checkInterval);
              resolve();
              return;
            }
            const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            const hasContent = imageData.data.some(value => value !== 0);
            if (hasContent || Date.now() - (ctx.startTime || 0) > 2000) {
              clearInterval(checkInterval);
              resolve();
            }
          }, 100);
        });
      });
      await Promise.all(qrLoadPromises);
    },

    copyCanvasContent(sourceEl, targetEl) {
      const sourceCanvases = sourceEl.querySelectorAll('canvas');
      const targetCanvases = targetEl.querySelectorAll('canvas');
      sourceCanvases.forEach((canvas, index) => {
        const targetCanvas = targetCanvases[index];
        if (!targetCanvas) return;
        targetCanvas.width = canvas.width;
        targetCanvas.height = canvas.height;
        const targetCtx = targetCanvas.getContext('2d');
        targetCtx.drawImage(canvas, 0, 0);
      });
    },

    updateProgress(current) {
      this.currentIndex = current;
      this.progress = Math.round((current / this.totalCount) * 100);
    },

    waitForDOMRender(time = 300) {
      return new Promise(resolve => setTimeout(resolve, time));
    }
  }
}
</script>

<style scoped>
:deep(.label-container) {
  width: 100%;
  height: auto;
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-smooth: always;
}

:deep(canvas) {
  display: block;
  visibility: visible;
  opacity: 1;
}

.config-container {
  input {
    padding: 6px 12px;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    outline: none;
  }

  input:focus {
    border-color: #409eff;
  }
}

button {
  border: 1px solid #409eff;
  background: #409eff;
  color: white;
  border-radius: 4px;
  transition: all 0.3s;
}

button:disabled {
  background: #a0cfff;
  cursor: not-allowed;
}
</style>