import { forwardRef, useState, useCallback, useRef } from 'react'
import { Dialog, Button, Progress } from '@/components/ui'
import { HiCloudArrowUp, HiXMark } from 'react-icons/hi2'
import classNames from 'classnames'

export interface FileUploadModalProps {
  isOpen: boolean
  onClose: () => void
  onUpload: (files: File[]) => Promise<void>
  currentFolderId?: string
  loading?: boolean
  className?: string
}

interface UploadFileWithProgress {
  id: string
  file: File
  progress: number
  status: 'pending' | 'uploading' | 'completed' | 'error'
  error?: string
  errorDetail?: string
}

const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props, ref) => {
  const { isOpen, onClose, onUpload, currentFolderId, loading = false, className } = props

  const [uploadFiles, setUploadFiles] = useState<UploadFileWithProgress[]>([])
  const [isDragOver, setIsDragOver] = useState(false)
  const [uploading, setUploading] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)

  const generateFileId = () => Math.random().toString(36).substr(2, 9)

  const formatFileSize = (bytes: number): string => {
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']

    // Handle undefined, null, NaN values
    if (!bytes || bytes === 0 || isNaN(bytes)) return '0 B'

    const i = Math.floor(Math.log(bytes) / Math.log(1024))
    return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + sizes[i]
  }

  const handleFilesSelect = useCallback((files: FileList | File[]) => {
    const fileArray = Array.from(files)
    const newFiles: UploadFileWithProgress[] = fileArray.map((file) => ({
      id: generateFileId(),
      file: file,
      progress: 0,
      status: 'pending' as const,
    }))

    setUploadFiles((prev) => [...prev, ...newFiles])
  }, [])

  const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      handleFilesSelect(e.target.files)
    }
  }

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setIsDragOver(true)
  }, [])

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

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault()
      setIsDragOver(false)

      if (e.dataTransfer.files) {
        handleFilesSelect(e.dataTransfer.files)
      }
    },
    [handleFilesSelect],
  )

  const removeFile = (fileId: string) => {
    setUploadFiles((prev) => prev.filter((f) => f.id !== fileId))
  }

  const handleUpload = async () => {
    if (uploadFiles.length === 0) return

    setUploading(true)
    const filesToUpload = uploadFiles.filter((f) => f.status === 'pending')

    // Upload files one by one
    for (const fileData of filesToUpload) {
      let progressInterval: NodeJS.Timeout | null = null
      
      try {
        // Set status to uploading
        setUploadFiles((prev) =>
          prev.map((f) => (f.id === fileData.id ? { ...f, status: 'uploading' as const } : f)),
        )

        // Simulate progress for visual feedback
        progressInterval = setInterval(() => {
          setUploadFiles((prev) =>
            prev.map((f) => {
              if (f.id === fileData.id && f.progress < 90) {
                return { ...f, progress: f.progress + 10 }
              }
              return f
            }),
          )
        }, 100)

        // Call the actual upload function for single file
        await onUpload([fileData.file])

        // Clear progress interval
        if (progressInterval) {
          clearInterval(progressInterval)
          progressInterval = null
        }

        // Mark as completed and remove from list after delay
        setUploadFiles((prev) =>
          prev.map((f) =>
            f.id === fileData.id ? { ...f, status: 'completed' as const, progress: 100 } : f,
          ),
        )

        // Remove completed files from list after 2 seconds
        setTimeout(() => {
          setUploadFiles((prev) => prev.filter((f) => f.id !== fileData.id))
        }, 2000)
      } catch (error: any) {
        console.error('Upload failed for file:', fileData.file.name, error)

        // Clear progress interval in case of error
        if (progressInterval) {
          clearInterval(progressInterval)
          progressInterval = null
        }

        // Extract detailed error message from ABP response
        let errorMessage = 'Upload failed'
        let detailMessage = ''

        if (error?.response?.data?.error) {
          const errorData = error.response.data.error
          
          // Ana hata mesajı
          if (errorData.message) {
            errorMessage = errorData.message
          }
          
          // Detay mesajı - validationErrors veya details'den
          if (errorData.details) {
            detailMessage = errorData.details
          } else if (errorData.validationErrors && errorData.validationErrors.length > 0) {
            detailMessage = errorData.validationErrors[0].message || errorData.validationErrors[0]
          }

          // Dosya boyutu kontrolü için özel mesaj
          if (detailMessage.includes('Request body too large') || detailMessage.includes('max request body size')) {
            const maxSizeMB = 30 // 30MB limit
            errorMessage = 'File too large'
            detailMessage = `File size exceeds the maximum allowed size of ${maxSizeMB}MB. Your file is ${(fileData.file.size / (1024 * 1024)).toFixed(1)}MB.`
          }

        } else if (error?.message) {
          errorMessage = error.message
        } else if (typeof error === 'string') {
          errorMessage = error
        }

        // Mark as error with detailed message
        setUploadFiles((prev) =>
          prev.map((f) =>
            f.id === fileData.id
              ? {
                  ...f,
                  status: 'error' as const,
                  error: errorMessage,
                  errorDetail: detailMessage,
                  progress: 0,
                }
              : f,
          ),
        )
      }
    }

    setUploading(false)

    // Check if all files are processed (completed or error)
    const remainingFiles = uploadFiles.filter(
      (f) => f.status === 'pending' || f.status === 'uploading',
    )
    if (remainingFiles.length === 0) {
      // If no pending files and no errors, close modal
      const hasErrors = uploadFiles.some((f) => f.status === 'error')
      if (!hasErrors) {
        setTimeout(() => {
          onClose()
          setUploadFiles([])
        }, 2000)
      }
    }
  }

  const handleClose = () => {
    if (!uploading) {
      setUploadFiles([])
      onClose()
    }
  }

  const clearCompletedFiles = () => {
    setUploadFiles((prev) => prev.filter((f) => f.status !== 'completed'))
  }

  const clearErrorFiles = () => {
    setUploadFiles((prev) => prev.filter((f) => f.status !== 'error'))
  }

  const totalFiles = uploadFiles.length
  const completedFiles = uploadFiles.filter((f) => f.status === 'completed').length
  const errorFiles = uploadFiles.filter((f) => f.status === 'error').length
  const pendingFiles = uploadFiles.filter((f) => f.status === 'pending').length
  const hasError = errorFiles > 0

  return (
    <Dialog isOpen={isOpen} onClose={handleClose} className={className}>
      <div ref={ref}>
        <div className="flex items-center justify-between pb-2 border-b">
          <h3 className="text-lg font-semibold">Upload Files</h3>
        </div>

        <div className="py-2">
          <div
            className={classNames(
              'relative border-2 border-dashed rounded-lg p-4 text-center transition-colors',
              isDragOver
                ? 'border-blue-400 bg-blue-50 dark:bg-blue-900/20'
                : 'border-gray-300 dark:border-gray-600 hover:border-gray-400',
            )}
            onDragOver={handleDragOver}
            onDragLeave={handleDragLeave}
            onDrop={handleDrop}
          >
            <input
              ref={fileInputRef}
              type="file"
              multiple
              className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
              onChange={handleFileInputChange}
              disabled={uploading}
            />

            <HiCloudArrowUp className="mx-auto h-12 w-12 text-gray-400 mb-4" />
            <p className="text-lg font-medium text-gray-900 dark:text-gray-100 mb-2">
              Choose files or drag and drop here
            </p>
            <p className="text-sm text-gray-500 dark:text-gray-400 mb-4">
              Select one or more files to upload
            </p>
          </div>

          {/* File List */}
          {uploadFiles.length > 0 && (
            <div className="space-y-1 max-h-80 overflow-y-auto">
              {uploadFiles.map((file) => (
                <div
                  key={file.id}
                  className="flex items-center justify-between p-2 bg-gray-50 dark:bg-gray-700 rounded-lg"
                >
                  <div className="flex-1 min-w-0">
                    {/* File name and size in one line */}
                    <div className="flex items-center justify-between">
                      <p className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate flex-1 mr-2">
                        {file.file.name}
                      </p>
                      <span className="text-xs text-gray-500 dark:text-gray-400 flex-shrink-0">
                        {formatFileSize(file.file.size)}
                      </span>
                    </div>

                    {/* Progress Bar */}
                    {file.status === 'uploading' && (
                      <div className="mt-1">
                        <Progress percent={file.progress} size="sm" />
                      </div>
                    )}

                    {/* Status Messages */}
                    {file.status === 'completed' && (
                      <p className="text-xs text-green-600 dark:text-green-400 mt-1">
                        ✓ Upload completed
                      </p>
                    )}
                    {file.status === 'error' && (
                      <div className="mt-1">
                        <p className="text-xs text-red-600 dark:text-red-400 font-medium">
                          ✗ {file.error || 'Upload failed'}
                        </p>
                        {file.errorDetail && (
                          <p className="text-xs text-red-500 dark:text-red-400 mt-0.5 leading-relaxed">
                            {file.errorDetail}
                          </p>
                        )}
                      </div>
                    )}
                  </div>

                  {(file.status === 'pending' || file.status === 'error') && (
                    <Button
                      variant="plain"
                      size="xs"
                      icon={<HiXMark />}
                      onClick={() => removeFile(file.id)}
                      disabled={uploading}
                      className="ml-2 flex-shrink-0"
                    />
                  )}
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Footer */}
        <div className="flex justify-between items-center pt-4 border-t">
          <div className="text-sm text-gray-500 dark:text-gray-400">
            {uploading && (
              <span>
                Uploading files... {completedFiles > 0 && `(${completedFiles} completed)`}
              </span>
            )}
            {!uploading && !hasError && pendingFiles > 0 && (
              <span className="text-green-600">Ready to upload {pendingFiles} file(s)</span>
            )}
            {!uploading && !hasError && pendingFiles === 0 && totalFiles === 0 && (
              <span className="text-gray-500">No files selected</span>
            )}
          </div>

          <div className="flex space-x-2">
            {hasError && !uploading && (
              <Button
                variant="plain"
                onClick={clearErrorFiles}
                className="text-red-600 hover:text-red-700"
              >
                Clear Errors
              </Button>
            )}
            <Button variant="default" onClick={handleClose} disabled={uploading}>
              {uploading ? 'Uploading...' : 'Close'}
            </Button>
            <Button
              variant="solid"
              onClick={handleUpload}
              disabled={pendingFiles === 0 || uploading}
              loading={uploading}
            >
              {uploading ? 'Uploading...' : `Upload ${pendingFiles} File(s)`}
            </Button>
          </div>
        </div>
      </div>
    </Dialog>
  )
})

FileUploadModal.displayName = 'FileUploadModal'

export default FileUploadModal
