<script setup lang="ts">
import { ref, watch, onMounted, nextTick } from "vue";
import { renderAsync } from "docx-preview";

defineOptions({
  name: "ReDocxPreview"
});

const props = defineProps<{
  url?: string;
  file?: File | Blob;
}>();

const emit = defineEmits<{
  (e: "rendered"): void;
  (e: "error", error: Error): void;
}>();

const docxContainerRef = ref<HTMLDivElement>();
const loading = ref(true);
const errorMsg = ref("");

// 渲染 docx 文件
async function renderDocx() {
  if (!docxContainerRef.value) return;

  loading.value = true;
  errorMsg.value = "";

  try {
    // 清空之前的内容
    docxContainerRef.value.innerHTML = "";

    let arrayBuffer: ArrayBuffer;

    if (props.file) {
      // 如果传入的是 File 或 Blob
      arrayBuffer = await props.file.arrayBuffer();
    } else if (props.url) {
      // 从 URL 获取文件
      const response = await fetch(props.url);
      if (!response.ok) {
        throw new Error(`加载文件失败: ${response.status}`);
      }
      arrayBuffer = await response.arrayBuffer();
    } else {
      loading.value = false;
      return;
    }

    // 使用 docx-preview 渲染
    await renderAsync(arrayBuffer, docxContainerRef.value, undefined, {
      className: "docx-container",
      inWrapper: true,
      ignoreWidth: false,
      ignoreHeight: false,
      ignoreFonts: false,
      breakPages: true,
      ignoreLastRenderedPageBreak: true,
      experimental: false,
      trimXmlDeclaration: true,
      useBase64URL: true,
      renderHeaders: true,
      renderFooters: true,
      renderFootnotes: true,
      renderEndnotes: true
    });

    emit("rendered");
  } catch (error: any) {
    console.error("渲染 docx 文件失败:", error);
    errorMsg.value = error.message || "渲染 docx 文件失败";
    emit("error", error);
  } finally {
    loading.value = false;
  }
}

// 打印文档
function handlePrint() {
  if (!docxContainerRef.value) return;
  const printContent = docxContainerRef.value.innerHTML;
  const printWindow = window.open("", "_blank");
  if (printWindow) {
    printWindow.document.write(`
      <!DOCTYPE html>
      <html>
        <head>
          <title>打印文档</title>
          <style>
            body { font-family: Arial, sans-serif; margin: 20px; }
            .docx-wrapper { background: white; }
            @page { margin: 1cm; }
          </style>
        </head>
        <body>${printContent}</body>
      </html>
    `);
    printWindow.document.close();
    printWindow.print();
  }
}

// 暴露方法供父组件调用
defineExpose({
  refresh: renderDocx,
  print: handlePrint
});

// 监听 URL 或文件变化
watch(
  () => [props.url, props.file],
  () => {
    nextTick(() => {
      renderDocx();
    });
  }
);

onMounted(() => {
  renderDocx();
});
</script>

<template>
  <div class="docx-preview-component">
    <div v-if="errorMsg" class="docx-error">
      <el-empty :description="errorMsg">
        <el-button type="primary" @click="renderDocx">重新加载</el-button>
      </el-empty>
    </div>
    <div v-else v-loading="loading" class="docx-loading-wrapper">
      <div ref="docxContainerRef" class="docx-render-container" />
    </div>
  </div>
</template>

<style scoped lang="scss">
.docx-preview-component {
  width: 100%;
  height: 100%;
}

.docx-error {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 200px;
}

.docx-loading-wrapper {
  width: 100%;
  height: 100%;
  min-height: 300px;
}

.docx-render-container {
  width: 100%;
  height: 100%;

  :deep(.docx-wrapper) {
    padding: 20px;
    background: white;

    section.docx {
      margin-bottom: 20px;
      box-shadow: 0 0 8px rgb(0 0 0 / 10%);
    }
  }
}
</style>
