import React, { useEffect, useMemo, useRef, useState } from "react";
import {
  Layout,
  Menu,
  Button,
  Descriptions,
  Input,
  Tooltip,
  Empty,
  Spin,
  Modal,
} from "antd";
import { ProDescriptions } from "@ant-design/pro-components";
import type { DescriptionsProps, MenuProps } from "antd";
import { DownOutlined, PlusOutlined, SearchOutlined } from "@ant-design/icons";
import TableEdit from "@/components/TableEdit";
import ER from "./components/ER";
import AddTable from "@/components/AddTable";
import { useModel, useRequest, useParams } from "umi";
import { GetDataModelDetail } from "@/api";
import NoData from "@/assets/no-data.png";
import { ColumnItem, ProjectInfo, TableItemType } from "@/type";
import { useFullscreen, useLocalStorageState } from "ahooks";
import AddModel from "@/components/AddModel";
import insertCss from "insert-css";
import LangInput from "@/components/LangInput";
import LangInputTextarea from "@/components/LangInputTextarea";
import { validateAliasName, validateTableCode } from "@/utils/validator";
import SyncModal from "@/components/SyncModal";
import AICreator from "@/components/ai/AICreator";

const { Content, Header } = Layout;
export default function index() {
  const [active, setActive] = useState(0);
  const [showNavigator, setShowNavigator] = useState(true);
  const addTableRef = useRef<{ open: () => void }>();
  const {
    project,
    setProject,
    setPlayModeEnable,
    exitPlayMode,
    updateTable,
    graph,
    onCreateByAi
  } = useModel("erModel");
  const [searchKeyword, setSearchKeyword] = useState("");
  const [selectKey, setSelectKey] = useState<string>(
    project.tables?.[0]?.table?.id || ""
  );
  const erRef = useRef<HTMLDivElement>(null);
  const addModelRef = useRef<{ edit: (info: ProjectInfo) => void }>();
  const syncModalRef = useRef<{ open: () => void }>();
  const [isFullscreen, { enterFullscreen, exitFullscreen }] =
    useFullscreen(erRef);
  const [collapsed, setCollapsed] = useState(true);
  const [seachColumn, setSearchColumn] = useState("");

  // 双击选中表数据
  const [selectTableItem, setSelectTableItem] = React.useState<TableItemType>();
  const [open, setOpen] = useState(false);

  useEffect(() => {
    graph?.on("node:dblclick", (args) => {
      const data = args.node.getData();
      if (data?.isTable) {
        setOpen(true);
        setSelectTableItem(data);
      }
    });
  }, [graph]);

  useEffect(() => {
    insertCss(`
      .ant-descriptions-header {
        margin-bottom: ${collapsed ? "0 !important" : "20px !important"};
      }
    `);
  }, [collapsed]);

  useEffect(() => {
    setPlayModeEnable(true);
    graph?.disableKeyboard();
  }, [project, graph]);

  useEffect(() => {
    // 监听浏览器tab切换 刷新数据
    const handleVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        refresh();
      }
    };
    document.addEventListener("visibilitychange", handleVisibilityChange);
    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange);
    };
  });

  const params = useParams();

  const { run, loading, refresh } = useRequest(GetDataModelDetail, {
    manual: true,
    onSuccess: (res) => {
      console.log("模型详情:", res);
      const result = res?.result;
      setSelectKey(result?.tables?.[0]?.table?.id || "");
      if (result) {
        setProject(result, false, true);
        graph?.centerContent();
      }
    },
  });

  const [hideDefaultColumn, setHideDefaultColumn] = useLocalStorageState(
    "er-hideDefaultColumn",
    {
      defaultValue: false,
      listenStorageChange: true,
    }
  );

  useEffect(() => {
    if (params?.id) {
      run({ id: params.id });
    }
  }, []);

  const descItems: DescriptionsProps["items"] = useMemo(() => {
    return [
      {
        key: "1",
        label: "模型名称",
        children: project?.name || "-",
      },
      {
        key: "2",
        label: "创建用户",
        children: project?.createdByName || "-",
      },
      {
        key: "3",
        label: "创建时间",
        children: project?.createTime || "-",
      },
      // {
      //   key: "5",
      //   label: "发布状态",
      //   children: project?.publishStatus || "-",
      // },
      {
        key: "4-1",
        label: "更新用户",
        children: project?.updateByName || "-",
      },
      {
        key: "4",
        label: "更新时间",
        children: project?.updateTime || "-",
      },
      {
        key: "6",
        label: "表",
        children: `${project.tables.length}张`,
      },
      {
        key: "7",
        label: "描述",
        children: project?.description || "-",
      },
    ];
  }, [project]);

  const tableData: MenuProps["items"] = useMemo(() => {
    const { tables } = project;
    const treeList: {
      key: string;
      label: string | React.ReactNode;
      icon: React.ReactNode;
      children?: MenuProps["items"];
    }[] = [];

    tables
      .filter((item) => {
        const tableName = item.table.langNameList?.find(
          (item) => item.name === "zh-CN"
        )?.value;
        return (
          item.table.schemaName.includes(searchKeyword) ||
          tableName?.includes(searchKeyword)
        );
      })
      .forEach((item) => {
        const name = item.table.langNameList?.find(
          (item) => item.name === "zh-CN"
        )?.value;
        const newItem = {
          key: item.table.id,
          label: item.table.schemaName + `${name ? `(${name})` : ""}`,
          icon: <i className="iconfont icon-biaogebeifen" />,
        };
        if (!item.table.parentBusinessTableId) {
          treeList.push(newItem);
        } else {
          const parent = treeList.find(
            (tableItem) => tableItem?.key === item.table.parentBusinessTableId
          );
          if (parent) {
            if (!parent?.children) {
              parent.children = [];
            }
            parent.children?.push(newItem);
          }
        }
      });
    return treeList;
  }, [project, searchKeyword]);

  const currentTable = useMemo(() => {
    return project.tables.find((item) => item.table.id === selectKey);
  }, [project, selectKey]);

  const currentColumns = useMemo(() => {
    return (currentTable?.tableColumnList || []).filter((item) => {
      if (seachColumn) {
        return item.langName?.includes(seachColumn);
      }
      return true;
    });
  }, [currentTable, seachColumn]);

  // 处理添加表
  const handleAddTable = (tables: TableItemType[]) => {
    setProject({
      ...project,
      tables: [...tables, ...project.tables],
    });
    setSelectKey(tables[0].table.id);
    graph?.select(tables[0].table.id);
  };

  const handleEnterFullscreen = () => {
    enterFullscreen();
  };
  const handleExitFullscreen = () => {
    exitFullscreen();
  };

  const handleSelectTable = (key: string) => {
    graph?.resetSelection(key);
    graph?.centerCell(graph.getCellById(key));
    setSelectKey(key);
  };

  const handleEnterEdit = () => {
    const { origin, pathname } = window.location;
    const enterpriseCode = sessionStorage.getItem("enterpriseCode");
    window.open(
      `${origin}${pathname}#/er/${project.id}?enterpriseCode=${enterpriseCode}`
    );
  };

  // 修改表格字段
  const handleChangeColumn = (columns: readonly ColumnItem[]) => {
    currentTable &&
      updateTable({
        ...currentTable,
        tableColumnList: [...columns],
      });
  };

  // 修改表格字段
  const handleChangeSelectTableColumn = (columns: readonly ColumnItem[]) => {
    selectTableItem &&
      updateTable({
        ...selectTableItem,
        tableColumnList: [...columns],
      });
  };

  // 同步数据表
  const handleSync = () => {
    syncModalRef.current?.open();
  };

  const extra = (
    <div className="flex gap-12px">
      <a onClick={handleSync}>
        <i className="iconfont icon-tongbu text-12px mr-4px" />
        数据表同步
      </a>
      <a onClick={() => project.id && addModelRef.current?.edit(project)}>
        <i className="iconfont icon-bianji text-12px mr-4px" />
        基础信息
      </a>
      <a onClick={handleEnterEdit}>
        <i className="iconfont icon-bianji text-12px mr-4px" />
        模型编辑
      </a>
      <a>
        <i className="iconfont icon-moban text-14px mr-4px" />
        保存为模板
      </a>
    </div>
  );

  // const handleAiCreate = async (data: any) => {
  //   await onCreateByAi(data);
  //   refresh();
  // }

  return (
    <Spin spinning={loading}>
      {/* 基础信息修改弹窗 */}
      <AddModel
        ref={addModelRef}
        onChange={(info) => {
          typeof info === "object" && setProject(info);
        }}
      />
      {/* 同步弹窗 */}
      <SyncModal ref={syncModalRef} onPush={refresh} />
      <Layout className="h-100vh flex flex-col bg-#fafafa p-12px">
        <Header
          className="shadow-sm"
          style={{
            backgroundColor: "#fff",
            padding: 16,
            height: "auto",
            borderRadius: 8,
            // boxShadow: "0 2px 4px rgba(0, 0, 0, 0.15)",
            marginBottom: 12,
          }}
        >
          <Descriptions
            title={
              <span>
                <svg className="iconfont w-14px h-14px m-r-4px">
                  <use xlinkHref="#icon-shujumoxing" />
                </svg>
                {project?.name || "-"}
                <Button
                  type="text"
                  className={!collapsed ? "rotate-180" : ""}
                  icon={<DownOutlined />}
                  onClick={() => setCollapsed(!collapsed)}
                />
              </span>
            }
            items={collapsed ? [] : descItems}
            extra={extra}
          ></Descriptions>
        </Header>

        <Content className="flex-1 overflow-auto flex gap-12px">
          <div className="left w-300px shrink-0 h-full shadow-sm bg-#fff rounded-8px overflow-y-auto">
            <div
              className="
              flex 
              justify-between
              header-tit 
              p-x-16px 
              p-y-12px 
              text-16px 
              font-bold 
              text-rgba(0, 0, 0, 0.88) 
              border-b-1px 
              border-b-#eee 
              border-b-solid"
            >
              <div>
                <svg className="iconfont w-14px h-14px m-r-4px">
                  <use xlinkHref="#icon-biaoge" />
                </svg>
                <span>数据表</span>
              </div>
              <div>
                <Input
                  placeholder="搜索"
                  className="w-100px m-r-4px"
                  suffix={<SearchOutlined />}
                  value={searchKeyword}
                  onChange={(e) => setSearchKeyword(e.target.value)}
                />
                <Tooltip title="添加数据表">
                  <Button
                    type="primary"
                    icon={<PlusOutlined />}
                    onClick={() => addTableRef.current?.open()}
                  ></Button>
                </Tooltip>
              </div>
            </div>
            <Menu
              mode="inline"
              items={tableData}
              selectedKeys={[selectKey]}
              onSelect={({ key }) => handleSelectTable(key)}
            />
            {!tableData.length && (
              <Empty image={NoData} description="点击+添加数据表！" />
            )}
          </div>
          <div className="right flex-1 overflow-hidden h-full shadow-sm bg-#fff rounded-8px p-12px flex flex-col">
            <div className="head flex justify-between">
              <div className="left flex gap-8px">
                <Button
                  type={active === 0 ? "primary" : "default"}
                  onClick={() => setActive(0)}
                >
                  ER图
                </Button>
                <Button
                  type={active === 1 ? "primary" : "default"}
                  onClick={() => setActive(1)}
                >
                  实体
                </Button>
                <AICreator
                  position={{
                    // bottom: 10,
                    right: 10,
                    top: 20
                  }}
                  // onChange={handleAiCreate}
                  trigger={
                    <Button
                      type="text"
                      icon={
                        <svg
                          className="icon color-#666"
                          aria-hidden="true"
                        >
                          <use xlinkHref="#icon-AI1"></use>
                        </svg>
                      }
                    >
                      AI助手
                    </Button>
                  }
                />
              </div>
              <div className="right flex gap-8px m-b-12px">
                {active === 0 ? (
                  <>
                    {/* <Input placeholder="搜索" suffix={<SearchOutlined />} /> */}
                    <Button
                      type={!hideDefaultColumn ? "primary" : "default"}
                      onClick={() => setHideDefaultColumn(!hideDefaultColumn)}
                    >
                      默认字段
                    </Button>
                    <Button
                      type={showNavigator ? "primary" : "default"}
                      onClick={() => setShowNavigator(!showNavigator)}
                      icon={<i className="iconfont icon-xiaoditu text-14px" />}
                    >
                      导航
                    </Button>
                    <Button
                      type="primary"
                      icon={
                        <i className="iconfont icon-quanping_o text-14px" />
                      }
                      onClick={handleEnterFullscreen}
                    >
                      全屏
                    </Button>
                  </>
                ) : (
                  <>
                    <Input
                      placeholder="搜索"
                      suffix={<SearchOutlined />}
                      value={seachColumn}
                      onChange={(e) => setSearchColumn(e.target.value)}
                    />
                  </>
                )}
              </div>
            </div>
            <div className="content w-full flex-1 overflow-auto">
              {active === 0 ? (
                <div
                  className="er w-full h-full bg-#ccc overflow-auto"
                  ref={erRef}
                >
                  <ER
                    showNavigator={showNavigator}
                    isFullScreen={isFullscreen}
                    onExitFullscreen={handleExitFullscreen}
                    onChangeShowNavigator={setShowNavigator}
                  />
                </div>
              ) : (
                <div>
                  <div className="p-y-10px p-l-20px">
                    <ProDescriptions
                      title={currentTable?.table.schemaName}
                      dataSource={currentTable?.table}
                      editable={{
                        onSave: async (keypath, newInfo, oriInfo) => {
                          currentTable &&
                            updateTable({
                              ...currentTable,
                              table: {
                                ...currentTable?.table,
                                ...newInfo,
                                langName: "",
                                langDescription: "",
                              },
                            });
                          return true;
                        },
                      }}
                      columns={[
                        {
                          label: "类型",
                          dataIndex: "type",
                          valueType: "select",
                          valueEnum: {
                            3: "业务表",
                            2: "流程表",
                          },
                          editable: false,
                        },
                        {
                          label: "编码",
                          dataIndex: "schemaName",
                          valueType: "text",
                          formItemProps: {
                            rules: [
                              { required: true, message: "请输入编码" },
                              validateTableCode,
                            ],
                          },
                        },
                        {
                          label: "别名",
                          dataIndex: "aliasName",
                          valueType: "text",
                          formItemProps: {
                            rules: [
                              { required: true, message: "请输入别名" },
                              validateAliasName,
                            ],
                          },
                        },
                        {
                          label: "名称",
                          dataIndex: "langNameList",
                          render: (_, record) => {
                            return (
                              record.langNameList?.find(
                                (item) => item.name === "zh-CN"
                              )?.value || "-"
                            );
                          },
                          renderFormItem: (_schema, config, form) => {
                            return (
                              <LangInput
                                style={{ width: 200 }}
                                onChange={(val) =>
                                  form.setFieldValue("langNameList", val)
                                }
                              />
                            );
                          },
                        },
                        {
                          label: "描述",
                          dataIndex: "langDescriptionList",
                          render: (_, record) => {
                            return (
                              record?.langDescriptionList?.find(
                                (item) => item.name === "zh-CN"
                              )?.value || "-"
                            );
                          },
                          renderFormItem: (_schema, config, form) => {
                            return (
                              <>
                                <LangInputTextarea
                                  value={form.getFieldValue(
                                    "langDescriptionList"
                                  )}
                                  onChange={(val) =>
                                    form.setFieldValue(
                                      "langDescriptionList",
                                      val
                                    )
                                  }
                                />
                              </>
                            );
                          },
                        },
                      ]}
                    ></ProDescriptions>
                  </div>
                  <TableEdit
                    key={selectKey}
                    data={currentColumns}
                    tableId={currentTable?.table?.id}
                    onChange={handleChangeColumn}
                  />
                </div>
              )}
            </div>
          </div>
        </Content>
        <Modal
          title="字段详情"
          width={"80%"}
          open={open}
          footer={(_, { CancelBtn }) => {
            return <CancelBtn />;
          }}
          onCancel={() => {
            setOpen(false);
            setSelectTableItem(undefined);
          }}
        >
          <TableEdit
            key={selectTableItem?.table.id}
            tableId={selectTableItem?.table?.id}
            data={selectTableItem?.tableColumnList || []}
            modelId={project.id}
            onChange={handleChangeSelectTableColumn}
          />
        </Modal>
        <AddTable ref={addTableRef} onChange={handleAddTable} />
      </Layout>
    </Spin>
  );
}
