<template>
  <div class="test-container">
    <div class="test-header">
      <h3>Word文档转换测试</h3>
      <div class="upload-section">
        <input type="file" @change="handleFileUpload" accept=".docx,.doc" />
        <div class="quick-actions" v-if="htmlContent">
          <button @click="directToPdf" class="action-btn">直接转为PDF并下载</button>
        </div>
      </div>
      <div class="convert-type">
        <label>
          <input type="radio" v-model="convertType" value="html" /> HTML
        </label>
        <label>
          <input type="radio" v-model="convertType" value="image" /> Image
        </label>
        <label>
          <input type="radio" v-model="convertType" value="pdf" /> PDF
        </label>
      </div>
    </div>

    <div v-if="loading" class="loading">
      <div class="spinner" />
      <div v-if="pdfProgress > 0" class="progress">
        转换进度: {{ pdfProgress }}%
      </div>
    </div>

    <div class="result-container">
      <!-- HTML显示 -->
      <div v-if="convertType === 'html'" class="result-section">
        <div id="html-container" class="html-result" v-html="htmlContent" />
        <div class="actions">
          <button @click="copyToClipboard">复制HTML</button>
          <button @click="convertHtmlToImage">转为图片</button>
          <button @click="convertHtmlToPdf">转为PDF</button>
        </div>
      </div>

      <!-- 图片显示 -->
      <div v-if="convertType === 'image'" class="result-section">
        <div v-if="imageUrl" class="image-result">
          <img :src="imageUrl" alt="转换后的图片" />
        </div>
        <div v-else class="no-result">请先转换为图片</div>
        <div class="actions" v-if="imageUrl">
          <button @click="downloadImage">下载图片</button>
        </div>
      </div>

      <!-- PDF显示 -->
      <div v-if="convertType === 'pdf'" class="result-section">
        <div v-if="pdfUrl" class="pdf-result">
          <iframe :src="pdfUrl" frameborder="0" />
        </div>
        <div v-else class="no-result">请先转换为PDF</div>
        <div class="actions" v-if="pdfUrl">
          <button @click="downloadPdf">下载PDF</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, onUnmounted } from 'vue';
import mammoth from 'mammoth';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import 'jspdf-autotable';

defineOptions({
  name: 'Test4Page',
});

const loading = ref<boolean>(false);
const convertType = ref<'html' | 'image' | 'pdf'>('html');
const imageUrl = ref<string>('');
const pdfUrl = ref<string>('');
const pdfBytes = ref<Uint8Array | null>(null);
const pdfDocument = ref<jsPDF | null>(null);
const pdfProgress = ref<number>(0);
const htmlContent = ref<string>('');
const fileData = ref<ArrayBuffer | null>(null);
const fileName = ref<string>('');

// 监听转换类型变化
watch(convertType, async (newType) => {
  if (newType === 'image' && htmlContent.value && !imageUrl.value) {
    // 如果切换到图片模式且已有HTML但没有图片，则生成图片
    await convertHtmlToImage();
  } else if (newType === 'pdf' && htmlContent.value && !pdfUrl.value) {
    // 如果切换到PDF模式且已有HTML但没有PDF，则生成PDF
    await convertHtmlToPdf();
  }
});

const handleFileUpload = async (event: Event) => {
  const input = event.target as HTMLInputElement;
  const file = input.files?.[0];
  
  if (!file) {
    alert('请选择文件');
    return;
  }
  
  fileName.value = file.name;
  pdfUrl.value = '';
  pdfBytes.value = null;
  htmlContent.value = '';
  fileData.value = null;
  
  try {
    // 读取Word文件
    const arrayBuffer = await file.arrayBuffer();
    fileData.value = arrayBuffer;
    
    // 根据当前选择的转换类型进行处理
    if (convertType.value === 'html') {
      await convertWordToHtml(arrayBuffer);
    } else if (convertType.value === 'image') {
      alert('请先选择HTML模式进行转换');
      convertType.value = 'html';
      await convertWordToHtml(arrayBuffer);
    } else if (convertType.value === 'pdf') {
      // 先转为HTML，再转为PDF
      await convertWordToHtml(arrayBuffer);
      // 等待DOM更新
      await new Promise(resolve => setTimeout(resolve, 500));
      await convertHtmlToPdf();
    }
  } catch (error) {
    console.error('文件处理失败:', error);
    alert('文件处理失败: ' + (error instanceof Error ? error.message : '未知错误'));
    loading.value = false;
  }
};

// Word转HTML方法
const convertWordToHtml = async (arrayBuffer: ArrayBuffer): Promise<void> => {
  try {
    loading.value = true;
    console.log('开始转换Word到HTML');
    
    // 使用mammoth转换为HTML
    const result = await mammoth.convertToHtml({ arrayBuffer });
    htmlContent.value = result.value;
    
    // 确保转换类型是html
    convertType.value = 'html';
    
    console.log('HTML转换完成');
    loading.value = false;
  } catch (error) {
    console.error('HTML转换失败:', error);
    alert('HTML转换失败: ' + (error instanceof Error ? error.message : '未知错误'));
    loading.value = false;
  }
};

// HTML转图片方法
const convertHtmlToImage = async (): Promise<boolean> => {
  try {
    loading.value = true;
    
    // 确保HTML已经渲染
    await new Promise(resolve => setTimeout(resolve, 300));
    
    // 必须确保HTML容器是可见的
    if (convertType.value !== 'html') {
      convertType.value = 'html';
      // 再次等待DOM更新
      await new Promise(resolve => setTimeout(resolve, 300));
    }
    
    const container = document.getElementById('html-container') as HTMLElement;
    if (!container) {
      console.error('找不到HTML容器');
      return false;
    }
    
    console.log('开始转换HTML到图片');
    
    // 获取原始容器高度和样式
    const originalHeight = container.offsetHeight;
    const originalScrollHeight = container.scrollHeight;
    
    console.log(`容器实际高度: ${originalHeight}px, 滚动高度: ${originalScrollHeight}px`);
    
    // 设置样式（临时）
    const originalStyles = {
      border: container.style.border,
      boxShadow: container.style.boxShadow,
      borderRadius: container.style.borderRadius,
      margin: container.style.margin,
      padding: container.style.padding,
      height: container.style.height,
      maxHeight: container.style.maxHeight,
      overflow: container.style.overflow
    };
    
    // 修改容器使其显示全部内容，不产生滚动条
    container.style.border = 'none';
    container.style.boxShadow = 'none';
    container.style.borderRadius = '0';
    container.style.margin = '0';
    container.style.padding = '0';
    container.style.height = `${originalScrollHeight}px`; // 关键修改：设置为滚动高度
    container.style.maxHeight = 'none'; // 移除最大高度限制
    container.style.overflow = 'visible'; // 确保内容不被裁剪
    
    // 让DOM更新样式
    await new Promise(resolve => setTimeout(resolve, 100));
    
    console.log('修改后容器高度:', container.offsetHeight);
    
    // 使用html2canvas转换，关键修改：禁用滚动处理
    const canvas = await html2canvas(container, {
      scale: 2, // 提高清晰度
      useCORS: true,
      allowTaint: true,
      backgroundColor: '#ffffff',
      windowHeight: container.scrollHeight, // 使用滚动高度
      height: container.scrollHeight, // 设置捕获高度为滚动高度
      width: container.offsetWidth,
      scrollY: 0, // 禁用滚动捕获
      scrollX: 0, // 禁用滚动捕获
      logging: true, // 开启日志便于调试
    });
    
    // 恢复容器原始样式
    container.style.border = originalStyles.border;
    container.style.boxShadow = originalStyles.boxShadow;
    container.style.borderRadius = originalStyles.borderRadius;
    container.style.margin = originalStyles.margin;
    container.style.padding = originalStyles.padding;
    container.style.height = originalStyles.height;
    container.style.maxHeight = originalStyles.maxHeight;
    container.style.overflow = originalStyles.overflow;
    
    console.log(`Canvas尺寸: ${canvas.width}x${canvas.height}`);
    
    // 转为图片URL
    imageUrl.value = canvas.toDataURL('image/png');
    
    // 切换到图片模式
    convertType.value = 'image';
    
    console.log('图片转换完成');
    loading.value = false;
    return true;
  } catch (error) {
    console.error('图片转换失败:', error);
    alert('图片转换失败: ' + (error instanceof Error ? error.message : '未知错误'));
    loading.value = false;
    return false;
  }
};

// HTML转PDF方法 - 简化版，不使用分页处理
const convertHtmlToPdf = async (): Promise<boolean> => {
  try {
    // 重置进度
    pdfProgress.value = 0;
    loading.value = true;
    
    // 确保HTML已经渲染
    await new Promise(resolve => setTimeout(resolve, 300));
    
    // 必须确保HTML容器是可见的
    if (convertType.value !== 'html') {
      convertType.value = 'html';
      // 再次等待DOM更新
      await new Promise(resolve => setTimeout(resolve, 300));
    }
    
    const container = document.getElementById('html-container') as HTMLElement;
    if (!container) {
      console.error('找不到HTML容器');
      return false;
    }
    
    console.log('开始转换HTML到PDF (简化方法)');
    pdfProgress.value = 10;
    
    // 获取原始容器高度和样式
    const originalHeight = container.offsetHeight;
    const originalScrollHeight = container.scrollHeight;
    const originalWidth = container.offsetWidth;
    
    console.log(`容器实际高度: ${originalHeight}px, 滚动高度: ${originalScrollHeight}px, 宽度: ${originalWidth}px`);
    
    // 获取样式（临时）
    const originalStyles = {
      border: container.style.border,
      boxShadow: container.style.boxShadow,
      borderRadius: container.style.borderRadius,
      margin: container.style.margin,
      padding: container.style.padding,
      height: container.style.height,
      maxHeight: container.style.maxHeight,
      overflow: container.style.overflow
    };
    
    // 修改容器使其显示全部内容，不产生滚动条
    container.style.border = 'none';
    container.style.boxShadow = 'none';
    container.style.borderRadius = '0';
    container.style.margin = '0';
    container.style.padding = '0';
    container.style.height = `${originalScrollHeight}px`; // 关键修改：设置为滚动高度
    container.style.maxHeight = 'none'; // 移除最大高度限制
    container.style.overflow = 'visible'; // 确保内容不被裁剪
    
    // 让DOM更新样式
    await new Promise(resolve => setTimeout(resolve, 100));
    
    console.log('修改后容器高度:', container.offsetHeight);
    pdfProgress.value = 30;
    
    // 使用html2canvas捕获整个内容为一个大canvas
    const canvas = await html2canvas(container, {
      scale: 2, // 提高清晰度
      useCORS: true,
      allowTaint: true,
      backgroundColor: '#ffffff',
      windowHeight: container.scrollHeight, // 使用滚动高度
      height: container.scrollHeight, // 设置捕获高度为滚动高度
      width: container.offsetWidth,
      scrollY: 0, // 禁用滚动捕获
      scrollX: 0, // 禁用滚动捕获
      logging: true, // 开启日志便于调试
    });
    
    console.log(`Canvas尺寸: ${canvas.width}x${canvas.height}`);
    pdfProgress.value = 70;
    
    // 恢复容器原始样式
    container.style.border = originalStyles.border;
    container.style.boxShadow = originalStyles.boxShadow;
    container.style.borderRadius = originalStyles.borderRadius;
    container.style.margin = originalStyles.margin;
    container.style.padding = originalStyles.padding;
    container.style.height = originalStyles.height;
    container.style.maxHeight = originalStyles.maxHeight;
    container.style.overflow = originalStyles.overflow;
    
    // 创建PDF实例 - 使用自定义大小以适应内容
    const imgWidth = 550; // A4宽度左右，减去边距
    const imgHeight = canvas.height * imgWidth / canvas.width;
    
    // 创建合适尺寸的PDF
    const pdf = new jsPDF({
      orientation: imgHeight > imgWidth ? 'portrait' : 'landscape',
      unit: 'pt',
      format: [imgWidth + 40, imgHeight + 40] // 添加边距
    });
    
    // 存储PDF引用
    pdfDocument.value = pdf;
    
    // 将canvas添加到PDF
    pdf.addImage(
      canvas.toDataURL('image/jpeg', 0.95), 
      'JPEG', 
      20, // 左边距
      20, // 上边距
      imgWidth, 
      imgHeight
    );
    
    pdfProgress.value = 90;
    console.log('PDF页面生成完成');
    
    // 保存PDF (两种方式)
    try {
      // 方式1: 使用Blob URL (用于预览)
      const pdfOutput = pdf.output('blob');
      pdfUrl.value = URL.createObjectURL(pdfOutput);
      console.log('PDF Blob URL创建成功:', pdfUrl.value);
      
      // 方式2: 保存PDF字节 (用于直接下载)
      const pdfData = pdf.output('arraybuffer');
      pdfBytes.value = new Uint8Array(pdfData);
      console.log('PDF字节数据创建成功, 大小:', pdfBytes.value.length);
      
      // 转换为PDF模式
      convertType.value = 'pdf';
    } catch (error) {
      console.error('创建PDF URL失败:', error);
      alert('创建PDF URL失败: ' + (error instanceof Error ? error.message : '未知错误'));
    }
    
    console.log('PDF生成完成');
    pdfProgress.value = 100;
    
    loading.value = false;
    pdfProgress.value = 0; // 清除进度
    return true;
  } catch (error) {
    console.error('PDF转换失败:', error);
    alert('PDF转换失败: ' + (error instanceof Error ? error.message : '未知错误'));
    loading.value = false;
    pdfProgress.value = 0; // 清除进度
    return false;
  }
};

// 下载PDF
const downloadPdf = () => {
  console.log('开始下载PDF...');
  
  try {
    // 方法1: 使用存储的PDF文档直接保存 (优先)
    if (pdfDocument.value) {
      const outputFilename = (fileName.value ? fileName.value.replace(/\.[^/.]+$/, '') : 'document') + '.pdf';
      console.log('使用jsPDF直接保存文件:', outputFilename);
      pdfDocument.value.save(outputFilename);
      return;
    }
    
    // 方法2: 使用Blob URL (如果pdfDocument不可用)
    if (pdfUrl.value) {
      console.log('使用Blob URL下载PDF:', pdfUrl.value);
      const link = document.createElement('a');
      link.href = pdfUrl.value;
      link.download = (fileName.value ? fileName.value.replace(/\.[^/.]+$/, '') : 'document') + '.pdf';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      return;
    }
    
    // 没有可用的PDF数据
    console.error('没有PDF可下载');
    alert('没有PDF可下载');
  } catch (error) {
    console.error('PDF下载失败:', error);
    alert('PDF下载失败: ' + (error instanceof Error ? error.message : '未知错误'));
  }
};

// 下载图片
const downloadImage = () => {
  if (!imageUrl.value) {
    alert('没有图片可下载');
    return;
  }
  
  const link = document.createElement('a');
  link.href = imageUrl.value;
  link.download = (fileName.value ? fileName.value.replace(/\.[^/.]+$/, '') : 'document') + '.png';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

// 一键转为PDF
const directToPdf = async () => {
  try {
    loading.value = true;
    console.log('一键转换文档为PDF');
    
    // 如果当前已经是HTML模式并且有HTML内容，直接转PDF
    if (convertType.value === 'html' && htmlContent.value) {
      console.log('直接从HTML转为PDF');
      const success = await convertHtmlToPdf();
      
      if (success) {
        // 等待PDF生成完成后下载
        console.log('HTML转PDF成功，准备下载');
        await new Promise(resolve => setTimeout(resolve, 300));
        downloadPdf();
      }
      
      loading.value = false;
      return;
    }
    
    // 否则，先转为HTML，再转为PDF
    if (fileData.value) {
      console.log('从Word文档转为HTML，再转为PDF');
      
      try {
        // 转换为HTML
        const result = await mammoth.convertToHtml({ arrayBuffer: fileData.value });
        htmlContent.value = result.value;
        convertType.value = 'html';
        
        // 等待DOM更新
        await new Promise(resolve => setTimeout(resolve, 500));
        
        // 然后转为PDF
        const success = await convertHtmlToPdf();
        
        if (success) {
          // 等待PDF生成完成后下载
          console.log('HTML转PDF成功，准备下载');
          await new Promise(resolve => setTimeout(resolve, 300));
          downloadPdf();
        }
      } catch (error) {
        console.error('文档转换过程中出错:', error);
        alert('文档转换失败: ' + (error instanceof Error ? error.message : '未知错误'));
      }
    } else {
      alert('请先上传Word文档');
    }
    
    loading.value = false;
  } catch (error) {
    console.error('一键转PDF失败:', error);
    alert('一键转PDF失败: ' + (error instanceof Error ? error.message : '未知错误'));
    loading.value = false;
  }
};

// HTML相关方法
const copyToClipboard = async () => {
  if (!htmlContent.value) {
    alert('没有HTML内容可复制');
    return;
  }
  
  try {
    await navigator.clipboard.writeText(htmlContent.value);
    alert('已复制到剪贴板');
  } catch (error) {
    console.error('复制失败:', error);
    alert('复制失败');
  }
};

onMounted(() => {
  console.log('Test4Page mounted');
});

// 在组件销毁时清理资源
onUnmounted(() => {
  console.log('Test4Page unmounted, 清理资源');
  
  // 清理Blob URL
  if (pdfUrl.value) {
    try {
      URL.revokeObjectURL(pdfUrl.value);
      console.log('已清理PDF Blob URL');
    } catch (error) {
      console.error('清理PDF Blob URL失败:', error);
    }
  }
  
  if (imageUrl.value) {
    try {
      URL.revokeObjectURL(imageUrl.value);
      console.log('已清理图片Blob URL');
    } catch (error) {
      console.error('清理图片Blob URL失败:', error);
    }
  }
  
  // 清理其他引用
  pdfDocument.value = null;
  pdfBytes.value = null;
  htmlContent.value = '';
  fileData.value = null;
});
</script>

<style scoped lang="scss">
.test-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.test-header {
  margin-bottom: 20px;
}

.upload-section {
  margin-bottom: 20px;
}

.convert-type {
  margin-top: 10px;
  display: flex;
  gap: 20px;
}

.loading {
  margin-top: 10px;
  color: #666;
}

.result-container {
  margin-top: 20px;
}

.result-section {
  margin-bottom: 20px;
  border-top: 1px solid #eee;
  padding-top: 20px;
}

h4 {
  margin-bottom: 15px;
  color: #333;
}

.html-result {
  padding: 15px;
  border: 1px solid #eee;
  border-radius: 4px;
  background-color: #fff;
  min-height: 200px;
  overflow: visible;
  width: 100%;
  box-sizing: border-box;
}

.image-container, .pdf-container {
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #f9f9f9;
  min-height: 200px;
  overflow: hidden;
}

.actions {
  margin-top: 15px;
  text-align: right;
}

.download-btn {
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.download-btn:hover {
  background-color: #45a049;
}

.action-buttons {
  margin-top: 20px;
  text-align: right;
}

.convert-btn {
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  margin-left: 10px;
}

.convert-btn:hover {
  background-color: #45a049;
}

.quick-actions {
  margin-top: 10px;
  text-align: right;
}

.action-btn {
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.action-btn:hover {
  background-color: #45a049;
}

.image-result {
  margin-bottom: 10px;
  width: 100%;
  overflow: auto;
  
  img {
    max-width: 100%;
    display: block;
  }
}

.no-result {
  margin-bottom: 10px;
  color: #666;
}

.pdf-result {
  margin-bottom: 10px;
  width: 100%;
  height: 600px;
  
  iframe {
    width: 100%;
    height: 100%;
    border: 1px solid #eee;
  }
}

.spinner {
  border: 4px solid rgba(0, 0, 0, 0.1);
  border-left-color: #4CAF50;
  border-radius: 50%;
  width: 30px;
  height: 30px;
  animation: spin 1s linear infinite;
  margin: 0 auto;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.progress {
  margin-top: 10px;
  color: #666;
}
</style> 