'use client'

// React Imports
import { useEffect, useState } from 'react'

// MUI Imports
import type { BoxProps } from '@mui/material/Box'
import Button from '@mui/material/Button'
import IconButton from '@mui/material/IconButton'
import List from '@mui/material/List'
import ListItem from '@mui/material/ListItem'
import Typography from '@mui/material/Typography'
import { styled } from '@mui/material/styles'

// Third-party Imports
import { useDropzone } from 'react-dropzone'

// Component Imports
import Link from '@components/Link'
import CustomAvatar from '@core/components/mui/Avatar'

// Styled Component Imports
import AppReactDropzone from '@/libs/styles/AppReactDropzone'

type FileProp = {
  name: string
  type: string
  size: number
}

interface ImageUploadProps {
  // Required props
  onUpload: (file: File) => Promise<string> | string // Returns image URL

  // Optional customization props
  title?: string | null // Made nullable
  currentImageUrl?: string
  onImageRemove?: () => void
  onImageChange?: (url: string) => void

  // Upload state
  isUploading?: boolean

  // UI customization
  maxFileSize?: number // in bytes
  acceptedFileTypes?: string[]
  showUrlOption?: boolean
  uploadButtonText?: string
  browseButtonText?: string
  dragDropText?: string
  replaceText?: string

  // Style customization
  className?: string
  disabled?: boolean
}

// Styled Dropzone Component
const Dropzone = styled(AppReactDropzone)<BoxProps>(({ theme }) => ({
  '& .dropzone': {
    minHeight: 'unset',
    padding: theme.spacing(12),
    [theme.breakpoints.down('sm')]: {
      paddingInline: theme.spacing(5)
    },
    '&+.MuiList-root .MuiListItem-root .file-name': {
      fontWeight: theme.typography.body1.fontWeight
    }
  }
}))

const ImageUpload: React.FC<ImageUploadProps> = ({
  onUpload,
  title = null, // Default to null
  currentImageUrl = '',
  onImageRemove,
  onImageChange,
  isUploading = false,
  maxFileSize = 5 * 1024 * 1024, // 5MB default
  acceptedFileTypes = ['image/*'],
  showUrlOption = true,
  uploadButtonText = 'Upload',
  browseButtonText = 'Browse Image',
  dragDropText = 'Drag and Drop Your Image Here.',
  replaceText = 'Drop New Image to Replace',
  className = '',
  disabled = false
}) => {
  // States
  const [files, setFiles] = useState<File[]>([])
  const [error, setError] = useState<string>('')

  const handleUpload = async () => {
    if (!files.length) return

    try {
      setError('')
      const imageUrl = await onUpload(files[0])

      if (typeof imageUrl === 'string') {
        onImageChange?.(imageUrl)
        setFiles([]) // Clear files after successful upload
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Upload failed')
    }
  }

  // Hooks
  const { getRootProps, getInputProps } = useDropzone({
    onDrop: (acceptedFiles: File[]) => {
      setError('')

      if (acceptedFiles.length === 0) return

      const file = acceptedFiles[0]

      // Validate file size
      if (file.size > maxFileSize) {
        setError(`File size should be less than ${formatFileSize(maxFileSize)}`)
        return
      }

      // Replace files instead of adding to them
      setFiles([file])
    },
    accept: acceptedFileTypes.reduce((acc, type) => ({ ...acc, [type]: [] }), {}),
    disabled: disabled || isUploading
  })

  const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 Bytes'
    const k = 1024
    const sizes = ['Bytes', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }

  const renderFilePreview = (file: FileProp) => {
    if (file.type.startsWith('image')) {
      return <img width={38} height={38} alt={file.name} src={URL.createObjectURL(file as any)} />
    } else {
      return <i className='tabler-file-description' />
    }
  }

  const handleRemoveFile = (file: FileProp) => {
    const filtered = files.filter((i: FileProp) => i.name !== file.name)
    setFiles(filtered)
    setError('')
  }

  const handleRemoveCurrentImage = () => {
    onImageRemove?.()
  }

  const handleRemoveAllFiles = () => {
    setFiles([])
    setError('')
  }

  const fileList = files.map((file: FileProp) => (
    <ListItem key={file.name} className='pis-4 plb-3'>
      <div className='file-details'>
        <div className='file-preview'>{renderFilePreview(file)}</div>
        <div>
          <Typography className='file-name font-medium' color='text.primary'>
            {file.name}
          </Typography>
          <Typography className='file-size' variant='body2'>
            {formatFileSize(file.size)}
          </Typography>
        </div>
      </div>
      <IconButton onClick={() => handleRemoveFile(file)} disabled={isUploading}>
        <i className='tabler-x text-xl' />
      </IconButton>
    </ListItem>
  ))

  return (
    <Dropzone className={className}>
      {/* Conditional title and URL option header */}
      {title && (
        <div className='flex justify-between items-center mb-4'>
          <Typography variant='h6' component='h2'>
            {title}
          </Typography>
          {showUrlOption && (
            <Typography component={Link} color='primary.main' className='font-medium'>
              Add media from URL
            </Typography>
          )}
        </div>
      )}

      <div {...getRootProps({ className: 'dropzone' })}>
        <input {...getInputProps()} />
        <div className='flex items-center flex-col gap-2 text-center'>
          <CustomAvatar variant='rounded' skin='light' color='secondary'>
            <i className='tabler-upload' />
          </CustomAvatar>
          <Typography variant='h4'>{currentImageUrl && !files.length ? replaceText : dragDropText}</Typography>
          <Typography color='text.disabled'>or</Typography>
          <Button variant='tonal' size='small' disabled={disabled || isUploading}>
            {browseButtonText}
          </Button>
        </div>
      </div>

      {/* Error Message */}
      {error && (
        <Typography color='error' variant='body2' className='mt-2 text-center'>
          {error}
        </Typography>
      )}

      {/* Show current image if it exists */}
      {currentImageUrl && !files.length && (
        <div className='current-image mb-4'>
          <Typography variant='subtitle2' className='mb-2'>
            Current Image:
          </Typography>
          <div className='flex items-center justify-between p-3 border border-gray-200 rounded'>
            <div className='flex items-center gap-3'>
              <img width={60} height={60} alt='Current image' src={currentImageUrl} className='rounded object-cover' />
              <div>
                <Typography className='font-medium' color='text.primary'>
                  Current image
                </Typography>
                <Typography variant='body2' color='text.secondary'>
                  Uploaded image
                </Typography>
              </div>
            </div>
            {onImageRemove && (
              <IconButton onClick={handleRemoveCurrentImage} color='error' disabled={isUploading}>
                <i className='tabler-x text-xl' />
              </IconButton>
            )}
          </div>
        </div>
      )}

      {/* File list and upload buttons */}
      {files.length > 0 && (
        <>
          <List>{fileList}</List>
          <div className='buttons'>
            <Button color='error' variant='tonal' onClick={handleRemoveAllFiles} disabled={isUploading}>
              Remove All
            </Button>
            <Button variant='contained' onClick={handleUpload} disabled={isUploading}>
              {isUploading ? 'Uploading...' : uploadButtonText}
            </Button>
          </div>
        </>
      )}
    </Dropzone>
  )
}

export default ImageUpload

// ===== USAGE EXAMPLES =====

// 1. Without title
// <ImageUpload
//   onUpload={handleUpload}
//   currentImageUrl={imageUrl}
//   onImageChange={setImageUrl}
//   onImageRemove={() => setImageUrl('')}
// />

// 2. With title
// <ImageUpload
//   title="Product Image"
//   onUpload={handleUpload}
//   currentImageUrl={imageUrl}
//   onImageChange={setImageUrl}
//   onImageRemove={() => setImageUrl('')}
// />

// 3. Explicitly set title to null
// <ImageUpload
//   title={null}
//   onUpload={handleUpload}
//   currentImageUrl={imageUrl}
//   onImageChange={setImageUrl}
//   onImageRemove={() => setImageUrl('')}
// />
