'use client'

import * as React from 'react'
import type { UploadProgress } from '@admin/types'
import { Button } from '@admin/components/ui/button'
import { Card, CardContent } from '@admin/components/ui/card'
import { Progress } from '@admin/components/ui/progress'
import { cn } from '@admin/utils/shared/cn'
import { parseDropzoneAccept } from '@admin/utils/upload/parse-dropzone-accept'
import { GalleryVerticalEnd } from 'lucide-react'
import { useDropzone } from 'react-dropzone'

export interface UploadDropzoneHandle {
  openFileDialog: () => void
}

export interface UploadDropzoneProps {
  onFilesSelected: (files: File[]) => void
  progress: UploadProgress[]
  isUploading: boolean
  accept?: string
  multiple?: boolean
  className?: string
  disabled?: boolean
  ref?: React.Ref<UploadDropzoneHandle>
}

export function UploadDropzone({
  onFilesSelected,
  progress,
  isUploading,
  accept,
  multiple = true,
  className,
  disabled = false,
  ref
}: UploadDropzoneProps) {
  const progressPercent = React.useMemo(() => {
    if (progress.length === 0) return 0
    return Math.round(progress.reduce((sum, item) => sum + item.progress, 0) / progress.length)
  }, [progress])

  const handleDrop = React.useCallback(
    (files: File[]) => {
      if (files.length === 0) return
      onFilesSelected(files)
    },
    [onFilesSelected]
  )

  const parsedAccept = React.useMemo(() => parseDropzoneAccept(accept), [accept])

  const { getRootProps, getInputProps, isDragActive, open } = useDropzone({
    noClick: true,
    noKeyboard: true,
    multiple,
    accept: parsedAccept,
    disabled: isUploading || disabled,
    onDrop: handleDrop
  })

  React.useImperativeHandle(ref, () => ({ openFileDialog: open }), [open])

  return (
    <Card
      data-slot="upload-dropzone"
      {...getRootProps({
        className: cn(
          'flex items-center justify-center',
          {
            'bg-muted p-2 ring-1 ring-border transition-all duration-100': isDragActive,
            'cursor-not-allowed': disabled || isUploading
          },
          className
        ),
        'aria-label': 'File upload dropzone'
      })}
    >
      <CardContent className="h-full w-full">
        {isUploading ? (
          <div
            data-slot="upload-dropzone-progress"
            className="flex h-full w-full flex-col items-center justify-center gap-3 text-center"
          >
            <p className="text-sm font-medium">Uploading files…</p>
            <Progress value={progressPercent} className="mx-auto h-2 max-w-sm" />
            <p className="text-sm text-muted-foreground">{progressPercent}% complete</p>
          </div>
        ) : (
          <div
            data-slot="upload-dropzone-idle"
            className="flex h-full w-full flex-col items-center justify-center gap-3 text-center"
          >
            <Button type="button" variant="outline" onClick={open}>
              <GalleryVerticalEnd />
              Add files
            </Button>
            <p className="text-sm text-muted-foreground">
              Drag & drop images, videos, or documents here
            </p>
          </div>
        )}
        <input {...getInputProps({ className: 'hidden' })} />
      </CardContent>
    </Card>
  )
}
