import React, { useEffect, useMemo, useRef, useState } from "react";
import { ProTable, PageContainer } from "@ant-design/pro-components";
import {
  Card,
  Col,
  Row,
  Button,
  Input,
  Breadcrumb,
  Empty,
  Pagination,
  Modal,
  Tree,
  Dropdown,
  message,
  TreeDataNode,
  Tooltip,
} from "antd";
import type { MenuProps } from "antd";
import { useRequest } from "umi";
import {
  AppstoreOutlined,
  MenuOutlined,
  MoreOutlined,
  PlusOutlined,
} from "@ant-design/icons";
import { GetDataModelList, SaveDataModel } from "@/api";
import ProjectCard from "./ProjectCard";
import DragItem from "./DragItem";
import DropItem from "./DropItem";
import { TableType } from "@/enum";
import AddModel from "@/components/AddModel";
import { uuid } from "@repo/utils";
import { ProjectInfo } from "@/type";

type BreadcrumbItem = {
  title: React.ReactNode;
  index: number;
  id: string;
  onClick: () => void;
};
export default function All({
  onChangeCurrentFolder,
  updateKey,
  type,
}: {
  onChangeCurrentFolder: (id: string) => void;
  updateKey: number;
  type: TableType;
}) {
  const [display, setDisplay] = useState("card");
  // 文件夹数据
  const [folderData, setFolderData] = useState<any[]>([]);
  const [dataSource, setDataSource] = useState<any[]>([]);
  const [total, setTotal] = useState(0);
  const [searchName, setSearchName] = useState("");
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(12);
  const [open, setOpen] = useState(false);
  const [currentFolder, setCurrentFolder] = useState("");
  const { confirm } = Modal;
  const moveSource = useRef<{ data: any; type: string }>();

  const [selectFolder, setSelectFolder] = useState("");
  const addModelRef = useRef<{ open: (type: TableType, folder: string) => void }>();

  const { loading, run, refresh } = useRequest(GetDataModelList, {
    defaultParams: [
      {
        name: searchName,
        folder: "",
        type,
      },
    ],
    onSuccess: (res) => {
      const result = res?.result || {};
      setDataSource(result);
      // 创建文件夹数据
      const list = new Set((result || [])
        .map((item: ProjectInfo) => item.directory)
        .filter((name: string) => name));

      setFolderData(
        [...list].map((item) => {
          return {
            id: uuid(),
            name: item,
          };
        })
      );
      setTotal(result.length || 0);
    },
  });

  useEffect(() => {
    updateKey && getData(1, pageSize);
  }, [updateKey]);

  useEffect(() => {
    onChangeCurrentFolder(currentFolder);
  }, [currentFolder]);

  // 面包屑点击
  const handleBreadcrumbClick = (index: number) => {
    const folderItem = breadcrumbDataRef.current[index];
    setCurrentFolder(folderItem.name);

    const newData = breadcrumbDataRef.current.slice(0, index + 1);
    setBreadcrumbData(newData);
    breadcrumbDataRef.current = newData;
  };

  const defultData = [
    {
      title: (
        <span className="ant-breadcrumb-link">
          <a>{type === TableType.BusinessTable ? "业务模型" : "流程模型"}</a>
        </span>
      ),
      name: "",
      index: 0,
      id: "root",
      onClick: () => {
        handleBreadcrumbClick(0);
      },
    },
  ];

  type BreadcrumbItemType = BreadcrumbItem & { name: string };
  const [breadcrumbData, setBreadcrumbData] =
    useState<BreadcrumbItemType[]>(defultData);
  const breadcrumbDataRef = useRef<BreadcrumbItemType[]>(breadcrumbData);

  const getData = (page: number, pageSize: number) => {
    setCurrentPage(page);
    setPageSize(pageSize);
    run({
      name: searchName,
      folder: "",
      type,
    });
  };

  const FolderIcon = function () {
    return (
      <svg className="icon w-20px h-20px" aria-hidden="true">
        <use xlinkHref="#icon-weibiaoti-_huabanfuben"></use>
      </svg>
    );
  };

  // 构建文件夹树
  const folderTreeData = useMemo((): TreeDataNode[] => {
    return [
      {
        id: "root",
        name: "",
        key: "",
        title: (
          <span>
            {type === TableType.BusinessTable ? "业务模型" : "流程模型"}
            {currentFolder === "" ? (
              <span className="text-12px color-#999">(当前)</span>
            ) : null}
          </span>
        ),
        icon: <FolderIcon />,
        parentId: "",
        children: folderData.map((item) => {
          return {
            ...item,
            key: item.name,
            title: (
              <span>
                {item.name}
                {currentFolder === item.name ? (
                  <span className="text-12px color-#999">(当前)</span>
                ) : null}
              </span>
            ),
            icon: <FolderIcon />,
          };
        }),
      },
    ] as unknown as TreeDataNode[];
  }, [folderData, currentFolder]);

  const contextMenu: MenuProps["items"] = useMemo(() => {
    const folder = {
      key: "1",
      label: <span className="ml-4px">文件夹</span>,
      icon: <FolderIcon />,
      onClick: () => {
        let name = "";
        confirm({
          title: "添加文件夹",
          centered: true,
          icon: <></>,
          content: (
            <Input
              defaultValue={name}
              onChange={(e) => {
                name = e.target.value;
              }}
            />
          ),
          onOk: async () => {
            // 添加文件夹
            setFolderData([...folderData, { id: uuid(), name }]);
          },
        });
      },
    };
    const model = {
      key: "2",
      label: <span className="ml-4px">添加模型</span>,
      onClick: async () => {
        addModelRef.current?.open(type, currentFolder);
      },
      icon: (
        <svg className="iconfont w-14px h-14px m-r-4px">
          <use xlinkHref="#icon-shujumoxing" />
        </svg>
      ),
    };

    return !currentFolder ? [folder, model] : [model];
  }, [currentFolder]);

  // 计算模型数据
  const getDataSource = useMemo(() => {
    return dataSource.filter((item) => item.directory === currentFolder);
  }, [dataSource, currentFolder]);

  // 打开文件夹
  const handleOpenFolder = (folderItem: { id: string; name: string }) => {
    const newData = [
      ...breadcrumbData,
      {
        title: (
          <span className="ant-breadcrumb-link">
            <a>{folderItem.name}</a>
          </span>
        ),
        name: folderItem.name,
        index: breadcrumbData.length,
        id: folderItem.id,
        onClick: () => {
          handleBreadcrumbClick(breadcrumbData.length);
        },
      },
    ];
    setBreadcrumbData(newData);
    breadcrumbDataRef.current = newData;
    setCurrentFolder(folderItem.name);
  };

  // 搜索文件
  const handleSearch = () => {
    setCurrentPage(1);
    getData(1, pageSize);
  };

  const handleOpenFolderModal = (data: any, type: "folder" | "model") => {
    moveSource.current = {
      data,
      type,
    };
    setOpen(true);
  };

  const setMoveSource = (data: any, type: "folder" | "model") => {
    moveSource.current = {
      data,
      type,
    };
    setOpen(false);
  };

  const handleAddChange = (id: any) => {
    refresh();
    const { origin, pathname } = window.location;
    const enterpriseCode = sessionStorage.getItem("enterpriseCode");
    window.open(
      `${origin}${pathname}#/detail/${id}?enterpriseCode=${enterpriseCode}`
    );
  };

  const handleMove = (targetFolder: string) => {
    if (
      !moveSource.current ||
      targetFolder === moveSource.current?.data?.directory
    ) {
      return;
    }
    if (moveSource.current?.type === "model") {
      const newData = {
        ...moveSource.current.data,
        directory: targetFolder,
      };
      SaveDataModel({ erDataModel: newData }).then((res) => {
        setDataSource(
          dataSource.map((item) => {
            return item.id === newData.id ? newData : item;
          })
        );
        setOpen(false);
        message.success("移动成功");
      });
    }
  };

  const handleCopy = (targetFolder: string) => {
    if (
      !moveSource.current ||
      targetFolder === moveSource.current?.data?.directory
    )
      return;
    // Copy({
    //   fileType: moveSource.current.type,
    //   fileId: moveSource.current.id,
    //   targetFolderId,
    // }).then(() => {
    //   message.success("复制成功");
    //   refresh();
    //   setOpen(false);
    // });
    if (moveSource.current?.type === "folder") {
      // refreshFolderAll();
    }
  };

  const clearMoveSource = () => {
    moveSource.current = undefined;
  };

  return (
    <>
      <PageContainer
        pageHeaderRender={() => <div className="m-t-12px"></div>}
        title={false}
        footer={[]}
        loading={loading}
      >
        <div className="flex justify-between items-center m-b-12px">
          <Breadcrumb items={breadcrumbData} />
          <AddModel ref={addModelRef} onChange={handleAddChange} />
          <div className="right flex items-center gap-12px">
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={() => {
                addModelRef.current?.open(type, currentFolder);
              }}
            >
              新建
            </Button>
            <Input
              placeholder="搜索文件"
              prefix={<i className="iconfont icon-chazhao" />}
              value={searchName}
              onChange={(e) => {
                setSearchName(e.target.value);
              }}
              onPressEnter={handleSearch}
            />
            <span>
              <Tooltip title={display === "card" ? "列表模式" : "卡片模式"}>
                <Button
                  onClick={() => {
                    setDisplay(display === "card" ? "list" : "card");
                  }}
                  icon={
                    display === "card" ? <MenuOutlined /> : <AppstoreOutlined />
                  }
                />
              </Tooltip>
            </span>
          </div>
        </div>
        <Dropdown
          menu={{
            items: contextMenu,
          }}
          trigger={["contextMenu"]}
        >
          <div style={{minHeight: "calc(100vh - 78px)"}}>
            {display === "card" ? (
              <>
                {folderData.length && !currentFolder ? (
                  <>
                    <div className="flex gap-12px flex-wrap">
                      {folderData.map((item, index) => {
                        return (
                          <DragItem
                            key={index}
                            title={item.name}
                            onDragStart={() => {
                              setMoveSource(item, "folder");
                            }}
                            onDragEnd={() => {
                              clearMoveSource();
                            }}
                          >
                            <DropItem
                              onDrop={() => {
                                handleMove(item.name);
                              }}
                            >
                              <Card
                                hoverable
                                bordered
                                className="w-240px m-b-12px"
                                onClick={() => handleOpenFolder(item)}
                                key={index}
                              >
                                <Card.Meta
                                  title={
                                    <span className="flex justify-between items-center group/item">
                                      <span>
                                        <svg
                                          className="icon"
                                          aria-hidden="true"
                                        >
                                          <use xlinkHref="#icon-weibiaoti-_huabanfuben"></use>
                                        </svg>
                                        <span className="ml-8px">
                                          {item.name}
                                        </span>
                                      </span>
                                    </span>
                                  }
                                />
                              </Card>
                            </DropItem>
                          </DragItem>
                        );
                      })}
                    </div>
                  </>
                ) : null}
                <Row gutter={[8, 16]}>
                  {getDataSource.map((item, index) => {
                    return (
                      <Col
                        xs={12}
                        sm={8}
                        md={6}
                        lg={6}
                        xl={6}
                        xxl={6}
                        key={index}
                      >
                        <DragItem
                          title={item.name}
                          onDragStart={() => {
                            setMoveSource(item, "model");
                          }}
                          onDragEnd={() => {
                            clearMoveSource();
                          }}
                        >
                          <ProjectCard
                            record={item}
                            onFresh={refresh}
                            onDelete={refresh}
                            onChangeLocation={() =>
                              handleOpenFolderModal(item, "model")
                            }
                          />
                        </DragItem>
                      </Col>
                    );
                  })}
                </Row>
                <div className="flex justify-end py-16px">
                  <Pagination
                    showTotal={(total, range) =>
                      `${range[0]}-${range[1]} 共 ${total} 条`
                    }
                    total={total}
                    current={currentPage}
                    pageSize={12}
                    pageSizeOptions={["12", "24", "36"]}
                    onChange={(page, pageSize) => {
                      getData(page, pageSize);
                    }}
                    hideOnSinglePage
                  />
                </div>
                {getDataSource.length == 0 ? (
                  <Empty description="暂无数据" />
                ) : null}
              </>
            ) : (
              <ProTable
                loading={loading}
                columns={[
                  {
                    title: "名称",
                    dataIndex: "name",
                  },
                  {
                    title: "描述",
                    dataIndex: "description",
                  },
                  {
                    title: "修改时间",
                    dataIndex: "updateTime",
                    sorter: (a, b) => a.updateTime - b.updateTime,
                  },
                ]}
                dataSource={getDataSource}
                rowKey={"id"}
                search={false}
                pagination={{
                  total: total,
                  pageSize: 12,
                  current: currentPage,
                  pageSizeOptions: ["12", "24", "36"],
                  onChange: (page, pageSize) => {
                    getData(page, pageSize);
                  },
                }}
              />
            )}
          </div>
        </Dropdown>
      </PageContainer>

      <Modal
        title="移动"
        width={440}
        open={open}
        onCancel={() => {
          setOpen(false);
          setSelectFolder("");
        }}
        centered
        footer={
          <div>
            <Button className="m-r-8px" onClick={() => setOpen(false)}>
              取消
            </Button>
            <Button
              className="m-r-8px"
              type="primary"
              onClick={() => handleMove(selectFolder)}
              disabled={selectFolder === currentFolder}
            >
              移动
            </Button>
          </div>
        }
      >
        <div className="min-h-300px">
          <Tree
            treeData={folderTreeData}
            selectedKeys={[selectFolder]}
            onSelect={(keys) => setSelectFolder(keys[0] as string)}
            showIcon
            blockNode
            autoExpandParent
          />
        </div>
      </Modal>
    </>
  );
}
