"use client";

import { useCallback } from "react";
import { useDropzone } from "react-dropzone";
import { motion, AnimatePresence } from "framer-motion";
import { Upload, File, X, FileVideo, FileImage, Music } from "lucide-react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { formatFileSize, getFileExtension } from "@/lib/utils";
import type { UploadedFile } from "@/types";

interface FileUploaderProps {
  onFilesDrop: (files: File[]) => void;
  files: UploadedFile[];
  onRemoveFile: (id: string) => void;
  accept?: Record<string, string[]>;
  maxSize?: number;
  maxFiles?: number;
  disabled?: boolean;
}

const defaultAccept = {
  "image/*": [".png", ".jpg", ".jpeg", ".webp"],
  "video/*": [".mp4", ".mov", ".avi", ".webm"],
  "audio/*": [".mp3", ".wav", ".ogg", ".aac"],
};

export function FileUploader({
  onFilesDrop,
  files,
  onRemoveFile,
  accept = defaultAccept,
  maxSize = 50 * 1024 * 1024, // 50MB
  maxFiles = 10,
  disabled = false,
}: FileUploaderProps) {
  const onDrop = useCallback(
    (acceptedFiles: File[]) => {
      if (disabled) return;
      onFilesDrop(acceptedFiles);
    },
    [onFilesDrop, disabled]
  );

  const { getRootProps, getInputProps, isDragActive, isDragReject } = useDropzone({
    onDrop,
    accept,
    maxSize,
    maxFiles,
    disabled,
    multiple: maxFiles > 1,
  });

  const getFileIcon = (file: File) => {
    if (file.type.startsWith("image/")) return FileImage;
    if (file.type.startsWith("video/")) return FileVideo;
    if (file.type.startsWith("audio/")) return Music;
    return File;
  };

  return (
    <div className="space-y-4">
      {/* Dropzone */}
      <div {...getRootProps()}>
        <motion.div
          whileHover={disabled ? {} : { scale: 1.01 }}
          whileTap={disabled ? {} : { scale: 0.99 }}
          className={`
            relative cursor-pointer rounded-lg border-2 border-dashed p-12 text-center transition-all
            ${
              isDragActive
                ? "border-primary bg-primary/5"
                : isDragReject
                  ? "border-destructive bg-destructive/5"
                  : "border-border hover:border-primary/50 hover:bg-accent/5"
            }
            ${disabled ? "cursor-not-allowed opacity-50" : ""}
          `}
        >
          <input {...getInputProps()} />
          <div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-primary/10">
            <Upload className="h-8 w-8 text-primary" />
          </div>
          <div className="mt-4">
            <p className="text-lg font-medium">
              {isDragActive
                ? "Drop your files here"
                : isDragReject
                  ? "File type not accepted"
                  : "Drag & drop files here"}
            </p>
            <p className="mt-2 text-sm text-muted-foreground">
              or click to browse • Max {formatFileSize(maxSize)} • Up to {maxFiles} file
              {maxFiles > 1 ? "s" : ""}
            </p>
          </div>
        </motion.div>
      </div>

      {/* File List */}
      <AnimatePresence>
        {files.length > 0 && (
          <motion.div
            initial={{ opacity: 0, height: 0 }}
            animate={{ opacity: 1, height: "auto" }}
            exit={{ opacity: 0, height: 0 }}
            className="space-y-2"
          >
            {files.map((file, index) => {
              const Icon = getFileIcon(file.file);
              return (
                <motion.div
                  key={file.id}
                  initial={{ opacity: 0, x: -20 }}
                  animate={{ opacity: 1, x: 0 }}
                  exit={{ opacity: 0, x: 20 }}
                  transition={{ delay: index * 0.05 }}
                >
                  <Card>
                    <CardContent className="flex items-center gap-4 p-4">
                      <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10">
                        <Icon className="h-5 w-5 text-primary" />
                      </div>
                      <div className="min-w-0 flex-1">
                        <p className="truncate text-sm font-medium">{file.name}</p>
                        <p className="text-xs text-muted-foreground">
                          {formatFileSize(file.size)} • {getFileExtension(file.name).toUpperCase()}
                        </p>
                      </div>
                      <Badge variant="secondary" className="shrink-0">
                        {file.file.type.split("/")[1].toUpperCase()}
                      </Badge>
                      <Button
                        variant="ghost"
                        size="icon"
                        onClick={() => onRemoveFile(file.id)}
                        disabled={disabled}
                      >
                        <X className="h-4 w-4" />
                      </Button>
                    </CardContent>
                  </Card>
                </motion.div>
              );
            })}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
