<script setup lang="ts">
import { computed, ref, watchEffect } from 'vue'
import { Marked } from 'marked'
import { markedHighlight } from 'marked-highlight'
import { throttle } from 'lodash-es'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js'
import 'highlight.js/styles/panda-syntax-light.css'
import 'github-markdown-css'

interface Props {
  rawTextContent: string
  fontSize?: number | string
  color?: string
}

const props = withDefaults(defineProps<Props>(), {
  rawTextContent: '',
  fontSize: '14px',
  color: '#333',
})

const marked = new Marked(
  markedHighlight({
    emptyLangClass: 'hljs',
    langPrefix: 'hljs language-',
    highlight(code, lang, _info) {
      const language = hljs.getLanguage(lang) ? lang : 'plaintext'

      return hljs.highlight(code, { language }).value
    },
  }),
).use({ gfm: true, async: true })

const renderTextContent = ref('')

const articleContainerStyle = computed(() => {
  return {
    fontSize: props.fontSize,
    color: props.color,
  }
})

const textContentParser = throttle(
  (text: string) => {
    ;(marked.parse(text) as Promise<string>).then((res) => {
      renderTextContent.value = DOMPurify.sanitize(res)
    })
  },
  500,
  { leading: true, trailing: true },
)

watchEffect(() => {
  textContentParser(props.rawTextContent)
})
</script>

<template>
  <div class="markdown-render-container">
    <article class="markdown-body article-container" :style="articleContainerStyle" v-html="renderTextContent" />
  </div>
</template>

<style lang="scss" scoped>
.article-container {
  // letter-spacing: 0.1ch;
  font-family: 'Microsoft YaHei UI';
  word-break: break-all;
  background-color: unset;
}
</style>
