<script setup lang="ts">
import { useToggle } from '@vueuse/core';
import hljs from 'highlight.js';
import { parseXmlString, XmlNode, XmlNodeType } from 'steady-xml';
import { nextTick, ref } from 'vue';
import 'highlight.js/styles/github-dark.css'; // 引入高亮主题

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

const [open, setOpen] = useToggle(false);

const formattedJson = ref<string>('');
const codeRef = ref<HTMLElement | null>(null);
const errorMessage = ref('');

async function onOpen(xml: string) {
  setOpen(true);
  try {
    const rootNodes = new XmlNode(XmlNodeType.Root, parseXmlString(xml));
    const parsed = rootNodes.parent?.toJSON() as unknown as string;
    formattedJson.value = JSON.stringify(parsed, null, 2);

    await nextTick();

    if (codeRef.value) {
      codeRef.value.textContent = formattedJson.value;
      try {
        hljs.highlightElement(codeRef.value);
      }
      catch (e) {
        // highlight.js 在某些环境可能抛错，捕获以防止影响显示
      }
    }
  }
  catch (err: any) {
    errorMessage.value = err?.message ?? String(err);
    formattedJson.value = errorMessage.value;
  }
}

function close() {
  setOpen(false);
}

// 暴露方法供父组件调用：组件实例上的 open(xmlString)
defineExpose({
  open: onOpen,
});
</script>

<template>
  <a-drawer
    v-model:open="open"
    title="json预览"
    placement="right"
    :width="1000"
    destroy-on-close
    :footer="false"
    @close="close"
  >
    <div size-full class="mt-[-20px]">
      <!-- 错误提示 -->
      <div v-if="errorMessage" class="error-message">
        {{ errorMessage }}
      </div>
      <pre class="w-full my-0px! p-0px!">
        <code ref="codeRef" class="language-json" />
      </pre>
    </div>
  </a-drawer>
</template>

<style>
pre .hljs {
  font-family: "Consolas", "Monaco", monospace !important; /* 等宽字体 */
  font-size: 16px !important; /* 字体大小 */
  line-height: 20px;
  color: #24292e !important;
  word-break: break-word;
  white-space: pre-wrap;
  background: #f9f9f9 !important; /* 浅灰色背景（默认是白色） */
  border-radius: 8px !important; /* 圆角 */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important; /* 阴影 */
}

.hljs-name,
.hljs-quote,
.hljs-selector-tag,
.hljs-selector-pseudo {
  color: #22863a;
}

.hljs-attr,
.hljs-attribute,
.hljs-literal,
.hljs-meta,
.hljs-number,
.hljs-operator,
.hljs-variable,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-id {
  color: #005cc5;
}

.hljs-regexp,
.hljs-string,
.hljs-meta .hljs-string {
  color: #032f62;
}
</style>
