import React, { useCallback, useState } from 'react';
import { Upload, Image, X } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useToast } from '@/hooks/use-toast';

interface DragDropZoneProps {
  onFilesAdded: (files: File[]) => void;
  maxFiles?: number;
  maxSizeMB?: number;
  allowedFileTypes?: string[];
  disabled?: boolean;
  className?: string;
  children?: React.ReactNode;
}

export function DragDropZone({
  onFilesAdded,
  maxFiles = 10,
  maxSizeMB = 25,
  allowedFileTypes = ['image/*'],
  disabled = false,
  className = '',
  children,
}: DragDropZoneProps) {
  const [isDragOver, setIsDragOver] = useState(false);
  const { toast } = useToast();

  const validateFiles = useCallback((files: FileList) => {
    const validFiles: File[] = [];
    const errors: string[] = [];

    Array.from(files).forEach((file) => {
      // Check file type
      const isValidType = allowedFileTypes.some(type => {
        if (type === 'image/*') {
          return file.type.startsWith('image/');
        }
        return file.type === type;
      });

      if (!isValidType) {
        errors.push(`${file.name}: Invalid file type`);
        return;
      }

      // Check file size
      if (file.size > maxSizeMB * 1024 * 1024) {
        errors.push(`${file.name}: File too large (max ${maxSizeMB}MB)`);
        return;
      }

      validFiles.push(file);
    });

    // Check total file count
    if (validFiles.length > maxFiles) {
      errors.push(`Too many files. Maximum ${maxFiles} files allowed.`);
      return { validFiles: validFiles.slice(0, maxFiles), errors };
    }

    return { validFiles, errors };
  }, [allowedFileTypes, maxSizeMB, maxFiles]);

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

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

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

    if (disabled) return;

    const files = e.dataTransfer.files;
    if (files.length === 0) return;

    const { validFiles, errors } = validateFiles(files);

    if (errors.length > 0) {
      toast({
        variant: 'destructive',
        title: 'File Validation Error',
        description: errors.join(', '),
      });
    }

    if (validFiles.length > 0) {
      onFilesAdded(validFiles);
    }
  }, [disabled, validateFiles, onFilesAdded, toast]);

  const handleFileInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    if (disabled) return;

    const files = e.target.files;
    if (!files || files.length === 0) return;

    const { validFiles, errors } = validateFiles(files);

    if (errors.length > 0) {
      toast({
        variant: 'destructive',
        title: 'File Validation Error',
        description: errors.join(', '),
      });
    }

    if (validFiles.length > 0) {
      onFilesAdded(validFiles);
    }

    // Reset input
    e.target.value = '';
  }, [disabled, validateFiles, onFilesAdded, toast]);

  if (children) {
    return (
      <div
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        className={cn(
          "relative transition-all duration-200",
          isDragOver && !disabled && "ring-2 ring-accent ring-offset-2",
          className
        )}
      >
        <input
          type="file"
          multiple
          accept={allowedFileTypes.join(',')}
          onChange={handleFileInput}
          disabled={disabled}
          className="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10"
        />
        {children}
      </div>
    );
  }

  return (
    <div
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
      className={cn(
        "relative border-2 border-dashed rounded-lg transition-all duration-200 p-8",
        isDragOver && !disabled
          ? "border-accent bg-accent/5 scale-[1.02]"
          : "border-border hover:border-accent/50",
        disabled && "opacity-50 cursor-not-allowed",
        !disabled && "cursor-pointer hover:bg-muted/50",
        className
      )}
    >
      <input
        type="file"
        multiple
        accept={allowedFileTypes.join(',')}
        onChange={handleFileInput}
        disabled={disabled}
        className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
      />
      
      <div className="text-center space-y-4">
        <div className="mx-auto w-16 h-16 bg-accent/10 rounded-full flex items-center justify-center">
          {isDragOver ? (
            <Upload className="w-8 h-8 text-accent animate-bounce" />
          ) : (
            <Image className="w-8 h-8 text-accent" />
          )}
        </div>
        
        <div className="space-y-2">
          <p className="text-lg font-medium">
            {isDragOver ? 'Drop files here' : 'Drag & drop photos here'}
          </p>
          <p className="text-sm text-muted-foreground">
            or click to browse files
          </p>
          <p className="text-xs text-muted-foreground">
            Max {maxFiles} files, {maxSizeMB}MB each
          </p>
        </div>
      </div>
    </div>
  );
}