<script lang="ts">
import "github-markdown-css/github-markdown.css";
import SvelteMarkdown from "svelte-markdown";
// import "mathjax-full/es5/tex-mml-svg.js";
import "./main.css";
import Prism from "prismjs";

import { onMount } from "svelte";
import DOMPurify from "isomorphic-dompurify";

let version = 0;

let content_unsafe = `
# This is a header
This is a paragraph $E = mc^2$
* This is a list
* With two items
1. And a sublist
2. That is ordered
* With another
* Sublist inside
| And this is | A table |
|-------------|---------|
| With two | columns |
`;

let content: string = '';

$: content = (() => {
  let c = DOMPurify.sanitize(content_unsafe, {})
  // console.log(c)
  return c
})()
let source = "";

import { tick } from "svelte";

let complete = false;

async function updateSource() {
    complete = false;
    version += 1;
    // 转义，双斜杠、"<"、">" 转义成特殊字符，渲染完后再还原
    source = content.replaceAll('\\\\', '\uE000')
                    .replaceAll('&lt;', '\uE001')
                    .replaceAll('&gt;', '\uE002')
                    .replaceAll('<', '\uE001')
                    .replaceAll('>', '\uE002');
    await tick();
    await AppendCodeTag();
    await recoverSource();
    Prism.highlightAll();
    if ((content.includes("$")) || (content.includes("$$"))) {
      complete = false;
      TriggerRender();
    } else {
      complete = true;
    }
}

/*
* 为所有 pre 标签下的 code 标签，加上 language-xxx 的类名
*/
async function AppendCodeTag(){
  const preTags = document.querySelectorAll('pre');
  preTags.forEach((pre) => {
    const codeTag = pre.querySelector('code');
    if (codeTag) {
      let preClass = pre.className;
      if (preClass) {
        codeTag.classList.add('language-' + preClass);
      }
    }
  });
}

async function recoverSource(){
// 还原转义的双斜杠
  const main = document.getElementById('main');
  if (main && main.innerHTML) {
    main.innerHTML = main.innerHTML.replaceAll('\uE000', '\\\\');
    main.innerHTML = main.innerHTML.replaceAll('\uE001', '&lt;').replaceAll('\uE002', '&gt;');
  }
}

function TriggerRender() {
  // 如果没有标签名为 mjx-container 元素，就一直循环触发
  const checkAndRender = async () => {
    await tick();
    const mjxContainer = document.querySelector('mjx-container');
    if (!mjxContainer) {
      await renderMath();
      setTimeout(checkAndRender, 100);
    } else {
      console.log("MathJax rendering complete.");
      complete = true;
    }
  };
  checkAndRender();
}

async function renderMath() {
    console.log("Rendering math...");
    const MathJax = (window as any).MathJax;
    if (!MathJax) return;
    if (MathJax.typesetPromise) {
      await MathJax.typesetPromise();
    }
}

let sizeParam = '1.2em';
onMount(async () => {
    /// @ts-ignore
    await import("mathjax-full/es5/tex-mml-svg.js");
  
    const urlParams = new URLSearchParams(window.location.search);
    sizeParam = urlParams.get('size') ?? sizeParam;
  
    (window as any).checkState = () => {
      return complete;
    };
});

</script>

<textarea name="content" id="content" bind:value={content_unsafe}></textarea>
<button id="button" on:click={updateSource}>Render</button>

<svelte:head>
  <script>
    window.MathJax = {
      loader: {
        paths: {
          tex: 'node_modules/mathjax-full/es5/input/tex/extensions'
        }
      },
      tex: {
        inlineMath: [['$', '$']],
        displayMath: [['$$', '$$']]
      }
    };
  </script>
</svelte:head>

<!-- version 是一个用于强制 Svelte 重新渲染内容的变量。当内容更新时，version 会递增，从而触发 Svelte 重新渲染包含 source 的部分。 -->
{#key version}
<div id="main" class="markdown-body main" style="font-size: {sizeParam || '1.2em'}">
  <SvelteMarkdown {source} />
</div>
{/key}

<style>
  .markdown-body {
    font-family: "Noto Sans SC", "Noto Sans CJK SC", "Noto Sans";
  }
</style>
