import { useCallback, useState } from "react";
import { Upload, Music, X, FileAudio, Loader2, Files } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { ScrollArea } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";

interface BatchFile {
  id: string;
  file: File;
  status: "pending" | "uploading" | "ready" | "error";
  duration?: number;
  waveformData?: number[];
}

interface BatchUploadZoneProps {
  files: BatchFile[];
  isLoading?: boolean;
  maxFiles?: number;
  onFilesAdd: (files: File[]) => void;
  onFileRemove: (id: string) => void;
  onClearAll: () => void;
}

export function BatchUploadZone({
  files,
  isLoading = false,
  maxFiles = 10,
  onFilesAdd,
  onFileRemove,
  onClearAll,
}: BatchUploadZoneProps) {
  const [isDragging, setIsDragging] = useState(false);

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

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

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

      const droppedFiles = Array.from(e.dataTransfer.files).filter(
        (file) => file.type === "audio/mpeg" || file.type === "audio/mp3" || file.name.endsWith(".mp3")
      );
      
      if (droppedFiles.length > 0) {
        const remainingSlots = maxFiles - files.length;
        const filesToAdd = droppedFiles.slice(0, remainingSlots);
        if (filesToAdd.length > 0) {
          onFilesAdd(filesToAdd);
        }
      }
    },
    [files.length, maxFiles, onFilesAdd]
  );

  const handleFileInput = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const selectedFiles = Array.from(e.target.files || []);
      if (selectedFiles.length > 0) {
        const remainingSlots = maxFiles - files.length;
        const filesToAdd = selectedFiles.slice(0, remainingSlots);
        if (filesToAdd.length > 0) {
          onFilesAdd(filesToAdd);
        }
      }
      e.target.value = "";
    },
    [files.length, maxFiles, onFilesAdd]
  );

  const formatDuration = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}:${secs.toString().padStart(2, "0")}`;
  };

  const formatFileSize = (bytes: number) => {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  };

  const readyCount = files.filter((f) => f.status === "ready").length;
  const uploadingCount = files.filter((f) => f.status === "uploading").length;

  return (
    <div className="space-y-4">
      <Card
        className={cn(
          "relative flex flex-col items-center justify-center p-6 transition-all duration-200 min-h-[120px]",
          isDragging && "bg-accent/50",
          files.length < maxFiles && "border-dashed border-2",
          isDragging ? "border-chart-2" : "border-border"
        )}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        data-testid="batch-upload-zone"
      >
        {files.length >= maxFiles ? (
          <div className="flex flex-col items-center gap-2 text-muted-foreground">
            <Files className="h-8 w-8" />
            <p className="text-sm">Maximum {maxFiles} files reached</p>
          </div>
        ) : (
          <>
            <input
              type="file"
              accept="audio/mpeg,.mp3"
              multiple
              onChange={handleFileInput}
              className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
              data-testid="input-batch-files"
            />
            <div className="flex flex-col items-center gap-3 pointer-events-none">
              <div className="p-3 rounded-full bg-accent/50 text-chart-2">
                <Upload className="h-6 w-6" />
              </div>
              <div className="text-center">
                <p className="font-medium text-sm">Drop MP3 files here</p>
                <p className="text-xs text-muted-foreground">
                  or click to browse (max {maxFiles} files)
                </p>
              </div>
            </div>
          </>
        )}
      </Card>

      {files.length > 0 && (
        <Card className="p-4">
          <div className="flex items-center justify-between mb-3">
            <div className="flex items-center gap-2">
              <Files className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium">
                {readyCount} of {files.length} files ready
              </span>
              {uploadingCount > 0 && (
                <span className="text-xs text-muted-foreground flex items-center gap-1">
                  <Loader2 className="h-3 w-3 animate-spin" />
                  {uploadingCount} uploading...
                </span>
              )}
            </div>
            <Button
              variant="ghost"
              size="sm"
              onClick={onClearAll}
              disabled={isLoading}
              className="text-muted-foreground"
              data-testid="button-clear-batch"
            >
              <X className="h-4 w-4 mr-1" />
              Clear All
            </Button>
          </div>
          
          <ScrollArea className="h-[200px]">
            <div className="space-y-2 pr-4">
              {files.map((batchFile) => (
                <div
                  key={batchFile.id}
                  className="flex items-center gap-3 p-2 rounded-md bg-accent/30"
                  data-testid={`batch-file-${batchFile.id}`}
                >
                  <div className={cn(
                    "p-2 rounded-full",
                    batchFile.status === "ready" ? "bg-green-500/20 text-green-600" :
                    batchFile.status === "uploading" ? "bg-yellow-500/20 text-yellow-600" :
                    batchFile.status === "error" ? "bg-red-500/20 text-red-600" :
                    "bg-muted text-muted-foreground"
                  )}>
                    {batchFile.status === "uploading" ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <FileAudio className="h-4 w-4" />
                    )}
                  </div>
                  
                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-medium truncate">
                      {batchFile.file.name}
                    </p>
                    <div className="flex items-center gap-2 text-xs text-muted-foreground">
                      <span>{formatFileSize(batchFile.file.size)}</span>
                      {batchFile.duration !== undefined && (
                        <>
                          <span className="text-border">|</span>
                          <span>{formatDuration(batchFile.duration)}</span>
                        </>
                      )}
                    </div>
                  </div>
                  
                  <Button
                    variant="ghost"
                    size="icon"
                    onClick={() => onFileRemove(batchFile.id)}
                    disabled={isLoading || batchFile.status === "uploading"}
                    className="h-8 w-8 text-muted-foreground"
                    data-testid={`button-remove-batch-${batchFile.id}`}
                  >
                    <X className="h-4 w-4" />
                  </Button>
                </div>
              ))}
            </div>
          </ScrollArea>
        </Card>
      )}
    </div>
  );
}
