import React, { useState, useEffect, useMemo } from "react";
import { supabase } from "@/config/supabase";
import {
  Upload,
  Button,
  message,
  List,
  Switch,
  Space,
  Input,
  Tag,
  Modal,
  Image,
  Popconfirm,
} from "antd";
import {
  UploadOutlined,
  FileTextOutlined,
  FileImageOutlined,
  FileMarkdownOutlined,
  FilePdfOutlined,
  FileWordOutlined,
  FileExcelOutlined,
  InboxOutlined,
  SearchOutlined,
  EditOutlined,
} from "@ant-design/icons";
import MonacoEditor from "@monaco-editor/react";
import InfiniteScroll from 'react-infinite-scroll-component';

const { Dragger } = Upload;
const { Search } = Input;

// 文件类型配置
const FILE_TYPES = {
  图片: ["image/jpeg", "image/png", "image/gif", "image/svg+xml"],
  文档: [
    "application/pdf",
    "application/msword",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "text/plain",
    "text/markdown",
  ],
  表格: [
    "application/vnd.ms-excel",
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "text/csv",
  ],
  代码: [
    "text/html",
    "text/javascript",
    "text/css",
    "application/json",
    "text/jsx",
    "text/tsx",
  ],
};

const StorageManager = () => {
  const [allFiles, setAllFiles] = useState([]);
  const [loading, setLoading] = useState(false);
  const [selectedFile, setSelectedFile] = useState(null);
  const [fileContent, setFileContent] = useState("");
  const [isPreview, setIsPreview] = useState(false);
  const [searchText, setSearchText] = useState("");
  const [selectedType, setSelectedType] = useState("全部");
  const [hasMore, setHasMore] = useState(true);
  const [displayFiles, setDisplayFiles] = useState([]);
  const INITIAL_LOAD_SIZE = 200;  // 初始加载200条
  const LOAD_MORE_SIZE = 100;     // 每次加载100条
  const [isRenaming, setIsRenaming] = useState(false);
  const [newFileName, setNewFileName] = useState("");

  // 文件图标映射
  const getFileIcon = (file) => {
    const mimetype = file.metadata?.mimetype;
    const iconMap = {
      "text/plain": <FileTextOutlined />,
      "text/markdown": <FileMarkdownOutlined />,
      "application/pdf": <FilePdfOutlined />,
      "application/msword": <FileWordOutlined />,
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
        <FileWordOutlined />,
      "application/vnd.ms-excel": <FileExcelOutlined />,
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": (
        <FileExcelOutlined />
      ),
    };

    if (mimetype?.startsWith("image/")) {
      return <FileImageOutlined />;
    }

    return iconMap[mimetype] || <FileTextOutlined />;
  };

  // 获取所有文件
  const fetchAllFiles = async (isInitial = true) => {
    setLoading(true);
    try {
      const { data, error } = await supabase.storage
        .from("file")
        .list("", {
          limit: isInitial ? INITIAL_LOAD_SIZE : LOAD_MORE_SIZE,
          offset: isInitial ? 0 : displayFiles.length,
          sortBy: { column: "created_at", order: "desc" },
        });

      if (error) throw error;
      if (isInitial) {
        setDisplayFiles(data || []);
      } else {
        setDisplayFiles(prev => [...prev, ...(data || [])]);
      }

      
      setHasMore(data?.length === (isInitial ? INITIAL_LOAD_SIZE : LOAD_MORE_SIZE));
    } catch (error) {
      message.error(`获取文件列表失败: ${error.message}`);
    } finally {
      setLoading(false);
    }
  };

  // 获取文件URL
  const getFileUrl = (fileName) => {
    const { data } = supabase.storage.from("file").getPublicUrl(fileName);
    return data.publicUrl;
  };

  // 预览文件
  const previewFile = async (file) => {
    try {
      // Handle PDF and other binary files
      if (file.metadata?.mimetype === 'application/pdf' || 
          file.metadata?.mimetype.includes('msword') ||
          file.metadata?.mimetype.includes('spreadsheet')) {
        window.open(getFileUrl(file.name), '_blank');
        return;
      }

      // Existing preview logic for text files
      const { data, error } = await supabase.storage
        .from("file")
        .download(file.name);

      if (error) throw error;

      const content = await data.text();
      setSelectedFile(file);
      setFileContent(content);
    } catch (error) {
      message.error("文件预览失败");
    }
  };

  // 上传文件配置
  const uploadProps = {
    name: "file",
    multiple: true,
    showUploadList: false,
    customRequest: async ({ file, onSuccess, onError }) => {
      try {
        const fileName = file.name;
        // 检查文件是否存在
        const fileExists = allFiles.some((f) => f.name === fileName);

        if (fileExists) {
          throw new Error("文件已存在");
        }

        const { data, error } = await supabase.storage
          .from("file")
          .upload(fileName, file);

        if (error) throw error;

        message.success(`${fileName} 上传成功`);
        onSuccess(data);
        fetchAllFiles();
      } catch (error) {
        message.error(`${file.name} 上传失败: ${error.message}`);
        onError(error);
      }
    },
    beforeUpload: (file) => {
      const isLt50M = file.size / 1024 / 1024 < 50;
      if (!isLt50M) {
        message.error("文件必须小于 50MB!");
        return false;
      }
      return true;
    },
  };

  // 文件过滤逻辑
  const filteredFiles = useMemo(() => {
    return displayFiles.filter((file) => {
      const matchesSearch = file.name
        .toLowerCase()
        .includes(searchText.toLowerCase());
      
      if (selectedType === "全部") return matchesSearch;

      const mimetype = file.metadata?.mimetype;
      const matchesType = FILE_TYPES[selectedType]?.includes(mimetype);
      
      return matchesSearch && matchesType;
    });
  }, [displayFiles, searchText, selectedType]);

  // 当前页的文件
 

  // 获取文件类型统计
  const typeStats = useMemo(() => {
    const stats = { 全部: displayFiles.length };
    
    // 初始化所有类型的计数为0
    Object.keys(FILE_TYPES).forEach(type => {
      stats[type] = 0;
    });

    // 统计每个文件的类型
    displayFiles.forEach((file) => {
      const mimetype = file.metadata?.mimetype;
      let counted = false;

      // 遍历所有文件类型配置
      Object.entries(FILE_TYPES).forEach(([type, mimetypes]) => {
        if (mimetypes.includes(mimetype)) {
          stats[type]++;
          counted = true;
        }
      });

      // 如果文件类型不在预定义类型中，归类为"其他"
      if (!counted) {
        stats['其他']++;
      }
    });

    return stats;
  }, [displayFiles]);

  

  useEffect(() => {
    fetchAllFiles();
  }, []);

  // 判断是否是图片
  const isImage = (file) => {
    return file.metadata?.mimetype?.startsWith("image/");
  };

  // 判断是否是HTML
  const isHtml = (file) => {
    return file.metadata?.mimetype === "text/html"||file.metadata?.mimetype === "text/plain";
  };

  // 保存文件内容
  const handleSaveContent = async () => {
    if (!selectedFile) return;

    try {
      // 创建 Blob 对象
      const blob = new Blob([fileContent], { type: "text/plain" });
      const file = new File([blob], selectedFile.name, { type: "text/plain" });

      // 上��更新后的文件
      const { error } = await supabase.storage
        .from("file")
        .update(selectedFile.name, file);

      if (error) throw error;

      message.success("保存成功");
      fetchAllFiles(); // 刷新文件列表
    } catch (error) {
      console.error("保存文件错误:", error);
      message.error(`保存失败: ${error.message}`);
    }
  };

  // 更新编辑器内容
  const handleEditorChange = (value) => {
    setFileContent(value);
  };

  // 处理重命名
  const handleRename = async () => {
    if (!selectedFile || !newFileName) return;

    try {
      // 检查新文件名是否已存在
      const fileExists = allFiles.some((f) => f.name === newFileName);
      if (fileExists) {
        throw new Error("文件名已存在");
      }

      // 获取原文件内容
      const { data: fileData, error: downloadError } = await supabase.storage
        .from("file")
        .download(selectedFile.name);

      if (downloadError) throw downloadError;

      // 创建新文件
      const { error: uploadError } = await supabase.storage
        .from("file")
        .upload(newFileName, fileData);

      if (uploadError) throw uploadError;

      // 删除旧文件
      const { error: deleteError } = await supabase.storage
        .from("file")
        .remove([selectedFile.name]);

      if (deleteError) throw deleteError;

      message.success("重命名成功");
      setIsRenaming(false);
      setSelectedFile({ ...selectedFile, name: newFileName });
      fetchAllFiles();
    } catch (error) {
      console.error("重命名错误:", error);
      message.error(`重命名失败: ${error.message}`);
    }
  };

  // 开始重命名
  const startRename = () => {
    setNewFileName(selectedFile.name);
    setIsRenaming(true);
  };
  // 添加文件删除功能
  const handleDelete = async (fileName) => {
    try {
      const { error } = await supabase.storage.from("file").remove([fileName]);
      if (error) throw error;
      message.success("文件删除成功");
      fetchAllFiles();
      if (selectedFile?.name === fileName) {
        setSelectedFile(null);
        setFileContent("");
      }
    } catch (error) {
      message.error(`删除失败: ${error.message}`);
    }
  };

  // 判断是否有过滤条件
  const hasFilters = useMemo(() => {
    return searchText !== '' || selectedType !== '全部';
  }, [searchText, selectedType]);

  // 加载更多数据
  const loadMoreFiles = () => {
    if (!hasMore || loading || hasFilters) return; // 有过滤条件时不加载更多
    fetchAllFiles(false);
  };

  // 初始化加载
  useEffect(() => {
    fetchAllFiles(true);
  }, []);

  // 搜索或筛选时重新加载
  const handleSearch = (value) => {
    setSearchText(value);
    // 不需要重新调用 fetchAllFiles，因为搜索是在前端过滤
  };

  const handleTypeChange = (type) => {
    setSelectedType(type);
    // 不需要重新调用 fetchAllFiles，因为类型筛选是在前端过滤
  };

  // 渲染文件列表
  const renderFileList = () => (
    <div className="flex-1 overflow-y-auto" id="scrollableDiv">
      <InfiniteScroll
        dataLength={displayFiles.length}
        next={loadMoreFiles}
        hasMore={!hasFilters && hasMore} // 只在没有过滤条件时显示加载更多
        loader={
          <div className="text-center py-4">
            <div className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent" />
          </div>
        }
        scrollableTarget="scrollableDiv"
        endMessage={
          <p className="text-center text-gray-500 py-4">
            {displayFiles.length > 0 
              ? hasFilters 
                ? "已显示所有匹配文件" 
                : "已加载全部文件" 
              : "暂无文件"}
          </p>
        }
      >
        <List
          loading={loading && displayFiles.length === 0}
          dataSource={filteredFiles}
          locale={{ emptyText: "暂无文件" }}
          renderItem={(file) => (
            <List.Item
              className={`cursor-pointer hover:bg-gray-100 ${
                selectedFile?.name === file.name ? "bg-blue-50" : ""
              }`}
              onClick={() => previewFile(file)}
              actions={[
                <Popconfirm
                  key="delete"
                  title="确认删除"
                  description={`是否确认删除文件 "${file.name}"?`}
                  onConfirm={(e) => {
                    e?.stopPropagation();
                    handleDelete(file.name);
                  }}
                  okText="确认"
                  cancelText="取消"
                >
                  <Button
                    type="text"
                    danger
                    onClick={(e) => e.stopPropagation()}
                  >
                    删除
                  </Button>
                </Popconfirm>,
              ]}
            >
              <List.Item.Meta
                avatar={
                  isImage(file) ? (
                    <Image
                      src={getFileUrl(file.name)}
                      alt={file.name}
                      width={32}
                      height={32}
                      className="object-cover rounded"
                      preview={false}
                      loading="lazy"
                      placeholder={
                        <div className="w-8 h-8 bg-gray-200 rounded animate-pulse" />
                      }
                    />
                  ) : (
                    getFileIcon(file)
                  )
                }
                title={file.name}
                description={
                  <div className="text-xs text-gray-500">
                    <span>类型: {file.metadata?.mimetype}</span>
                    <span className="ml-2">
                      大小: {(file.metadata?.size / 1024).toFixed(2)} KB
                    </span>
                    <span className="ml-2">
                      创建时间: {new Date(file.created_at).toLocaleString()}
                    </span>
                  </div>
                }
              />
            </List.Item>
          )}
        />
      </InfiniteScroll>
    </div>
  );

  // 渲染文件类型标签
  const renderTypeTags = () => (
    <div className="flex flex-wrap gap-2">
      {Object.entries({ 全部: null, ...FILE_TYPES }).map(([type]) => (
        <Tag.CheckableTag
          key={type}
          checked={selectedType === type}
          onChange={(checked) => handleTypeChange(checked ? type : "全部")}
          className="cursor-pointer"
        >
          {`${type} (${typeStats[type] || 0})`}
        </Tag.CheckableTag>
      ))}
    </div>
  );

  return (
    <div className="flex h-screen bg-gray-50">
      {/* 左侧文件列表 */}
      <div className="w-1/3  p-2 border-r border-gray-200 flex flex-col">
        <div className="mb-4 h-[150px]">
          <Dragger
            {...uploadProps}
            className="bg-white  p-2 rounded-lg shadow-sm"
          >
            <p className="text-base">点击或者拖拽文件到此区域上传</p>
            <p className="ant-upload-hint text-xs text-gray-500">
              支持单个或批量上传，文件大小不超过50MB
            </p>
          </Dragger>
        </div>

        {/* 搜索和筛选区域 */}
        <div className="mb-4 space-y-3">
          <Search
            placeholder="搜索文件名..."
            allowClear
            onChange={(e) => {
              setSearchText(e.target.value);
            }}
            className="w-full"
            size="large"
          />
          {renderTypeTags()}
        </div>

        {/* 文件列表 */}
        {renderFileList()}
      </div>

      {/* 右侧预览区域 */}
      <div className="flex-1 p-4 overflow-y-auto bg-white">
        {selectedFile ? (
          <>
            <div className="mb-4 border-b pb-4">
              <Space size="middle" align="center">
                <Space>
                  <span className="font-medium text-lg">
                    {selectedFile.name}
                  </span>
                  <Button
                    type="text"
                    icon={<EditOutlined />}
                    onClick={startRename}
                  />
                </Space>
                {isHtml(selectedFile) && (
                  <Switch
                    checkedChildren="预览"
                    unCheckedChildren="代码"
                    checked={isPreview}
                    onChange={setIsPreview}
                  />
                )}
                {!isImage(selectedFile) && (
                  <Button type="primary" onClick={handleSaveContent}>
                    保存
                  </Button>
                )}
              </Space>
            </div>

            <div className="mt-4">
              {isImage(selectedFile) ? (
                <div className="flex justify-center">
                  <Image
                    src={getFileUrl(selectedFile.name)}
                    alt={selectedFile.name}
                    className="max-w-full max-h-[80vh] object-contain"
                    loading="lazy"
                    preview={{
                      toolbarRender: () => null, // 隐藏底部工具栏
                      maskClassName: "backdrop-blur-sm",
                    }}
                    placeholder={
                      <div className="w-full h-[80vh] bg-gray-100 rounded flex items-center justify-center">
                        <div className="w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" />
                      </div>
                    }
                  />
                </div>
              ) : isHtml(selectedFile) ? (
                isPreview ? (
                  <iframe
                    srcDoc={fileContent}
                    className="w-full h-[calc(100vh-200px)] border rounded"
                  />
                ) : (
                  <MonacoEditor
                    height="calc(100vh - 200px)"
                    language="html"
                    theme="vs-light"
                    value={fileContent}
                    onChange={handleEditorChange}
                    options={{
                      minimap: { enabled: true },
                    }}
                  />
                )
              ) : (
                <MonacoEditor
                  height="calc(100vh - 200px)"
                  language="plaintext"
                  theme="vs-light"
                  value={fileContent}
                  onChange={handleEditorChange}
                  options={{
                    minimap: { enabled: false },
                  }}
                />
              )}
            </div>
          </>
        ) : (
          <div className="h-full flex items-center justify-center text-gray-400">
            选择文件以预览
          </div>
        )}
      </div>

      {/* 重命名对话框 */}
      <Modal
        title="重命名文件"
        open={isRenaming}
        onOk={handleRename}
        onCancel={() => setIsRenaming(false)}
        okText="确认"
        cancelText="取消"
      >
        <Input
          value={newFileName}
          onChange={(e) => setNewFileName(e.target.value)}
          placeholder="请输入新文件名"
          autoFocus
        />
      </Modal>
    </div>
  );
};

export default StorageManager;
