<script setup lang="ts">
import { computed, ref, watchEffect } from 'vue'
import { Marked } from 'marked'
import { markedHighlight } from 'marked-highlight'
import 'katex/dist/katex.min.css'
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'
import markedKatex, { MarkedKatexOptions } from './plugins/katex'

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

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

const katexOptions: MarkedKatexOptions = {
  throwOnError: false,
  displayMode: true,
  nonStandard: true,
  output: 'html',
}

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

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

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)
})

function getRenderTextContent() {
  return renderTextContent.value
}

defineExpose({
  getRenderTextContent,
})
</script>

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

<style lang="scss" scoped>
@include custom-scrollbar(6px);

.article-container {
  overflow-x: auto;
  font-family: 'Microsoft YaHei UI';
  word-break: break-all;
  background-color: unset;
}

:deep(pre) {
  &::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }

  &::-webkit-scrollbar-corner {
    background: transparent;
  }

  &::-webkit-scrollbar-thumb {
    background: #bfbfbf;
    border-radius: 5px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 2px;
  }
}
</style>
