<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;"
      ></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: 30      // 单次导出数量
      },

      // 任务规划数据
      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;
    },

    // ========== 任务规划核心逻辑 ==========
    // 1. 获取总数据量，初始化任务规划
    async fetchTotalData() {
      try {
        const res = await listMaterialCoil({
          status: 0,
          dataType: 1,
          materialType: '成品',
          itemType: 'product',
          selectType: 'raw_material',
          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('获取数据总量失败，请刷新重试');
      }
    },

    // 2. 初始化任务列表
    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' };
      // 重置PDF实例
      this.pdfDoc = null;
    },

    // 3. 修改pageSize后重新规划任务
    replanTask() {
      // 先校验参数
      this.validatePageSize();
      // 重新计算总任务数
      this.taskPlan.totalTask = Math.ceil(this.taskPlan.totalCount / this.config.pageSize);
      // 重新初始化任务列表
      this.initTaskList();
      Message.success(`已重新规划任务！单次导出${this.config.pageSize}条，总计${this.taskPlan.totalTask}个任务`);
    },

    // 4. 更新任务状态
    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);
    },

    // ========== 核心导出逻辑 ==========
    // 1. 批量导出所有未完成任务
    async handleExportAll() {
      if (this.exportLoading || this.hasRunningTask) return;
      if (this.taskPlan.totalCount === 0) {
        Message.warning('暂无外标签数据可导出');
        return;
      }

      try {
        this.exportLoading = true;
        // 初始化PDF文档（jsPDF默认创建1个空白页）
        this.pdfDoc = new jsPDF({ unit: 'mm', format: 'a4', orientation: 'portrait' });
        
        // 筛选出未完成的任务（pending/failed）
        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);
        }

        // 保存最终PDF
        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;
      }
    },

    // 2. 单独执行单个任务
    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', format: 'a4', orientation: 'portrait' });
        }

        // 执行单个任务核心逻辑
        await this.runSingleTaskCore(taskIdx);

        // 保存单个任务的PDF
        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;
      }
    },

    // 3. 单个任务执行核心逻辑（修复空白页关键）
    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);

        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,
        });

        // ========== 修复空白页核心逻辑 ==========
        // 关键规则：
        // 1. jsPDF实例化时默认创建1个空白页
        // 2. 第一个任务的第一个标签：直接使用默认空白页，不新增
        // 3. 第一个任务的非第一个标签：新增页面
        // 4. 非第一个任务的所有标签：新增页面
        const needAddPage = index > 0 || taskIdx > 1;
        if (needAddPage) {
          this.pdfDoc.addPage();
        }

        // 尺寸计算
        const domWidth = tempContainer.offsetWidth;
        const domHeight = tempContainer.offsetHeight;
        const domWidthMM = domWidth * (25.4 / 96);
        const domHeightMM = domHeight * (25.4 / 96);

        const a4Width = 210;
        const a4Height = 297;
        const margin = 5;
        const availableWidth = a4Width - 2 * margin;
        const availableHeight = a4Height - 2 * margin;

        const scaleRatio = Math.min(availableWidth / domWidthMM, availableHeight / domHeightMM);
        const finalWidth = domWidthMM * scaleRatio;
        const finalHeight = domHeightMM * scaleRatio;

        const x = (a4Width - finalWidth) / 2;
        const y = (a4Height - finalHeight) / 2;

        // 插入图片到PDF
        this.pdfDoc.addImage(canvas.toDataURL('image/png', 1.0), 'PNG', x, y, finalWidth, finalHeight);

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

      // 当前任务完成
      this.updateTaskStatus(taskIdx, 'completed', 100);
    },

    // ========== 辅助方法 ==========
    // 等待二维码/图片/字体加载
    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;

      // 等待二维码Canvas渲染
      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);
    },

    // 复制Canvas内容
    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);
    },

    // 等待DOM渲染
    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>