<template>
  <div class="preview-container" v-html="renderedContent"></div>
</template>

<script setup>
import { computed } from 'vue'
import MarkdownIt from 'markdown-it'
import katex from 'katex'
import 'katex/dist/katex.min.css'

const props = defineProps({
  content: {
    type: String,
    default: ''
  }
})

const md = new MarkdownIt({
  html: false,
  linkify: true,
  typographer: true
})

// 预处理 markdown，转换 $...$ 为 <span class="math-inline">...</span>
const preprocessLatex = (text) => {
  // 处理 $$...$$ 块级公式
  text = text.replace(/\$\$([\s\S]*?)\$\$/g, (match, content) => {
    try {
      const html = katex.renderToString(content.trim(), {
        displayMode: true,
        throwOnError: false
      })
      return `<div class="math-block">${html}</div>`
    } catch (e) {
      return `<div class="math-error">$$${content}$$</div>`
    }
  })
  
  // 处理 $...$ 行内公式
  // 使用负向前瞻和负向后瞻来避免与 $$ 冲突
  text = text.replace(/(?<!\$)\$(?!\$)([^\$\n]+?)\$(?!\$)/g, (match, content) => {
    try {
      const html = katex.renderToString(content.trim(), {
        displayMode: false,
        throwOnError: false
      })
      return `<span class="math-inline">${html}</span>`
    } catch (e) {
      return `<span class="math-error">${match}</span>`
    }
  })
  
  return text
}

const renderedContent = computed(() => {
  if (!props.content) return '<p></p>'
  
  // 先预处理 LaTeX
  const processed = preprocessLatex(props.content)
  
  // 然后渲染 markdown
  return md.render(processed)
})
</script>

<style scoped>
.preview-container {
  width: 100%;
  height: 100%;
  padding: 20px 40px;
  overflow-y: auto;
  background-color: #ffffff;
  color: #333;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
  line-height: 1.6;
}

.preview-container :deep(.math-block) {
  display: block;
  margin: 1em 0;
  text-align: center;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 8px 0;
}

.preview-container :deep(.math-inline) {
  font-size: 1.1em;
  padding: 0 2px;
}

.preview-container :deep(.math-error) {
  color: #dc3545;
  background-color: #f8d7da;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: monospace;
}

.preview-container :deep(h1),
.preview-container :deep(h2),
.preview-container :deep(h3),
.preview-container :deep(h4),
.preview-container :deep(h5),
.preview-container :deep(h6) {
  margin-top: 1em;
  margin-bottom: 0.5em;
  font-weight: 600;
  line-height: 1.25;
}

.preview-container :deep(p) {
  margin: 1em 0;
}

.preview-container :deep(code) {
  background-color: #f5f5f5;
  padding: 0.2em 0.4em;
  border-radius: 3px;
  font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', monospace;
  font-size: 0.9em;
}

.preview-container :deep(pre) {
  background-color: #f5f5f5;
  padding: 16px;
  border-radius: 6px;
  overflow-x: auto;
}

.preview-container :deep(pre code) {
  background-color: transparent;
  padding: 0;
}

.preview-container :deep(blockquote) {
  border-left: 4px solid #ddd;
  margin: 1em 0;
  padding-left: 16px;
  color: #666;
}

.preview-container :deep(ul),
.preview-container :deep(ol) {
  padding-left: 2em;
  margin: 1em 0;
}

.preview-container :deep(li) {
  margin: 0.25em 0;
}

.preview-container :deep(a) {
  color: #4a90d9;
  text-decoration: none;
}

.preview-container :deep(a:hover) {
  text-decoration: underline;
}

.preview-container :deep(img) {
  max-width: 100%;
  height: auto;
}

.preview-container :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin: 1em 0;
}

.preview-container :deep(th),
.preview-container :deep(td) {
  border: 1px solid #ddd;
  padding: 8px 12px;
  text-align: left;
}

.preview-container :deep(th) {
  background-color: #f5f5f5;
  font-weight: 600;
}

.preview-container :deep(hr) {
  border: none;
  border-top: 1px solid #ddd;
  margin: 2em 0;
}
</style>
