<template>
  <div v-if="mode === 'html'" class="rich-text" v-html="normalizedHtml" />
  <div v-else class="rich-text whitespace-pre-wrap break-words">
    {{ text }}
  </div>
</template>

<script setup lang="ts">
const props = defineProps<{
  content?: string | null
}>()

const text = computed(() => (typeof props.content === 'string' ? props.content : ''))

// Heuristic: treat as HTML only when it looks like it contains tags.
const mode = computed(() => (/<[a-z][\s\S]*>/i.test(text.value) ? 'html' : 'text'))

function escapeHtml(input: string) {
  return input
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#039;')
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return !!value && typeof value === 'object' && !Array.isArray(value)
}

const normalizedHtml = computed(() => {
  const raw = text.value.trim()
  if (!raw) return ''

  // Some CMS fields store JSON; try to pull out a common HTML field.
  if (
    (raw.startsWith('{') && raw.endsWith('}')) ||
    (raw.startsWith('[') && raw.endsWith(']'))
  ) {
    try {
      const parsed: unknown = JSON.parse(raw)

      let candidate = ''
      if (typeof parsed === 'string') candidate = parsed
      else if (isRecord(parsed)) {
        const html = parsed.html
        const content = parsed.content
        const body = parsed.body
        if (typeof html === 'string') candidate = html
        else if (typeof content === 'string') candidate = content
        else if (typeof body === 'string') candidate = body
      }

      if (candidate && /<[a-z][\s\S]*>/i.test(candidate)) return candidate

      // Fallback: render JSON as <pre>.
      return `<pre class="rich-pre">${escapeHtml(JSON.stringify(parsed, null, 2))}</pre>`
    } catch {
      // ignore JSON parse errors
    }
  }

  return raw
})
</script>

<style scoped>
.rich-text {
  color: rgba(0, 0, 0, 0.88);
  line-height: 1.75;
  font-size: 16px;
}

.rich-text :deep(h1) {
  font-size: 28px;
  font-weight: 700;
  margin: 18px 0 12px;
}

.rich-text :deep(h2) {
  font-size: 22px;
  font-weight: 700;
  margin: 16px 0 10px;
}

.rich-text :deep(h3) {
  font-size: 18px;
  font-weight: 700;
  margin: 14px 0 8px;
}

.rich-text :deep(p) {
  margin: 10px 0;
}

.rich-text :deep(a) {
  color: #1677ff;
  text-decoration: underline;
}

.rich-text :deep(ul),
.rich-text :deep(ol) {
  padding-left: 20px;
  margin: 10px 0;
}

.rich-text :deep(li) {
  margin: 6px 0;
}

.rich-text :deep(img) {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 12px auto;
}

.rich-text :deep(blockquote) {
  margin: 12px 0;
  padding: 8px 12px;
  border-left: 4px solid rgba(0, 0, 0, 0.12);
  background: rgba(0, 0, 0, 0.02);
}

.rich-pre {
  white-space: pre-wrap;
  word-break: break-word;
  padding: 12px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.04);
  font-size: 13px;
  line-height: 1.6;
}
</style>
