import { PlusOutlined } from '@ant-design/icons'
import { App, Typography, Upload } from 'antd'
import type { UploadFile, UploadProps } from 'antd'
import type { ClipboardEvent, DragEvent } from 'react'

import { uploadFile } from '@/services/files'
import type { UploadedFile } from '@/types/worker-platform'

type ImageUploadProps = {
  value?: UploadedFile[]
  onChange?: (files: UploadedFile[]) => void
  scene: string
  scope: 'admin' | 'worker' | 'collect'
  maxCount?: number
  showPasteHint?: boolean
}

export default function ImageUpload({
  value = [],
  onChange,
  scene,
  scope,
  maxCount = 6,
  showPasteHint = false,
}: ImageUploadProps) {
  const { message } = App.useApp()
  const fileList: UploadFile[] = value.map((file) => ({
    uid: file.objectKey || file.url,
    name: file.filename || '图片',
    status: 'done',
    url: file.thumbnailUrl || file.url,
    thumbUrl: file.thumbnailUrl || file.url,
  }))

  async function uploadFiles(files: File[]) {
    const images = files.filter((file) => file.type.startsWith('image/'))
    if (images.length === 0) return
    const remaining = maxCount - value.length
    if (remaining <= 0) {
      message.warning(`最多上传 ${maxCount} 张图片`)
      return
    }
    const next = [...value]
    for (const file of images.slice(0, remaining)) {
      try {
        const uploaded = await uploadFile(file, scene, scope)
        next.push(uploaded)
      } catch (error) {
        message.error(error instanceof Error ? error.message : '上传失败')
      }
    }
    if (next.length > value.length) onChange?.(next)
  }

  function handlePaste(event: ClipboardEvent<HTMLDivElement>) {
    const files = Array.from(event.clipboardData?.files || [])
    if (files.length === 0) return
    event.preventDefault()
    void uploadFiles(files)
  }

  function handleDrop(event: DragEvent<HTMLDivElement>) {
    event.preventDefault()
    const files = Array.from(event.dataTransfer?.files || [])
    if (files.length > 0) void uploadFiles(files)
  }

  const customRequest: UploadProps['customRequest'] = async (options) => {
    try {
      const uploaded = await uploadFile(options.file as File, scene, scope)
      onChange?.([...value, uploaded].slice(-maxCount))
      options.onSuccess?.(uploaded)
    } catch (error) {
      message.error(error instanceof Error ? error.message : '上传失败')
      options.onError?.(error instanceof Error ? error : new Error('上传失败'))
    }
  }

  return (
    <div
      className="image-upload-droppable"
      onPaste={handlePaste}
      onDrop={handleDrop}
      onDragOver={(event) => event.preventDefault()}
    >
      <Upload
        accept="image/jpeg,image/png,image/webp"
        listType="picture-card"
        fileList={fileList}
        maxCount={maxCount}
        customRequest={customRequest}
        onRemove={(file) => {
          onChange?.(
            value.filter((item) => (item.objectKey || item.url) !== file.uid),
          )
          return true
        }}
        showUploadList={{ showPreviewIcon: false }}
      >
        {value.length >= maxCount ? null : (
          <button className="image-upload-trigger" type="button">
            <PlusOutlined />
            <span>上传</span>
          </button>
        )}
      </Upload>
      {showPasteHint ? (
        <Typography.Text type="secondary" className="image-upload-hint">
          支持点击选择、粘贴剪贴板截图或拖拽图片上传
        </Typography.Text>
      ) : null}
    </div>
  )
}
