<template>
  <a-card
    :bodyStyle="bodyStyle"
    :style="cardStyle"
    :bordered="bordered"
  >
    <template #title v-if="showTitle">
      <span v-html="fileTitle"></span>
    </template>
    <template #extra v-if="showExtra">
      <slot name="extra"></slot>
      <a v-if="showToggleCollapse" href="#" style="margin-left: 20px" @click="toggleCollapse">{{ toggleCollapseLeft ? '展开>' : '<收起' }}</a>
    </template>
    <i-frame v-if="fileTp === 'pdf' || fileTp === 'url'" :src="fileUrl" :style="iframeStyle" />
    <div v-else :style="contentStyle" v-html="docContent" class="file-content"></div>
  </a-card>
</template>

<script lang="ts" setup>
  import iFrame from '/@/components/iFrame/index.vue';
  import { ref, computed } from 'vue';
  import mammoth from 'mammoth';
  import * as XLSX from 'xlsx';

  const props = withDefaults(defineProps<{
    showTitle?: boolean;
    showExtra?: boolean;
    showToggleCollapse?: boolean;
    bordered?: boolean;
    bodyStyle?: Record<string, any>;
    cardStyle?: Record<string, any>;
    iframeStyle?: Record<string, any>;
    contentStyle?: Record<string, any>;
    useStaticPrefixForDocx?: boolean;
  }>(), {
    showTitle: true,
    showExtra: false,
    showToggleCollapse: false,
    bordered: true,
    bodyStyle: () => ({ height: '100%', padding: '0px 0px', margin: '0px 0px' }),
    cardStyle: () => ({ overflow: 'hidden', height: '100%', padding: '0px' }),
    iframeStyle: () => ({ width: '100%', height: '100%' }),
    contentStyle: () => ({ height: '100%', overflow: 'auto' }),
    useStaticPrefixForDocx: false,
  });

  const loading = ref(false);
  const fileTp = ref('');
  const fileTitle = ref('文件名称');
  const fileUrl = ref('');
  const docContent = ref<string>('');
  const curDocFile = ref<any>({});
  const toggleCollapseLeft = ref(false);

  const emit = defineEmits(['toggle-collapse']);

  const fetchDoc = async (docUrl: string) => {
    try {
      const response = await fetch(docUrl);
      const arrayBuffer = await response.arrayBuffer();
      const result = await mammoth.convertToHtml({ arrayBuffer });
      docContent.value = result.value;
    } catch (error) {
      console.error('无法加载 DOC 文件:', error);
    } finally {
      loading.value = false;
    }
  };

  const fetchText = async (docUrl: string) => {
    try {
      const response = await fetch(docUrl);
      const arrayBuffer = await response.arrayBuffer();
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const decoder = new TextDecoder('utf-8');
      const text = decoder.decode(arrayBuffer);
      docContent.value = text;
    } catch (error) {
      console.error('无法加载 Txt 文件:', error);
    } finally {
      loading.value = false;
    }
  };

  const fetchExcel = async (docUrl: string) => {
    try {
      fetch(docUrl)
        .then((response) => {
          if (!response.ok) {
            throw new Error('网络响应不是 OK');
          }
          return response.arrayBuffer();
        })
        .then((data) => {
          const workbook = XLSX.read(data, { type: 'array' });
          const firstSheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[firstSheetName];
          const htmlString = XLSX.utils.sheet_to_html(worksheet);
          docContent.value = htmlString;
        })
        .catch((error) => {
          console.error('读取 Excel 文件时出错:', error);
        });
    } catch (error) {
      console.error('无法加载 Excel 文件:', error);
    } finally {
      loading.value = false;
    }
  };

  const fetchXml = async (fileUrl: string) => {
    try {
      const response = await fetch(fileUrl);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const xmlText = await response.text();
      const parser = new DOMParser();
      const xmlDoc = parser.parseFromString(xmlText, 'text/xml');
      docContent.value = createXmlTree(xmlDoc.documentElement);
    } catch (error) {
      console.error('Error fetching or parsing XML:', error);
    } finally {
      loading.value = false;
    }
  };

  function createXmlTree(node: any) {
    let html = `<div class="xml-node"><strong>${node.nodeName}</strong>`;

    if (node.attributes && node.attributes.length > 0) {
      html += ' [';
      for (let i = 0; i < node.attributes.length; i++) {
        const attr = node.attributes[i];
        html += `${attr.name}="${attr.value}"`;
        if (i < node.attributes.length - 1) {
          html += ', ';
        }
      }
      html += ']';
    }
    if (node.childNodes.length > 0) {
      html += '<div class="xml-node">';
      node.childNodes.forEach((childNode: any) => {
        if (childNode.nodeType === Node.ELEMENT_NODE) {
          html += createXmlTree(childNode);
        } else if (childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim()) {
          html += `<div>文本: ${childNode.nodeValue.trim()}</div>`;
        }
      });
      html += '</div>';
    }

    html += '</div>';
    return html;
  }

  async function getFileExtension(filename: string) {
    const index = filename.lastIndexOf('.');
    if (index === -1) return '';
    return filename.substring(index + 1);
  }

  function isHttpOrHttps(url: string) {
    return url.startsWith('http://') || url.startsWith('https://');
  }

  async function showFile(fileData: any) {
    curDocFile.value = fileData;
    const globOnlineViewUrl = import.meta.env.VITE_GLOB_ONLINE_VIEW_URL;
    const domainUrl = import.meta.env.VITE_GLOB_DOMAIN_URL;

    let filePath = fileData.filePath ;    
    if(!filePath) {
      filePath = fileData.fpath || fileData.filepath;
    }
    let fileType = fileData.fileTp || fileData.filetp;
    let fileName = fileData.fileName  || filePath;

    if (isHttpOrHttps(filePath)) {
      fileTp.value = 'url';
      fileUrl.value = filePath;
      fileTitle.value = '网址：' + filePath;
    } else {
      if (!fileType) {
        fileType = await getFileExtension(filePath);
      }
      fileTp.value = fileType;
      if(fileType === 'pdf') {
        fileUrl.value = domainUrl + filePath;
      } else {
        fileUrl.value = globOnlineViewUrl + filePath;
      }
      fileTitle.value = '文件名：' + fileName;
    }

    loading.value = true;
    try {
      if (fileTp.value === 'docx') {
        await fetchDoc(fileUrl.value);
      } else if (fileTp.value === 'pdf' || fileTp.value === 'url') {
      } else if (fileTp.value === 'txt') {
        await fetchText(fileUrl.value);
      } else if (fileTp.value === 'xml') {
        await fetchXml(fileUrl.value);
      } else if (fileTp.value === 'xlsx') {
        fetchExcel(fileUrl.value);
      } else if (fileTp.value === 'zip') {
      } else {
        await fetchText(fileUrl.value);
      }
    } catch (error) {
      console.log(error);
    } finally {
      loading.value = false;
    }
  }

  function getFileId() {
    return curDocFile.value['fileId'] || curDocFile.value['id'];
  }

  function setDocFile(fileData: any) {
    if (fileData && (fileData.filePath || fileData.fpath || fileData.filepath)) {
      showFile(fileData);
    }
  }

  function toggleCollapse() {
    toggleCollapseLeft.value = !toggleCollapseLeft.value;
    emit('toggle-collapse');
  }

  defineExpose({
    getFileId,
    setDocFile,
    showFile,
  });
</script>

<style lang="less" scoped>
  :deep(.file-content) {
    padding: 20px;
    font-family: "Microsoft YaHei", SimSun, sans-serif;
    line-height: 1.6;
    color: #333;

    table {
      border-collapse: collapse;
      width: 100%;
      margin: 15px 0;
      border: 1px solid #ddd;

      th, td {
        border: 1px solid #ddd;
        padding: 8px 12px;
      }

      th {
        background-color: #f2f2f2;
        font-weight: bold;
      }
    }

    h1, h2, h3, h4, h5, h6 {
      margin: 20px 0 10px;
      color: #222;
      font-weight: bold;
    }

    h1 { font-size: 24px; }
    h2 { font-size: 22px; }
    h3 { font-size: 20px; }
    h4 { font-size: 18px; }
    h5 { font-size: 16px; }
    h6 { font-size: 14px; }

    p {
      margin: 0 0 15px;
      text-align: justify;
    }

    ul, ol {
      margin: 15px 0;
      padding-left: 30px;
    }

    li {
      margin-bottom: 5px;
    }

    img {
      max-width: 100%;
      height: auto;
      margin: 10px 0;
    }

    pre {
      background-color: #f5f5f5;
      padding: 15px;
      border-radius: 4px;
      overflow-x: auto;
      margin: 15px 0;
    }

    blockquote {
      border-left: 4px solid #ddd;
      padding-left: 15px;
      color: #666;
      margin: 15px 0;
    }
  }
</style>
