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,
  Tag,
  Tooltip,
} from "antd";
import type { MenuProps } from "antd";
import { Icon, useRequest } from "umi";
import {
  AppstoreOutlined,
  MenuOutlined,
  MoreOutlined,
} from "@ant-design/icons";
import {
  FlowchartMindMapList,
  AddFolder,
  EditFolder,
  DeleteFolder,
  Move,
  Copy,
  GetAllFolders,
} from "@/api/systemDesigner";
import ProjectCard from "./ProjectCard";
import { graphOptions } from "./data";
import { GraphType } from "@/enum";
import DragItem from "./DragItem";
import DropItem from "./DropItem";
import { createNew, listToTree } from "@/utils";

type BreadcrumbItem = {
  title: React.ReactNode;
  index: number;
  id: string;
  onClick: () => void;
};
export default function All({
  onChangeCurrentFolder,
  updateKey,
}: {
  onChangeCurrentFolder: (id: string) => void;
  updateKey: number;
}) {
  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 [graphType, setGraphType] = useState<GraphType | "">("");
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(12);
  const [open, setOpen] = useState(false);
  const currentFolder = useRef("root");
  const { confirm } = Modal;
  const moveSource = useRef<{ id: string; type: "folder" | "chart" }>();
  const [folderList, setFolderList] = useState<any[]>([]);
  const [selectFolder, setSelectFolder] = useState("");

  const { loading, run, refresh } = useRequest(FlowchartMindMapList, {
    defaultParams: [
      {
        currentPage,
        pageSize,
        filters: [
          {
            name: "name",
            value: searchName,
          },
          {
            name: "folderId",
            value: currentFolder.current,
          },
        ],
      },
    ],
    onSuccess: (res) => {
      const result = res?.result || {};
      setDataSource(result?.pageList?.model || []);
      setFolderData(result?.folders || []);
      setTotal(result?.pageList?.totalCount || 0);
    },
  });

  const { refresh: refreshFolderAll } = useRequest(GetAllFolders, {
    onSuccess: (res) => {
      setFolderList(res?.result || []);
    },
  });

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

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

  // 面包屑点击
  const handleBreadcrumbClick = (index: number) => {
    const folderItem = breadcrumbDataRef.current[index];
    if (currentFolder.current === folderItem.id) return;
    currentFolder.current = folderItem.id;

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

    updateCurrentFolderAndGetData(folderItem.id);
  };
  const defultData = [
    {
      title: (
        <span className="ant-breadcrumb-link">
          <a>我的文件</a>
        </span>
      ),
      index: 0,
      id: "root",
      onClick: () => {
        handleBreadcrumbClick(0);
      },
    },
  ];

  const [breadcrumbData, setBreadcrumbData] =
    useState<BreadcrumbItem[]>(defultData);
  const breadcrumbDataRef = useRef<BreadcrumbItem[]>(breadcrumbData);

  const getData = (page: number, pageSize: number, type?: GraphType | "") => {
    setCurrentPage(page);
    setPageSize(pageSize);
    run({
      currentPage: page,
      pageSize: pageSize,
      filters: [
        {
          name: "searchText",
          value: searchName,
        },
        {
          name: "folderId",
          value: currentFolder.current,
        },
        {
          name: "type",
          value: type !== undefined ? type : graphType,
        },
      ],
    });
  };

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

  const root = {
    id: "root",
    name: "我的文件",
    key: "root",
    title: (
      <span>
        我的文件
        {currentFolder.current === "root" ? (
          <span className="text-12px color-#999">(当前)</span>
        ) : null}
      </span>
    ),
    icon: <FolderIcon />,
    parentId: "",
    children: [],
  };

  // 构建文件夹树
  const folderTreeData = useMemo((): TreeDataNode[] => {
    return [
      listToTree(
        folderList.map((item) => {
          return {
            ...item,
            key: item.id,
            title: (
              <span>
                {item.name}
                {currentFolder.current === item.id ? (
                  <span className="text-12px color-#999">(当前)</span>
                ) : null}
              </span>
            ),
            icon: <FolderIcon />,
          };
        }),
        root
      ),
    ] as unknown as TreeDataNode[];
  }, [folderList, currentFolder.current]);

  const contextMenu: MenuProps["items"] = [
    {
      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 () => {
            await AddFolder({
              parentId: currentFolder.current,
              name,
            });
            message.success("添加成功");
            refresh();
          },
        });
      },
    },
    { type: "divider" },
    {
      key: "2",
      label: <span className="ml-4px">流程图</span>,
      icon: <Icon icon="local:flow" width="22px" />,
      onClick: async () => {
        await createNew(GraphType.flowchart, currentFolder.current);
        getData(1, pageSize);
      },
    },
    {
      key: "3",
      label: <span className="ml-4px">思维导图</span>,
      icon: <Icon icon="local:mind" width="22px" />,
      onClick: async () => {
        await createNew(GraphType.mindmap, currentFolder.current);
        getData(1, pageSize);
      },
    },
  ];

  // 更新当前文件夹并获取数据
  const updateCurrentFolderAndGetData = (folderId: string) => {
    currentFolder.current = folderId;
    getData(1, pageSize);
  };

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

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

  // 搜索图形类型
  const setSearchGraphType = (type: GraphType | "") => {
    setGraphType(type);
    getData(1, pageSize, type);
  };

  const handleOpenFolderModal = (id: string, type: "folder" | "chart") => {
    moveSource.current = {
      id,
      type,
    };
    setOpen(true);
  };

  const setMoveSource = (id: string, type: "folder" | "chart") => {
    moveSource.current = {
      id,
      type,
    };
    setOpen(false);
  };

  const handleMove = (targetFolderId: string) => {
    if (!moveSource.current || targetFolderId === moveSource.current?.id)
      return;
    Move({
      fileType: moveSource.current.type,
      fileId: moveSource.current.id,
      targetFolderId,
    }).then(() => {
      message.success("移动成功");
      refresh();
      setOpen(false);
    });
    if (moveSource.current?.type === "folder") {
      refreshFolderAll();
    }
  };

  const handleCopy = (targetFolderId: string) => {
    if (!moveSource.current || targetFolderId === moveSource.current?.id)
      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={[]}
      >
        <div className="flex justify-between items-center m-b-12px">
          <Breadcrumb items={breadcrumbData} />
          <div className="right flex gap-12px">
            <Input
              placeholder="搜索文件"
              prefix={<i className="iconfont icon-chazhao" />}
              value={searchName}
              onChange={(e) => {
                setSearchName(e.target.value);
              }}
              onPressEnter={handleSearch}
            />
            <span>
              {graphType ? (
                <Tag
                  color="#108ee9"
                  closable
                  onClose={() => setSearchGraphType("")}
                >
                  {graphOptions.find((item) => item.value === graphType)?.label}
                </Tag>
              ) : (
                <Dropdown
                  menu={{
                    items: graphOptions.map((item) => {
                      return {
                        key: item.key,
                        label: item.label,
                        value: item.value,
                        onClick: () => {
                          setSearchGraphType(item.value);
                        },
                      };
                    }),
                  }}
                >
                  <Button icon={<i className="iconfont icon-shaixuan" />} />
                </Dropdown>
              )}
            </span>
            <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 ? (
                  <>
                    <div className="flex gap-12px flex-wrap">
                      {folderData.map((item, index) => {
                        return (
                          <DragItem
                            key={index}
                            title={item.name}
                            onDragStart={() => {
                              setMoveSource(item.id, "folder");
                            }}
                            onDragEnd={() => {
                              clearMoveSource();
                            }}
                          >
                            <DropItem
                              onDrop={() => {
                                handleMove(item.id);
                              }}
                            >
                              <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>
                                      <Dropdown
                                        menu={{
                                          items: [
                                            {
                                              key: "1",
                                              label: "重命名",
                                              onClick: () => {
                                                let name = item.name;
                                                confirm({
                                                  title: "重命名",
                                                  centered: true,
                                                  icon: <></>,
                                                  content: (
                                                    <Input
                                                      defaultValue={name}
                                                      onChange={(e) => {
                                                        name = e.target.value;
                                                      }}
                                                    />
                                                  ),
                                                  onOk: async () => {
                                                    await EditFolder({
                                                      id: item.id,
                                                      name,
                                                    });
                                                    refresh();
                                                    refreshFolderAll;
                                                    message.success(
                                                      "重命名成功"
                                                    );
                                                  },
                                                });
                                              },
                                            },
                                            {
                                              key: "2",
                                              label: "移动/复制",
                                              onClick: () => {
                                                handleOpenFolderModal(
                                                  item.id,
                                                  "folder"
                                                );
                                              },
                                            },
                                            {
                                              key: "3",
                                              label: "删除",
                                              onClick: () => {
                                                confirm({
                                                  title: "删除",
                                                  content: "确定删除该文件夹？",
                                                  centered: true,
                                                  onOk: async () => {
                                                    await DeleteFolder({
                                                      id: item.id,
                                                    });
                                                    message.success("删除成功");
                                                    refresh();
                                                    refreshFolderAll();
                                                  },
                                                });
                                              },
                                            },
                                          ],
                                          onClick: (e) => {
                                            e.domEvent.stopPropagation();
                                          },
                                        }}
                                      >
                                        <MoreOutlined
                                          className="hidden group-hover/item:inline-block"
                                          onClick={(e) => e.stopPropagation()}
                                        />
                                      </Dropdown>
                                    </span>
                                  }
                                />
                              </Card>
                            </DropItem>
                          </DragItem>
                        );
                      })}
                    </div>
                  </>
                ) : null}
                <Row gutter={[8, 16]}>
                  {dataSource.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.id, "chart");
                          }}
                          onDragEnd={() => {
                            clearMoveSource();
                          }}
                        >
                          <ProjectCard
                            record={item}
                            onFresh={refresh}
                            onDelete={refresh}
                            onChangeLocation={() =>
                              handleOpenFolderModal(item.id, "chart")
                            }
                          />
                        </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>
                {dataSource.length == 0 ? (
                  <Empty description="暂无数据" />
                ) : null}
              </>
            ) : (
              <ProTable
                loading={loading}
                columns={[
                  {
                    title: "名称",
                    dataIndex: "name",
                  },
                  {
                    title: "类型",
                    dataIndex: "type",
                  },
                  {
                    title: "修改时间",
                    dataIndex: "updatedTime",
                    sorter: (a, b) => a.updateTime - b.updateTime,
                  },
                ]}
                dataSource={dataSource}
                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.current}
            >
              移动
            </Button>
            <Button type="primary" onClick={() => handleCopy(selectFolder)}>
              复制
            </Button>
          </div>
        }
      >
        <div className="min-h-300px">
          <Tree
            treeData={folderTreeData}
            selectedKeys={[selectFolder]}
            onSelect={(keys) => setSelectFolder(keys[0] as string)}
            showIcon
            blockNode
            autoExpandParent
          />
        </div>
      </Modal>
    </>
  );
}
