import type { Ref } from 'vue'
import type { ExposeParam, UploadImgCallBack } from 'md-editor-v3'
import { authFetch, parseApiResponse } from '../services/api'
import { useToast } from './useToast'

export function useMdMediaUpload(editorRef: Ref<ExposeParam | undefined>) {
  const toast = useToast()

  const insertAtCursor = (text: string) => {
    editorRef.value?.insert?.(() => ({ targetValue: text }))
  }

  const uploadMediaFile = async (file: File): Promise<string | null> => {
    const formData = new FormData()
    formData.append('file', file)
    formData.append('categoryId', '1')
    formData.append('storageType', 'local')

    const response = await authFetch('/api/admin/attachments/upload', {
      method: 'POST',
      headers: {},
      body: formData
    })

    const result = await parseApiResponse<{ fileUrl: string }>(response)
    return result?.fileUrl ?? null
  }

  const uploadAndInsertVideo = async (file: File) => {
    try {
      const url = await uploadMediaFile(file)
      if (!url) return
      insertAtCursor(`\n<video controls src="${url}" style="max-width:100%"></video>\n`)
      toast.showToast('视频上传成功', 'success')
    } catch (error: unknown) {
      console.error('上传视频失败:', error)
      const message = error instanceof Error ? error.message : '上传视频失败'
      toast.showToast(message, 'error')
    }
  }

  const handleUploadImg = async (files: File[], callback: UploadImgCallBack) => {
    try {
      const uploadResults = await Promise.all(
        files.map(async (file) => {
          const url = await uploadMediaFile(file)
          return url ? { url, alt: file.name, title: file.name } : null
        })
      )
      const urls = uploadResults.filter((item): item is { url: string; alt: string; title: string } => item !== null)
      if (urls.length > 0) {
        callback(urls)
        toast.showToast('图片上传成功', 'success')
      }
    } catch (error: unknown) {
      console.error('上传图片失败:', error)
      const message = error instanceof Error ? error.message : '上传图片失败'
      toast.showToast(message, 'error')
    }
  }

  const handleEditorDrop = async (e: DragEvent) => {
    const files = Array.from(e.dataTransfer?.files || [])
    const imageFiles = files.filter((f) => f.type.startsWith('image/'))
    const videoFiles = files.filter((f) => f.type.startsWith('video/'))
    if (imageFiles.length === 0 && videoFiles.length === 0) return

    e.preventDefault()

    if (imageFiles.length > 0) {
      await handleUploadImg(imageFiles, (urls) => {
        if (!Array.isArray(urls) || urls.length === 0) return
        urls.forEach((item) => {
          if (typeof item === 'string') {
            insertAtCursor(`![image](${item})`)
          } else {
            insertAtCursor(`![${item.alt || 'image'}](${item.url})`)
          }
        })
      })
    }

    for (const file of videoFiles) {
      await uploadAndInsertVideo(file)
    }
  }

  const handleVideoPaste = async (e: ClipboardEvent) => {
    const items = e.clipboardData?.items
    if (!items) return

    for (let i = 0; i < items.length; i++) {
      const item = items[i]
      if (item.type.startsWith('video/')) {
        e.preventDefault()
        const file = item.getAsFile()
        if (file) await uploadAndInsertVideo(file)
        break
      }
    }
  }

  return {
    handleUploadImg,
    handleEditorDrop,
    handleVideoPaste,
  }
}
