import React, { useEffect, useMemo, useRef, useState } from "react";
import {
  Layout,
  Menu,
  Button,
  Descriptions,
  Input,
  Tooltip,
  Empty,
  Spin,
} 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, history, useRequest, useParams } from "umi";
import { GetDataModelDetail } from "@/api";
import NoData from "@/assets/no-data.png";
import { ColumnItem, ProjectInfo, TableItemType } from "@/type";
import { useFullscreen } 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";

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,
  } = 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(false);

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

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

  const params = useParams();

  const { run, loading } = 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);
      }
    },
  });

  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: "4-1",
        label: "更新用户",
        children: project?.updatedBy || "-",
      },
      {
        key: "4",
        label: "更新时间",
        children: project?.updateTime || "-",
      },
      {
        key: "5",
        label: "发布状态",
        children: project?.publishStatus || "-",
      },
      {
        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 handleAddTable = (tableItem: TableItemType) => {
    setProject({
      ...project,
      tables: [...project.tables, tableItem],
    });
    setSelectKey(tableItem.table.id);
  };

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

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

  const handleEnterEdit = () => {
    exitPlayMode();
    const enterpriseCode = sessionStorage.getItem("enterpriseCode");
    history.push(`/er/${project.id}?enterpriseCode=${enterpriseCode}`);
  };

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

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

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

  return (
    <Spin spinning={loading}>
      {/* 基础信息修改弹窗 */}
      <AddModel
        ref={addModelRef}
        onChange={(info) => {
          typeof info === "object" && setProject(info);
        }}
      />
      {/* 同步弹窗 */}
      <SyncModal ref={syncModalRef} />
      <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">
            <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>
              </div>
              <div className="right flex gap-8px m-b-12px">
                {active === 0 ? (
                  <>
                    <Input placeholder="搜索" suffix={<SearchOutlined />} />
                    <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 />} />
                  </>
                )}
              </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={currentTable?.tableColumnList || []}
                    tableId={currentTable?.table?.id}
                    onChange={handleChangeColumn}
                  />
                </div>
              )}
            </div>
          </div>
        </Content>
        <AddTable ref={addTableRef} onChange={handleAddTable} />
      </Layout>
    </Spin>
  );
}
