/**
 * Converter for "post" (rich text) message type.
 *
 * Extracts title and paragraph text from the locale-wrapped JSON structure.
 */

import type { ConvertedPayload, MessageConvertContext } from './types'
import { safeParse } from './utils'

const LOCALE_PRIORITY = ['zh_cn', 'en_us', 'ja_jp'] as const

interface PostBody {
  title?: string
  content?: Array<Array<Record<string, unknown>>>
}

function unwrapLocale(parsed: Record<string, unknown>): PostBody | undefined {
  if ('title' in parsed || 'content' in parsed) {
    return parsed as unknown as PostBody
  }
  for (const locale of LOCALE_PRIORITY) {
    const localeData = parsed[locale]
    if (localeData != null && typeof localeData === 'object') {
      return localeData as PostBody
    }
  }
  const firstKey = Object.keys(parsed)[0]
  if (firstKey) {
    const firstValue = parsed[firstKey]
    if (firstValue != null && typeof firstValue === 'object') {
      return firstValue as PostBody
    }
  }
  return undefined
}

function renderElement(el: Record<string, unknown>): string {
  const tag = String(el.tag ?? '')
  switch (tag) {
    case 'text': {
      let text = String(el.text ?? '')
      const style = el.style as string[] | undefined
      if (style?.includes('bold')) text = `**${text}**`
      if (style?.includes('italic')) text = `*${text}*`
      if (style?.includes('underline')) text = `<u>${text}</u>`
      if (style?.includes('lineThrough')) text = `~~${text}~~`
      if (style?.includes('codeInline')) text = `\`${text}\``
      return text
    }
    case 'a': {
      const text = String(el.text ?? el.href ?? '')
      const href = String(el.href ?? '')
      return href ? `[${text}](${href})` : text
    }
    case 'at': {
      const userId = String(el.user_id ?? '')
      if (userId === 'all') return '@all'
      const userName = String(el.user_name ?? userId)
      return `@${userName}`
    }
    case 'img':
      return '[image]'
    case 'media':
      return '[file]'
    case 'code_block': {
      const lang = String(el.language ?? '')
      const code = String(el.text ?? '')
      return `\n\`\`\`${lang}\n${code}\n\`\`\`\n`
    }
    case 'hr':
      return '\n---\n'
    default:
      return String(el.text ?? '')
  }
}

export async function convertPost(ctx: MessageConvertContext): Promise<ConvertedPayload | null> {
  const rawParsed = safeParse(ctx.rawContent)
  if (rawParsed == null || typeof rawParsed !== 'object') {
    return { text: '[rich text message]' }
  }

  const parsed = unwrapLocale(rawParsed as Record<string, unknown>)
  if (!parsed) {
    return { text: '[rich text message]' }
  }

  const lines: string[] = []
  if (parsed.title) {
    lines.push(`**${parsed.title}**`, '')
  }

  const contentBlocks = parsed.content ?? []
  for (const paragraph of contentBlocks) {
    if (!Array.isArray(paragraph)) continue
    let line = ''
    for (const el of paragraph) {
      line += renderElement(el as Record<string, unknown>)
    }
    if (line) lines.push(line)
  }

  const text = lines.join('\n').trim() || '[rich text message]'
  return { text }
}
