<script setup>
const props = defineProps({
  content: {
    type: String,
    default: ''
  }
})

/**
 * 마크다운 블록을 생성
 * @param {string} type - 블록 타입
 * @param {string|Array<string>} text - 블록 텍스트
 * @param {number|null} level - 제목 레벨
 * @param {string} id - 블록 ID
 * @returns {{ id: string, type: string, text: string|Array<string>, level: number|null }} 블록
 */
const createBlock = (type = 'paragraph', text = '', level = null, id = '') => ({
  id,
  type,
  text,
  level
})

/**
 * 마크다운 문자열을 렌더링용 블록 목록으로 변환
 * @param {string} markdown - 마크다운 문자열
 * @returns {Array<Object>} 블록 목록
 */
const parseMarkdownBlocks = (markdown) => {
  const lines = markdown.split('\n')
  const blocks = []
  let index = 0

  while (index < lines.length) {
    const line = lines[index]
    const trimmedLine = line.trim()

    if (!trimmedLine) {
      index += 1
      continue
    }

    if (trimmedLine.startsWith('```')) {
      const codeLines = []
      index += 1

      while (index < lines.length && !lines[index].trim().startsWith('```')) {
        codeLines.push(lines[index])
        index += 1
      }

      blocks.push(createBlock('code', codeLines.join('\n'), null, `block-${blocks.length}`))
      index += 1
      continue
    }

    if (trimmedLine === '---') {
      blocks.push(createBlock('divider', '', null, `block-${blocks.length}`))
      index += 1
      continue
    }

    const headingMatch = trimmedLine.match(/^(#{1,3})\s+(.+)$/)

    if (headingMatch) {
      blocks.push(createBlock('heading', headingMatch[2], headingMatch[1].length, `block-${blocks.length}`))
      index += 1
      continue
    }

    if (trimmedLine.startsWith('> ')) {
      blocks.push(createBlock('quote', trimmedLine.replace(/^>\s?/, ''), null, `block-${blocks.length}`))
      index += 1
      continue
    }

    if (/^- /.test(trimmedLine)) {
      const items = []

      while (index < lines.length && /^- /.test(lines[index].trim())) {
        items.push(lines[index].trim().replace(/^- /, ''))
        index += 1
      }

      blocks.push(createBlock('list', items, null, `block-${blocks.length}`))
      continue
    }

    blocks.push(createBlock('paragraph', trimmedLine, null, `block-${blocks.length}`))
    index += 1
  }

  return blocks
}

const blocks = computed(() => parseMarkdownBlocks(props.content))
</script>

<template>
  <div class="content-markdown-renderer">
    <template v-for="block in blocks" :key="block.id">
      <ProseHeading v-if="block.type === 'heading'" :level="block.level">
        {{ block.text }}
      </ProseHeading>
      <ProseBlockquote v-else-if="block.type === 'quote'">
        {{ block.text }}
      </ProseBlockquote>
      <ProseList v-else-if="block.type === 'list'">
        <li v-for="(item, itemIndex) in block.text" :key="`${block.id}-${itemIndex}`">
          {{ item }}
        </li>
      </ProseList>
      <pre
        v-else-if="block.type === 'code'"
        class="content-markdown-renderer__code my-6 overflow-x-auto rounded bg-[#15171a] px-4 py-3 text-sm leading-6 text-white"
      ><code>{{ block.text }}</code></pre>
      <hr v-else-if="block.type === 'divider'" class="content-markdown-renderer__divider my-10 border-line">
      <p v-else class="content-markdown-renderer__paragraph my-5 leading-8">
        {{ block.text }}
      </p>
    </template>
  </div>
</template>
