/**
 * DragDropUpload Component
 * Provides drag & drop file upload with preview and progress tracking
 */

import { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { AlertCircle, CheckCircle2, Upload, X } from 'lucide-react';
import { Button } from '@/components/ui/button';

interface FilePreview {
  file: File;
  preview: string;
  progress: number;
  status: 'idle' | 'uploading' | 'success' | 'error';
  error?: string;
}

interface DragDropUploadProps {
  onUpload: (files: File[]) => Promise<void>;
  acceptedFileTypes?: Record<string, string[]>;
  maxSize?: number; // in bytes
  maxFiles?: number;
}

export function DragDropUpload({
  onUpload,
  acceptedFileTypes = {
    'audio/*': ['.mp3', '.wav', '.flac', '.m4a', '.ogg'],
    'image/*': ['.jpg', '.jpeg', '.png', '.gif', '.webp'],
  },
  maxSize = 100 * 1024 * 1024, // 100MB
  maxFiles = 10,
}: DragDropUploadProps) {
  const [filePreviews, setFilePreviews] = useState<FilePreview[]>([]);
  const [isUploading, setIsUploading] = useState(false);

  const onDrop = useCallback(
    async (acceptedFiles: File[], rejectedFiles: any[]) => {
      // Handle rejected files
      if (rejectedFiles.length > 0) {
        console.warn('Some files were rejected:', rejectedFiles);
      }

      // Create previews for accepted files
      const newPreviews: FilePreview[] = acceptedFiles.map((file) => ({
        file,
        preview: URL.createObjectURL(file),
        progress: 0,
        status: 'idle' as const,
      }));

      setFilePreviews((prev) => [...prev, ...newPreviews]);

      // Start upload if not already uploading
      if (!isUploading && newPreviews.length > 0) {
        setIsUploading(true);
        await handleUpload(newPreviews.map((fp) => fp.file));
        setIsUploading(false);
      }
    },
    [isUploading]
  );

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: acceptedFileTypes,
    maxSize,
    maxFiles,
    multiple: true,
  });

  const handleUpload = async (files: File[]) => {
    try {
      // Update status to uploading
      setFilePreviews((prev) =>
        prev.map((fp) =>
          files.includes(fp.file) ? { ...fp, status: 'uploading' } : fp
        )
      );

      // Simulate progress
      files.forEach((file) => {
        const interval = setInterval(() => {
          setFilePreviews((prev) =>
            prev.map((fp) =>
              fp.file === file && fp.status === 'uploading'
                ? { ...fp, progress: Math.min(fp.progress + 10, 90) }
                : fp
            )
          );
        }, 200);

        setTimeout(() => clearInterval(interval), 2000);
      });

      // Upload files
      await onUpload(files);

      // Update status to success
      setFilePreviews((prev) =>
        prev.map((fp) =>
          files.includes(fp.file)
            ? { ...fp, status: 'success', progress: 100 }
            : fp
        )
      );

      // Clear after 2 seconds
      setTimeout(() => {
        setFilePreviews((prev) =>
          prev.filter((fp) => !files.includes(fp.file))
        );
      }, 2000);
    } catch (error) {
      console.error('Upload failed:', error);

      // Update status to error
      setFilePreviews((prev) =>
        prev.map((fp) =>
          files.includes(fp.file)
            ? { ...fp, status: 'error', error: 'Upload failed' }
            : fp
        )
      );
    }
  };

  const removeFile = (file: File) => {
    setFilePreviews((prev) => prev.filter((fp) => fp.file !== file));
  };

  return (
    <div className="w-full">
      {/* Drop Zone */}
      <div
        {...getRootProps()}
        className={`
          border-2 border-dashed rounded-lg p-8 text-center cursor-pointer
          transition-colors duration-200
          ${
            isDragActive
              ? 'border-primary-500 bg-primary-50 dark:bg-primary-900/20'
              : 'border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500'
          }
        `}
      >
        <input {...getInputProps()} />
        <Upload className="w-12 h-12 mx-auto mb-4 text-gray-400" />
        <p className="text-lg font-medium mb-2">
          {isDragActive
            ? 'Déposer les fichiers ici'
            : 'Glissez-déposez vos fichiers ici'}
        </p>
        <p className="text-sm text-gray-500">
          ou cliquez pour sélectionner
        </p>
        <p className="text-xs text-gray-400 mt-2">
          Maximum {maxFiles} fichiers, {maxSize / (1024 * 1024)}MB par fichier
        </p>
      </div>

      {/* File Previews */}
      {filePreviews.length > 0 && (
        <div className="mt-6 space-y-3">
          {filePreviews.map((preview, index) => (
            <div
              key={index}
              className="flex items-center gap-4 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg"
            >
              {/* Preview Image/Audio */}
              {preview.file.type.startsWith('image/') && (
                <img
                  src={preview.preview}
                  alt={preview.file.name}
                  className="w-16 h-16 rounded object-cover"
                />
              )}
              {preview.file.type.startsWith('audio/') && (
                <div className="w-16 h-16 rounded bg-primary-500 flex items-center justify-center text-white">
                  <Upload className="w-8 h-8" />
                </div>
              )}

              {/* File Info */}
              <div className="flex-1 min-w-0">
                <p className="text-sm font-medium truncate">{preview.file.name}</p>
                <p className="text-xs text-gray-500">
                  {(preview.file.size / (1024 * 1024)).toFixed(2)} MB
                </p>

                {/* Progress Bar */}
                {preview.status === 'uploading' && (
                  <div className="mt-2 w-full bg-gray-200 dark:bg-gray-700 rounded-full h-1.5">
                    <div
                      className="bg-primary-500 h-1.5 rounded-full transition-all"
                      style={{ width: `${preview.progress}%` }}
                    />
                  </div>
                )}
              </div>

              {/* Status Icon */}
              <div className="flex items-center gap-2">
                {preview.status === 'success' && (
                  <CheckCircle2 className="w-5 h-5 text-green-500" />
                )}
                {preview.status === 'error' && (
                  <AlertCircle className="w-5 h-5 text-red-500" />
                )}
                {preview.status === 'idle' ||
                  (preview.status === 'uploading' && (
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => removeFile(preview.file)}
                    >
                      <X className="w-4 h-4" />
                    </Button>
                  ))}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

