<template>
  <slot
    :data="data?.data"
    :body="data?.body"
    :toc="data?.toc"
    :excerpt="data?.excerpt"
    :error="error"
  >
    <MDCRenderer
      v-if="body"
      :tag="tag"
      :class="props.class"
      :body="body"
      :data="data?.data"
      :unwrap="props.unwrap"
      :components="{
        a: ProseA,
        h1: ProseH1,
        h2: ProseH2,
        h3: ProseH3,
        h4: ProseH4,
        h5: ProseH5,
        h6: ProseH6,
        blockquote: ProseBlockquote,
      }"
    />
  </slot>
</template>

<script setup lang="ts">
import ProseA from "~/components/content/prose/ProseA.vue";
import ProseH1 from "~/components/content/prose/ProseH1.vue";
import ProseH2 from "~/components/content/prose/ProseH2.vue";
import ProseH3 from "~/components/content/prose/ProseH3.vue";
import ProseH4 from "~/components/content/prose/ProseH4.vue";
import ProseH5 from "~/components/content/prose/ProseH5.vue";
import ProseH6 from "~/components/content/prose/ProseH6.vue";
import ProseBlockquote from "~/components/content/prose/ProseBlockquote.vue";

import { hash } from 'ohash'
import { useAsyncData } from 'nuxt/app'
import { watch, computed } from 'vue'

const props = defineProps({
  tag: {
    type: [String, Boolean],
    default: 'div'
  },
  content: {
    type: [String, Object],
    required: true
  },
  excerpt: {
    type: Boolean,
    default: false
  },
  class: {
    type: [String, Array, Object],
    default: ''
  },
  unwrap: {
    type: [Boolean, String],
    default: false
  }
})
const model = defineModel<number>({
  default: 0,
});

const parser = useMarkdown();
const key = computed(() => hash(props.content))

const { data, refresh, error } = await useAsyncData(key.value, async () => {
  const timer = performance.now();
  if (typeof props.content !== 'string') {
    model.value = performance.now() - timer;
    return props.content
  }
  const result = await parser(props.content);
  model.value = performance.now() - timer;
  return result;
})

const body = computed(() => props.excerpt ? data.value?.excerpt : data.value?.body)

watch(() => props.content, () => {
  refresh()
})
</script>