import React, { useState, useRef } from 'react';
import type { DragEvent, ChangeEvent } from 'react';
import './FileUpload.css';

interface FileUploadProps {
  onFilesSelected: (files: File[]) => void;
  accept?: string;
  multiple?: boolean;
  maxFiles?: number;
  maxFileSize?: number; // in MB
  disabled?: boolean;
  className?: string;
}

interface FileWithPreview extends File {
  preview?: string;
}

const FileUpload: React.FC<FileUploadProps> = ({
  onFilesSelected,
  accept = 'image/*',
  multiple = true,
  maxFiles = 10,
  maxFileSize = 5, // 5MB default
  disabled = false,
  className = '',
}) => {
  const [selectedFiles, setSelectedFiles] = useState<FileWithPreview[]>([]);
  const [dragOver, setDragOver] = useState(false);
  const [errors, setErrors] = useState<string[]>([]);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const validateFile = (file: File): string | null => {
    // Check file size
    if (file.size > maxFileSize * 1024 * 1024) {
      return `Datei "${file.name}" ist zu groß. Maximum: ${maxFileSize}MB`;
    }

    // Check file type
    if (!file.type.startsWith('image/')) {
      return `Datei "${file.name}" ist kein gültiges Bild`;
    }

    return null;
  };

  const processFiles = (files: FileList | File[]) => {
    const fileArray = Array.from(files);
    const newErrors: string[] = [];
    const validFiles: FileWithPreview[] = [];

    // Check total file count
    if (selectedFiles.length + fileArray.length > maxFiles) {
      newErrors.push(`Maximal ${maxFiles} Dateien erlaubt`);
      setErrors(newErrors);
      return;
    }

    fileArray.forEach((file) => {
      const error = validateFile(file);
      if (error) {
        newErrors.push(error);
      } else {
        // Create preview URL
        const fileWithPreview = file as FileWithPreview;
        fileWithPreview.preview = URL.createObjectURL(file);
        validFiles.push(fileWithPreview);
      }
    });

    if (newErrors.length > 0) {
      setErrors(newErrors);
    } else {
      setErrors([]);
      const updatedFiles = [...selectedFiles, ...validFiles];
      setSelectedFiles(updatedFiles);
      onFilesSelected(updatedFiles);
    }
  };

  const handleFileSelect = (e: ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      processFiles(e.target.files);
    }
  };

  const handleDrop = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setDragOver(false);
    
    if (disabled) return;
    
    const files = e.dataTransfer.files;
    if (files.length > 0) {
      processFiles(files);
    }
  };

  const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    if (!disabled) {
      setDragOver(true);
    }
  };

  const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setDragOver(false);
  };

  const removeFile = (index: number) => {
    const fileToRemove = selectedFiles[index];
    if (fileToRemove.preview) {
      URL.revokeObjectURL(fileToRemove.preview);
    }
    
    const updatedFiles = selectedFiles.filter((_, i) => i !== index);
    setSelectedFiles(updatedFiles);
    onFilesSelected(updatedFiles);
  };

  const clearAll = () => {
    selectedFiles.forEach(file => {
      if (file.preview) {
        URL.revokeObjectURL(file.preview);
      }
    });
    setSelectedFiles([]);
    setErrors([]);
    onFilesSelected([]);
  };

  return (
    <div className={`file-upload ${className}`}>
      {/* Drop Zone */}
      <div
        className={`drop-zone ${dragOver ? 'drag-over' : ''} ${disabled ? 'disabled' : ''}`}
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onClick={() => !disabled && fileInputRef.current?.click()}
      >
        <div className="drop-zone-content">
          <div className="upload-icon">📁</div>
          <p className="upload-text">
            {selectedFiles.length > 0 
              ? `${selectedFiles.length} Datei${selectedFiles.length > 1 ? 'en' : ''} ausgewählt`
              : 'Bilder hier ablegen oder klicken zum Auswählen'
            }
          </p>
          <p className="upload-hint">
            Maximal {maxFiles} Dateien, je max. {maxFileSize}MB
          </p>
        </div>
        
        <input
          ref={fileInputRef}
          type="file"
          accept={accept}
          multiple={multiple}
          onChange={handleFileSelect}
          disabled={disabled}
          style={{ display: 'none' }}
        />
      </div>

      {/* Error Messages */}
      {errors.length > 0 && (
        <div className="upload-errors">
          {errors.map((error, index) => (
            <div key={index} className="error-message">
              ⚠️ {error}
            </div>
          ))}
        </div>
      )}

      {/* File Previews */}
      {selectedFiles.length > 0 && (
        <div className="file-previews">
          <div className="preview-header">
            <h4>Ausgewählte Bilder ({selectedFiles.length})</h4>
            <button 
              type="button" 
              onClick={clearAll}
              className="clear-all-btn"
              disabled={disabled}
            >
              Alle entfernen
            </button>
          </div>
          
          <div className="preview-grid">
            {selectedFiles.map((file, index) => (
              <div key={index} className="file-preview">
                <div className="preview-image">
                  <img 
                    src={file.preview} 
                    alt={file.name}
                    onLoad={() => {
                      // Clean up object URL after image loads
                      if (file.preview) {
                        URL.revokeObjectURL(file.preview);
                      }
                    }}
                  />
                  <button
                    type="button"
                    className="remove-file-btn"
                    onClick={() => removeFile(index)}
                    disabled={disabled}
                  >
                    ✕
                  </button>
                </div>
                <div className="file-info">
                  <div className="file-name" title={file.name}>
                    {file.name.length > 20 ? `${file.name.substring(0, 17)}...` : file.name}
                  </div>
                  <div className="file-size">
                    {(file.size / 1024 / 1024).toFixed(2)} MB
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

export default FileUpload;