"use client";

import { useState, useCallback, useEffect } from "react";
import { useDropzone } from "react-dropzone";
import { Upload, X } from "lucide-react";
import toast from "react-hot-toast";

interface ImageUploaderProps {
  onFilesSelected: (files: File[]) => void;
}

interface FileWithPreview extends File {
  preview: string;
}

export default function ImageUploader({ onFilesSelected }: ImageUploaderProps) {
  const [selectedFiles, setSelectedFiles] = useState<FileWithPreview[]>([]);

  const onDrop = useCallback(
    (acceptedFiles: File[], rejectedFiles: any[]) => {
      // Handle rejected files
      if (rejectedFiles.length > 0) {
        rejectedFiles.forEach(({ file, errors }) => {
          errors.forEach((error: any) => {
            switch (error.code) {
              case "file-too-large":
                toast.error(
                  `File "${file.name}" is too large. Maximum size is 10MB.`
                );
                break;
              case "file-invalid-type":
                toast.error(
                  `File "${file.name}" is not a supported image format.`
                );
                break;
              case "too-many-files":
                toast.error(
                  "Too many files selected. Please select fewer files."
                );
                break;
              default:
                toast.error(`Error with file "${file.name}": ${error.message}`);
            }
          });
        });
      }

      const imageFiles = acceptedFiles.filter(
        (file) =>
          file.type.startsWith("image/") ||
          file.type === "image/heic" ||
          file.type === "image/heif"
      );

      if (imageFiles.length !== acceptedFiles.length) {
        toast.error("Some files were ignored. Only image files are supported.");
      }

      if (imageFiles.length === 0 && rejectedFiles.length === 0) {
        toast.error("No valid image files selected.");
        return;
      }

      const filesWithPreviews = imageFiles.map((file) =>
        Object.assign(file, {
          preview: URL.createObjectURL(file),
        })
      );

      const newFiles = [...selectedFiles, ...filesWithPreviews];
      setSelectedFiles(newFiles);
      onFilesSelected(newFiles);
    },
    [selectedFiles, onFilesSelected]
  );

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    accept: {
      "image/*": [
        ".jpg",
        ".jpeg",
        ".png",
        ".gif",
        ".svg",
        ".bmp",
        ".tiff",
        ".heic",
        ".heif",
      ],
    },
    multiple: true,
    maxSize: 10 * 1024 * 1024, // 10MB max
    maxFiles: 100,
  });

  const removeFile = (index: number) => {
    const fileToRemove = selectedFiles[index];
    URL.revokeObjectURL(fileToRemove.preview);

    const newFiles = selectedFiles.filter((_, i) => i !== index);
    setSelectedFiles(newFiles);
    onFilesSelected(newFiles);
  };

  const formatFileSize = (bytes: number) => {
    if (bytes === 0) return "0 Bytes";
    const k = 1024;
    const sizes = ["Bytes", "KB", "MB", "GB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  };

  // Cleanup preview URLs
  useEffect(() => {
    return () => {
      selectedFiles.forEach((file) => URL.revokeObjectURL(file.preview));
    };
  }, [selectedFiles]);

  return (
    <div className="bg-white rounded-2xl shadow-lg p-8">
      <div className="mb-6">
        <h2 className="text-2xl font-bold text-gray-900 mb-2">Upload Images</h2>
        <p className="text-gray-600">
          Drag and drop your images or click to browse. Supports JPG, PNG, GIF,
          SVG, HEIC, BMP, TIFF.
        </p>
      </div>

      <div
        {...getRootProps()}
        className={`border-2 border-dashed rounded-xl p-12 text-center cursor-pointer transition-all ${
          isDragActive
            ? "border-blue-400 bg-blue-50"
            : "border-gray-300 hover:border-blue-400 hover:bg-gray-50"
        }`}
      >
        <input {...getInputProps()} />
        <div className="flex flex-col items-center">
          <div className="bg-gradient-to-r from-blue-500 to-purple-600 w-16 h-16 rounded-full flex items-center justify-center mb-4">
            <Upload className="w-8 h-8 text-white" />
          </div>
          {isDragActive ? (
            <p className="text-lg text-blue-600 font-medium">
              Drop your images here...
            </p>
          ) : (
            <>
              <p className="text-lg font-medium text-gray-900 mb-2">
                Drag & drop images here, or click to browse
              </p>
              <p className="text-sm text-gray-500">
                Maximum file size: 10MB per image
              </p>
            </>
          )}
        </div>
      </div>

      {selectedFiles.length > 0 && (
        <div className="mt-8">
          <h3 className="text-lg font-semibold text-gray-900 mb-4">
            Selected Files ({selectedFiles.length})
          </h3>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 max-h-96 overflow-y-auto">
            {selectedFiles.map((file, index) => (
              <div
                key={index}
                className="relative bg-gray-50 rounded-lg p-3 group"
              >
                <div className="aspect-square mb-3 bg-gray-200 rounded-lg overflow-hidden">
                  <img
                    src={file.preview}
                    alt={file.name}
                    className="w-full h-full object-cover"
                  />
                </div>
                <div className="space-y-1">
                  <p
                    className="text-sm font-medium text-gray-900 truncate"
                    title={file.name}
                  >
                    {file.name}
                  </p>
                  <p className="text-xs text-gray-500">
                    {formatFileSize(file.size)}
                  </p>
                </div>
                <button
                  onClick={() => removeFile(index)}
                  className="absolute top-2 right-2 p-1 bg-red-500 text-white rounded-full opacity-0 group-hover:opacity-100 transition-opacity hover:bg-red-600"
                >
                  <X className="w-4 h-4" />
                </button>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
