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

interface FileUploadZoneProps {
  label: string;
  description: string;
  type: "source" | "target";
  file: File | null;
  isLoading?: boolean;
  duration?: number;
  onFileSelect: (file: File) => void;
  onRemove: () => void;
}

export function FileUploadZone({
  label,
  description,
  type,
  file,
  isLoading = false,
  duration,
  onFileSelect,
  onRemove,
}: FileUploadZoneProps) {
  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 droppedFile = e.dataTransfer.files[0];
      if (droppedFile && (droppedFile.type === "audio/mpeg" || droppedFile.type === "audio/mp3" || droppedFile.name.endsWith(".mp3"))) {
        onFileSelect(droppedFile);
      }
    },
    [onFileSelect]
  );

  const handleFileInput = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const selectedFile = e.target.files?.[0];
      if (selectedFile) {
        onFileSelect(selectedFile);
      }
    },
    [onFileSelect]
  );

  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 accentColor = type === "source" ? "text-primary" : "text-chart-2";
  const borderColor = type === "source" 
    ? isDragging ? "border-primary" : "border-border" 
    : isDragging ? "border-chart-2" : "border-border";

  return (
    <Card
      className={cn(
        "relative flex flex-col items-center justify-center p-6 transition-all duration-200",
        file ? "min-h-[180px]" : "min-h-[200px]",
        isDragging && "bg-accent/50",
        !file && "border-dashed border-2",
        borderColor
      )}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
      data-testid={`upload-zone-${type}`}
    >
      {isLoading ? (
        <div className="flex flex-col items-center gap-3">
          <Loader2 className={cn("h-10 w-10 animate-spin", accentColor)} />
          <p className="text-sm text-muted-foreground">Processing audio...</p>
        </div>
      ) : file ? (
        <div className="flex flex-col items-center gap-4 w-full">
          <div className={cn("p-3 rounded-full bg-accent", accentColor)}>
            <FileAudio className="h-6 w-6" />
          </div>
          <div className="text-center space-y-1">
            <p className="font-medium text-sm truncate max-w-[200px]" data-testid={`text-filename-${type}`}>
              {file.name}
            </p>
            <div className="flex items-center gap-2 text-xs text-muted-foreground">
              <span>{formatFileSize(file.size)}</span>
              {duration !== undefined && (
                <>
                  <span className="text-border">|</span>
                  <span data-testid={`text-duration-${type}`}>{formatDuration(duration)}</span>
                </>
              )}
            </div>
          </div>
          <Button
            variant="ghost"
            size="sm"
            onClick={onRemove}
            className="text-muted-foreground"
            data-testid={`button-remove-${type}`}
          >
            <X className="h-4 w-4 mr-1" />
            Remove
          </Button>
        </div>
      ) : (
        <>
          <input
            type="file"
            accept="audio/mpeg,.mp3"
            onChange={handleFileInput}
            className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
            data-testid={`input-file-${type}`}
          />
          <div className="flex flex-col items-center gap-4 pointer-events-none">
            <div className={cn("p-4 rounded-full bg-accent/50", accentColor)}>
              {type === "source" ? (
                <Music className="h-8 w-8" />
              ) : (
                <Upload className="h-8 w-8" />
              )}
            </div>
            <div className="text-center space-y-1">
              <p className="font-semibold">{label}</p>
              <p className="text-sm text-muted-foreground">{description}</p>
            </div>
            <p className="text-xs text-muted-foreground">
              Drop MP3 file here or click to browse
            </p>
          </div>
        </>
      )}
    </Card>
  );
}
