import { nanoid } from "../../../../../_vendor/nanoid/index.browser.js";
import { useState, useRef } from "react";
import { useEventCallback } from "../../../../../_vendor/usehooks-ts/dist-index.js";
function useDragAndDrop(options) {
  const { accept, maxSize, maxFiles, onFilesAdded, onFileRemoved, onError } = options;
  const [isDragging, setIsDragging] = useState(false);
  const [attachments, setAttachments] = useState([]);
  const fileMapRef = useRef(/* @__PURE__ */ new Map());
  const abortControllersRef = useRef(/* @__PURE__ */ new Map());
  const dragCounter = useRef(0);
  const validateFile = useEventCallback((file) => {
    if (accept.length > 0) {
      if (accept.some((a) => a.startsWith("."))) ;
      else {
        if (!accept.includes(file.type)) {
          return {
            valid: false,
            error: `File type ${file.type} is not supported`
          };
        }
      }
    }
    if (file.size > maxSize) {
      return {
        valid: false,
        error: `File size exceeds ${maxSize / 1024 / 1024}MB limit`
      };
    }
    return { valid: true };
  });
  const processFiles = useEventCallback(async (files) => {
    const fileArray = Array.from(files);
    const currentCount = attachments.length;
    if (currentCount + fileArray.length > maxFiles) {
      onError?.(`Cannot add more than ${maxFiles} files`);
      return;
    }
    const newAttachments = [];
    for (const file of fileArray) {
      const validation = validateFile(file);
      if (!validation.valid) {
        onError?.(validation.error || "Invalid file");
        continue;
      }
      const isImage = file.type.startsWith("image/");
      const attachment = {
        id: nanoid(),
        type: isImage ? "image" : "file",
        name: file.name,
        size: file.size,
        mimeType: file.type,
        url: "",
        // 初始为空，上传后更新
        uploadStatus: "pending"
      };
      if (isImage) {
        try {
          attachment.url = URL.createObjectURL(file);
        } catch (error) {
          console.error("Failed to create object URL:", error);
        }
      }
      attachment.uploadStatus = "pending";
      fileMapRef.current.set(attachment.id, file);
      newAttachments.push(attachment);
    }
    if (newAttachments.length > 0) {
      setAttachments((prev) => [...prev, ...newAttachments]);
      onFilesAdded?.(newAttachments);
    }
  });
  const removeAttachment = useEventCallback((id) => {
    setAttachments((prev) => {
      const attachment = prev.find((a) => a.id === id);
      const abortController = abortControllersRef.current.get(id);
      if (abortController && attachment?.uploadStatus === "uploading") {
        abortController.abort();
        abortControllersRef.current.delete(id);
      }
      if (attachment?.url && attachment.url.startsWith("blob:")) {
        URL.revokeObjectURL(attachment.url);
      }
      fileMapRef.current.delete(id);
      return prev.filter((a) => a.id !== id);
    });
    onFileRemoved?.(id);
  });
  const clearAttachments = useEventCallback(() => {
    abortControllersRef.current.forEach((controller) => {
      controller.abort();
    });
    abortControllersRef.current.clear();
    attachments.forEach((attachment) => {
      if (attachment.url && attachment.url.startsWith("blob:")) {
        URL.revokeObjectURL(attachment.url);
      }
    });
    setAttachments([]);
    fileMapRef.current.clear();
  });
  const getFileById = useEventCallback((id) => {
    return fileMapRef.current.get(id);
  });
  const handleDragEnter = useEventCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
    dragCounter.current++;
    if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
      setIsDragging(true);
    }
  });
  const handleDragLeave = useEventCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
    dragCounter.current--;
    if (dragCounter.current === 0) {
      setIsDragging(false);
    }
  });
  const handleDragOver = useEventCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
  });
  const handleDrop = useEventCallback((e) => {
    e.preventDefault();
    e.stopPropagation();
    dragCounter.current = 0;
    setIsDragging(false);
    const files = e.dataTransfer.files;
    if (files && files.length > 0) {
      processFiles(files);
    }
  });
  const handleFileInput = useEventCallback((e) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      processFiles(files);
    }
  });
  const handlePaste = useEventCallback((e) => {
    const items = e.clipboardData.items;
    const files = [];
    for (let i = 0; i < items.length; i++) {
      const item = items[i];
      if (item.kind === "file") {
        const file = item.getAsFile();
        if (file) {
          files.push(file);
        }
      }
    }
    if (files.length > 0) {
      processFiles(files);
    }
  });
  const updateAttachmentProgress = useEventCallback((id, progress) => {
    setAttachments(
      (prev) => prev.map(
        (attachment) => attachment.id === id ? { ...attachment, uploadProgress: progress } : attachment
      )
    );
  });
  const setAttachmentError = useEventCallback((id, error) => {
    setAttachments(
      (prev) => prev.map(
        (attachment) => attachment.id === id ? { ...attachment, error, uploadStatus: "failed" } : attachment
      )
    );
  });
  const updateAttachmentUrl = useEventCallback((id, url) => {
    setAttachments(
      (prev) => prev.map(
        (attachment) => attachment.id === id ? { ...attachment, url, uploadStatus: "completed" } : attachment
      )
    );
  });
  const updateAttachmentExtraData = useEventCallback(
    (id, extraData) => {
      setAttachments(
        (prev) => prev.map(
          (attachment) => attachment.id === id ? { ...attachment, extraData } : attachment
        )
      );
    }
  );
  const setAttachmentUploading = useEventCallback((id) => {
    setAttachments(
      (prev) => prev.map(
        (attachment) => attachment.id === id ? { ...attachment, uploadStatus: "uploading" } : attachment
      )
    );
  });
  const createAbortController = useEventCallback((id) => {
    const controller = new AbortController();
    abortControllersRef.current.set(id, controller);
    return controller;
  });
  const cleanupAbortController = useEventCallback((id) => {
    abortControllersRef.current.delete(id);
  });
  const getAbortController = useEventCallback((id) => {
    return abortControllersRef.current.get(id);
  });
  const addAttachments = useEventCallback((newAttachments) => {
    if (newAttachments.length === 0) return;
    const uniqueAttachments = newAttachments.filter((newAttachment) => {
      return !attachments.some(
        (existing) => existing.id === newAttachment.id || existing.url && newAttachment.url && existing.url === newAttachment.url
      );
    });
    if (uniqueAttachments.length > 0) {
      setAttachments((prev) => [...prev, ...uniqueAttachments]);
      onFilesAdded?.(uniqueAttachments);
    }
  });
  return {
    isDragging,
    attachments,
    handlers: {
      onDragEnter: handleDragEnter,
      onDragLeave: handleDragLeave,
      onDragOver: handleDragOver,
      onDrop: handleDrop,
      onPaste: handlePaste
    },
    processFiles,
    removeAttachment,
    clearAttachments,
    addAttachments,
    handleFileInput,
    updateAttachmentProgress,
    setAttachmentError,
    updateAttachmentUrl,
    updateAttachmentExtraData,
    setAttachmentUploading,
    getFileById,
    createAbortController,
    cleanupAbortController,
    getAbortController
  };
}
export {
  useDragAndDrop
};
//# sourceMappingURL=use-drag-and-drop.js.map
