"use client"

import React, { useCallback, useState, useRef } from 'react'
import { Button } from './button'
import { Progress } from './progress'
import { useToast } from './use-toast'
import { Upload, X, FileImage, File, Loader2 } from 'lucide-react'
import { uploadFile, uploadImage, formatFileSize } from '@/lib/api/upload'
import type { UploadResponse } from '@/lib/api/upload'

interface FileUploadProps {
  /**
   * 接受的文件类型
   */
  accept?: Record<string, string[]>
  /**
   * 是否允许多文件上传
   */
  multiple?: boolean
  /**
   * 最大文件大小（字节）
   */
  maxSize?: number
  /**
   * 最大文件数量
   */
  maxFiles?: number
  /**
   * 是否只允许图片
   */
  imageOnly?: boolean
  /**
   * 上传成功回调
   */
  onUploadSuccess?: (files: UploadResponse[]) => void
  /**
   * 上传失败回调
   */
  onUploadError?: (error: string) => void
  /**
   * 文件移除回调
   */
  onRemove?: (file: UploadResponse) => void
  /**
   * 预设的文件列表
   */
  defaultFiles?: UploadResponse[]
  /**
   * 是否禁用
   */
  disabled?: boolean
  /**
   * 提示文本
   */
  placeholder?: string
  /**
   * 样式类名
   */
  className?: string
}

export function FileUpload({
  accept = { 'image/*': ['.jpeg', '.jpg', '.png', '.gif', '.webp'] },
  multiple = false,
  maxSize = 10 * 1024 * 1024, // 10MB
  maxFiles = 1,
  imageOnly = false,
  onUploadSuccess,
  onUploadError,
  onRemove,
  defaultFiles = [],
  disabled = false,
  placeholder = '点击或拖拽文件到这里上传',
  className = '',
}: FileUploadProps) {
  const { toast } = useToast()
  const [uploadedFiles, setUploadedFiles] = useState<UploadResponse[]>(defaultFiles)
  const [uploading, setUploading] = useState(false)
  const [progress, setProgress] = useState(0)
  const [isDragActive, setIsDragActive] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)

  const handleFiles = useCallback(async (files: FileList | null) => {
    if (!files || disabled || uploading) return

    const acceptedFiles = Array.from(files).filter(file => {
      if (imageOnly) {
        return file.type.startsWith('image/')
      }
      return true
    })

    if (acceptedFiles.length === 0) return

    // 检查文件数量限制
    if (uploadedFiles.length + acceptedFiles.length > maxFiles) {
      const error = `最多只能上传 ${maxFiles} 个文件`
      onUploadError?.(error)
      toast({
        title: '上传失败',
        description: error,
        variant: 'destructive',
      })
      return
    }

    setUploading(true)
    const uploadPromises: Promise<UploadResponse>[] = []

    for (const file of acceptedFiles) {
      // 文件大小检查
      if (file.size > maxSize) {
        const error = `文件 ${file.name} 大小超过限制 ${formatFileSize(maxSize)}`
        onUploadError?.(error)
        toast({
          title: '上传失败',
          description: error,
          variant: 'destructive',
        })
        continue
      }

      // 上传文件
      const uploadPromise = (imageOnly ? uploadImage(file, ({ percentage }) => {
        setProgress(percentage)
      }) : uploadFile(file, ({ percentage }) => {
        setProgress(percentage)
      })).then(response => response.data)

      uploadPromises.push(uploadPromise)
    }

    try {
      const results = await Promise.all(uploadPromises)
      const newFiles = [...uploadedFiles, ...results]
      
      setUploadedFiles(newFiles)
      onUploadSuccess?.(results)
      
      toast({
        title: '上传成功',
        description: `成功上传 ${results.length} 个文件`,
      })
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : '上传失败'
      onUploadError?.(errorMsg)
      toast({
        title: '上传失败',
        description: errorMsg,
        variant: 'destructive',
      })
    } finally {
      setUploading(false)
      setProgress(0)
    }
  }, [uploadedFiles, disabled, uploading, maxFiles, maxSize, imageOnly, onUploadSuccess, onUploadError, toast])

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    if (!disabled && !uploading) {
      setIsDragActive(true)
    }
  }, [disabled, uploading])

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragActive(false)
  }, [])

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragActive(false)
    
    if (disabled || uploading) return
    
    const files = e.dataTransfer.files
    handleFiles(files)
  }, [disabled, uploading, handleFiles])

  const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files
    handleFiles(files)
    // 清空input以允许重新选择同一文件
    if (fileInputRef.current) {
      fileInputRef.current.value = ''
    }
  }, [handleFiles])

  const handleClick = useCallback(() => {
    if (!disabled && !uploading) {
      fileInputRef.current?.click()
    }
  }, [disabled, uploading])

  const removeFile = (fileToRemove: UploadResponse) => {
    const newFiles = uploadedFiles.filter(file => file.url !== fileToRemove.url)
    setUploadedFiles(newFiles)
    onRemove?.(fileToRemove)
    
    toast({
      title: '文件已移除',
      description: fileToRemove.filename,
    })
  }

  // 生成accept字符串
  const acceptString = Object.keys(accept).join(',')

  return (
    <div className={`space-y-4 ${className}`}>
      {/* 隐藏的文件input */}
      <input
        ref={fileInputRef}
        type="file"
        multiple={multiple}
        accept={acceptString}
        onChange={handleInputChange}
        className="hidden"
        disabled={disabled || uploading}
      />

      {/* 上传区域 */}
      <div
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        onClick={handleClick}
        className={`
          border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors
          ${isDragActive ? 'border-primary bg-primary/10' : 'border-gray-300 hover:border-gray-400'}
          ${disabled || uploading ? 'opacity-50 cursor-not-allowed' : ''}
        `}
      >
        
        {uploading ? (
          <div className="space-y-2">
            <Loader2 className="h-8 w-8 animate-spin mx-auto text-primary" />
            <p className="text-sm text-gray-500">上传中...</p>
            <Progress value={progress} className="w-full max-w-xs mx-auto" />
            <p className="text-xs text-gray-400">{progress}%</p>
          </div>
        ) : (
          <div className="space-y-2">
            <Upload className="h-8 w-8 mx-auto text-gray-400" />
            <div>
              <p className="text-sm text-gray-600">
                {isDragActive ? '松开鼠标上传文件' : placeholder}
              </p>
              <p className="text-xs text-gray-400 mt-1">
                {imageOnly ? '支持图片格式' : '支持多种文件格式'}，
                最大 {formatFileSize(maxSize)}
              </p>
            </div>
          </div>
        )}
      </div>

      {/* 已上传文件列表 */}
      {uploadedFiles.length > 0 && (
        <div className="space-y-2">
          <h4 className="text-sm font-medium text-gray-700">已上传文件</h4>
          <div className="grid gap-2">
            {uploadedFiles.map((file, index) => (
              <div
                key={`${file.url}-${index}`}
                className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border"
              >
                <div className="flex items-center space-x-3">
                  {file.mimeType && file.mimeType.startsWith('image/') ? (
                    <FileImage className="h-5 w-5 text-blue-500" />
                  ) : (
                    <File className="h-5 w-5 text-gray-500" />
                  )}
                  
                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-medium text-gray-900 truncate">
                      {file.filename}
                    </p>
                    <p className="text-xs text-gray-500">
                      {formatFileSize(file.size)}
                    </p>
                  </div>
                </div>
                
                <div className="flex items-center space-x-2">
                  {file.mimeType && file.mimeType.startsWith('image/') && (
                    <img
                      src={file.url}
                      alt={file.filename}
                      className="h-10 w-10 object-cover rounded border"
                    />
                  )}
                  
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => removeFile(file)}
                    className="text-red-500 hover:text-red-700 hover:bg-red-50"
                  >
                    <X className="h-4 w-4" />
                  </Button>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  )
}