<script setup lang="ts">
import { MdEditor } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import { request, unwrapApiBody, type ApiResponse } from '~/utils/http/factory'

const props = defineProps<{
  modelValue: string
}>()

const emit = defineEmits<{
  'update:modelValue': [string]
}>()

const toast = useToast()
const editorId = `post-body-md-${useId()}`

const local = computed({
  get: () => props.modelValue,
  set: (v: string) => emit('update:modelValue', v),
})

function extractUploadError(e: unknown): string {
  if (e && typeof e === 'object') {
    const fe = e as {
      statusMessage?: string
      message?: string
      data?: { message?: string }
    }
    if (typeof fe.statusMessage === 'string' && fe.statusMessage.length) {
      return fe.statusMessage
    }
    if (typeof fe.data?.message === 'string' && fe.data.message.length) {
      return fe.data.message
    }
    if (typeof fe.message === 'string' && fe.message.length) {
      return fe.message
    }
  }
  return '图片上传失败'
}

async function onUploadImg(files: File[], callback: (urls: string[]) => void) {
  const form = new FormData()
  for (const f of files) {
    form.append('file', f)
  }
  try {
    const res = await request<ApiResponse<{ files: { url: string }[] }>>('/api/file/upload', {
      method: 'POST',
      body: form,
    })
    const { files: uploaded } = unwrapApiBody(res)
    callback(uploaded.map((x) => x.url))
  } catch (e: unknown) {
    toast.add({ title: extractUploadError(e), color: 'error' })
    callback([])
  }
}
</script>

<template>
  <ClientOnly>
    <MdEditor
      :id="editorId"
      v-model="local"
      language="zh-CN"
      :preview="true"
      preview-theme="github"
      theme="light"
      :on-upload-img="onUploadImg"
      :style="{ height: 'min(72vh, 720px)' }"
      class="w-full rounded-lg overflow-hidden ring ring-default"
    />
    <template #fallback>
      <div class="text-muted text-sm py-12 text-center border border-default rounded-lg">
        编辑器加载中…
      </div>
    </template>
  </ClientOnly>
</template>
