import React, {
  useState,
  useEffect,
  ChangeEvent,
  useRef,
  useCallback,
} from "react";
import { Input } from "@/components/ui/input";
import { Upload } from "lucide-react";
import { FileMeta, CustomFile } from "@/types/webrtc";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog";
// Add this declaration at the top of the file to extend existing types and avoid IDE errors
declare module "@/components/ui/input" {
  interface InputProps {
    webkitdirectory?: string | boolean;
    directory?: string | boolean;
  }
}

import { getDictionary } from "@/lib/dictionary";
import { useLocale } from "@/hooks/useLocale";
import type { Messages } from "@/types/messages";
import { en } from "@/constants/messages/en"; // Import English dictionary as default

const traverseFileTree = async (
  item: FileSystemEntry,
  path = ""
): Promise<CustomFile[]> => {
  return new Promise((resolve) => {
    // console.log('path',path)//path in ['','test/','test/sub/']
    if (item.isFile) {
      (item as FileSystemFileEntry).file((file: File) => {
        // console.log('file.name',file.name)//file.name in ['Gmail-773240713232313363.txt','link.txt','cvat-serverless部署踩坑及部署模型测试 (1).docx','images.jpg']
        // console.log('fullName',path + file.name,'folderName',path.split('/')[0])
        const customFile: CustomFile = Object.assign(file, {
          fullName: path + file.name,
          folderName: path.split("/")[0],
        });
        resolve([customFile]);
      });
    } else if (item.isDirectory) {
      const dirReader = (item as FileSystemDirectoryEntry).createReader();
      let entries: FileSystemEntry[] = [];

      const readEntries = () => {
        dirReader.readEntries(async (results) => {
          if (results.length) {
            entries = entries.concat(Array.from(results));
            readEntries();
          } else {
            const newPath = path + item.name + "/";
            const subResults = await Promise.all(
              entries.map((entry) => traverseFileTree(entry, newPath))
            );
            // console.log('subResults',subResults)
            const files: CustomFile[] = subResults.flat();
            // console.log('files',files)
            resolve(files); // Removed conditional judgment, directly return processed files
          }
        });
      };

      readEntries();
    }
  });
};

function formatFileChosen(
  template: string,
  fileNum: number,
  folderNum: number
) {
  return template
    .replace("{fileNum}", fileNum.toString())
    .replace("{folderNum}", folderNum.toString());
}

interface FileUploadHandlerProps {
  onFilePicked: (files: CustomFile[]) => void;
}

const FileUploadHandler: React.FC<FileUploadHandlerProps> = ({
  onFilePicked,
}) => {
  const locale = useLocale();
  const [messages, setMessages] = useState<Messages>(en); // Use English dictionary as initial value

  const dropZoneRef = useRef<HTMLDivElement>(null); // Drag and drop files to attachments -- support
  const folderInputRef = useRef<HTMLInputElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  // File selector -- message prompt
  const [fileText, setFileText] = useState<string>(
    en.text.fileUploadHandler.NoFileChosen_tips
  );
  const [isModalOpen, setIsModalOpen] = useState(false);

  useEffect(() => {
    if (locale !== "en") {
      // Only load other language packs if not English
      getDictionary(locale)
        .then((dict) => {
          setMessages(dict);
          setFileText(dict.text.fileUploadHandler.NoFileChosen_tips);
        })
        .catch((error) => console.error("Failed to load messages:", error));
    }
  }, [locale]);

  const handleFileChange = useCallback(
    (newFiles: CustomFile[]) => {
      // console.log(newFiles);
      onFilePicked(newFiles);

      const fileNum = newFiles.length;
      const folderNum = newFiles.filter((file) => file.folderName).length;

      const choose_dis = formatFileChosen(
        messages!.text.fileUploadHandler.fileChosen_tips_template,
        fileNum,
        folderNum
      );

      setFileText(choose_dis);
      setTimeout(
        () => setFileText(messages!.text.fileUploadHandler.NoFileChosen_tips),
        2000
      );
      // Reset the file input
      if (fileInputRef.current) {
        fileInputRef.current.value = "";
      }
    },
    [messages, onFilePicked]
  );
  // Drag and drop folder upload response processing
  const handleDrop = useCallback(
    (e: React.DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();

      const items = e.dataTransfer.items;
      if (items) {
        const itemsArray = Array.from(items);
        Promise.all(
          itemsArray.map((item) => {
            const entry = item.webkitGetAsEntry();
            if (entry) {
              return traverseFileTree(entry);
            }
            return Promise.resolve([]);
          })
        ).then((results) => {
          const allFiles = results.flat();
          handleFileChange(allFiles);
        });
      }
    },
    [handleFileChange]
  );
  /*  Define a callback function handleDragOver to handle the drag-over event.
      In handleDragOver, prevent default behavior and event propagation to ensure custom handling.
      There is no dependency array, which means the handleDragOver function will only be created once when the component first renders, and will not be re-created in subsequent renders.
    */
  const handleDragOver = useCallback((e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
  }, []);
  // Click to upload file processing
  const handleFileInputChange = useCallback(
    (e: ChangeEvent<HTMLInputElement>) => {
      if (e.target.files) {
        const files = Array.from(e.target.files);
        let files2 = [];
        for (let file of files) {
          const customFile: CustomFile = Object.assign(file, {
            fullName: file.name,
            folderName: "",
          });
          files2.push(customFile);
        }
        handleFileChange(files2);
        setIsModalOpen(false); // Close the dialog
      }
    },
    [handleFileChange]
  );
  // Click to upload folder response processing
  const handleFolderInputChange = useCallback(
    (e: ChangeEvent<HTMLInputElement>) => {
      if (e.target.files) {
        const files_ = Array.from(e.target.files);
        let files: CustomFile[] = [];

        files_.forEach((file) => {
          // console.log('file.webkitRelativePath',file.webkitRelativePath)//[test/Gmail-773240713232313363.txt,test/link.txt,test/sub/cvat-serverless部署踩坑及部署模型测试 (1).docx,test/sub/images.jpg]
          const pathParts = file.webkitRelativePath.split("/");
          const customFile: CustomFile = Object.assign(file, {
            fullName: file.webkitRelativePath,
            folderName: pathParts[0],
          });
          files.push(customFile);
        });

        handleFileChange(files);
        setIsModalOpen(false); // Close the dialog
      }
    },
    [handleFileChange]
  );

  // Handle drag and drop area click
  const handleZoneClick = () => {
    setIsModalOpen(true);
  };
  // Handle file selection
  const handleSelectFile = () => {
    fileInputRef.current?.click();
  };

  // Handle folder selection
  const handleSelectFolder = () => {
    folderInputRef.current?.click();
  };
  if (messages === null) {
    return <div>Loading...</div>;
  }
  return (
    <>
      <div
        ref={dropZoneRef}
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        className="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center cursor-pointer"
        onClick={handleZoneClick}
      >
        <p className="text-sm text-gray-600 mb-4">
          {messages.text.fileUploadHandler.Drag_tips}
        </p>
        <Upload className="h-12 w-12 mx-auto mb-4 text-blue-500" />
        <p className="text-sm text-gray-600">{fileText}</p>

        <Input
          id="file-upload"
          type="file"
          onChange={handleFileInputChange}
          multiple
          className="hidden"
          ref={fileInputRef}
        />
        <Input
          id="folder-upload"
          type="file"
          onChange={handleFolderInputChange}
          multiple
          webkitdirectory=""
          directory=""
          className="hidden"
          ref={folderInputRef}
        />
      </div>

      <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
        <DialogContent className="sm:max-w-[425px]">
          <DialogHeader>
            <DialogTitle className="text-xl font-semibold">
              {messages.text.fileUploadHandler.chosenDiagTitle}
            </DialogTitle>
            <DialogDescription className="mt-2 text-muted-foreground">
              {messages.text.fileUploadHandler.chosenDiagDescription}
            </DialogDescription>
          </DialogHeader>
          <div className="flex justify-center gap-4 mt-6">
            <button
              onClick={handleSelectFile}
              className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
            >
              {messages.text.fileUploadHandler.SelectFile_dis}
            </button>
            <button
              onClick={handleSelectFolder}
              className="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors"
            >
              {messages.text.fileUploadHandler.SelectFolder_dis}
            </button>
          </div>
        </DialogContent>
      </Dialog>
    </>
  );
};

export { FileUploadHandler };
