import React, { useEffect, useMemo, useRef } from "react";
import { register } from "@antv/x6-react-shape";
import { Graph, Node } from "@antv/x6";
import type { ColumnItem, TableItemType } from "@/type";
import { DATA_TYPE_OPTIONS } from "@/constants";
import { useSessionStorageState, useLocalStorageState } from "ahooks";
import { Tooltip } from "antd";

function TableNode({ node, graph }: { node: Node; graph: Graph }) {
  const { table, tableColumnList: columnsList } = node.getData<TableItemType>();
  const containerRef = useRef<HTMLDivElement>(null);
  const [showEdit, setShowEdit] = React.useState(false);
  const [_tabActiveKey, setTabActiveKey] =
    useSessionStorageState("tabs-active-key");
  const [_active, setTableActive] = useSessionStorageState("table-active");
  const [playModeEnable] = useSessionStorageState("playModeEnable", {
    listenStorageChange: true,
  });
  // 隐藏默认字段
  const [hideDefaultColumn] = useLocalStorageState(
    "er-hideDefaultColumn",
    {
      defaultValue: false,
      listenStorageChange: true
    }
  );

  const tableColumnList = useMemo(() => {
    return columnsList.filter(item => hideDefaultColumn ? !item.isPreDefined : true);
  }, [columnsList, hideDefaultColumn]);

  useEffect(() => {
    const container = containerRef.current;
    if (container?.clientHeight) {
      node.setSize(node.size().width, container.clientHeight);
    }
  }, [tableColumnList.length]);

  const hasListener = useRef(false);
  const relationSource = useRef<any>();
  useEffect(() => {
    if (!hasListener.current) {
      hasListener.current = true;
      // 参考线添加完成
      graph.on("edge:added", (args) => {
        if (args.edge.data?.type === "refer") {
          relationSource.current = args.edge.source;
        }
      });
      // 参考线移除
      graph.on("edge:removed", (args) => {
        if (args.edge.data?.type === "refer") {
          relationSource.current = undefined;
        }
      });
      graph.on("edge:connected", (args) => {
        // 连接完成后删除refer类型的连线
        if (args.edge.data?.type === "refer") {
          graph.removeEdge(args.edge);
          const target: any = args.edge.target;
          const source: any = args.edge.source;
          if (target?.cell === node.id && target?.port?.includes("port1")) {
            node.prop("add:relation", {
              source: {
                tableId: source?.cell,
                columnId: source?.port?.slice(
                  0,
                  source?.port?.indexOf("_port")
                ),
              },
              target: {
                tableId: node.id,
                columnId: target.port.slice(0, target.port.indexOf("_port")),
              },
            });
          }
        }
      });
    }
  }, []);

  const renderPort = () => {
    const ports = node.getPorts();
    ports?.forEach((item) => {
      if (!tableColumnList.find((column) => item.id?.includes(column.id))) {
        node.removePort(item);
      }
    });

    tableColumnList.forEach((item, index) => {
      if (!ports.find((port) => port.id?.includes(item.id))) {
        node.addPort({
          id: item.id + "_port1",
          group: "columnPort",
          args: {
            y: 47 + 12 + index * 28,
          },
          attrs: {
            circle: {
              r: 4,
              magnet: true,
              stroke: "#31d0c6",
              strokeWidth: 0,
              fill: "rgba(255,255,255,0)",
            },
          },
          zIndex: 5,
        });
        node.addPort({
          id: item.id + "_port2",
          group: "columnPort",
          args: {
            x: 0,
            y: 43 + index * 28,
          },
          attrs: {
            rect: {
              magnet: true,
              fill: "rgba(255,255,255, 0)",
              strokeWidth: 0,
              width: node.size().width,
              height: 27,
            },
          },
          zIndex: 0,
        });
      }
    });
  };

  // 连接桩，1用于开始连接拖拽，2用于关系连线连接
  useEffect(() => {
    renderPort();
  }, [tableColumnList]);


  // 触发添加关系操作
  // 字段位置鼠标抬起，判断有没有开始连线操作
  const handleColumnMouseUp = (record: ColumnItem) => {
    if (relationSource.current) {
      node.prop("add:relation", {
        source: {
          tableId: relationSource.current?.cell,
          columnId: relationSource.current?.port.slice(
            0,
            relationSource.current.port.indexOf("_port")
          ),
        },
        target: {
          tableId: node.id,
          columnId: record.id,
        },
      });
    }
  };

  const handleEdit = () => {
    setTabActiveKey("1");
    setTableActive(node.id);
  };

  const tableName = useMemo(() => {
    return table.langNameList?.find((item) => item.name === "zh-CN")?.value;
  }, [table]);

  const ColumnItem = ({ record }: { record: ColumnItem }) => {
    const type = DATA_TYPE_OPTIONS.find((item) => item.value === record.type);
    const columnName = record.langNameList?.find(
      (item) => item.name === "zh-CN"
    )?.value;
    return (
      <div
        className="w-full h-28px flex px-8px leading-28px overflow-hidden"
        onMouseUp={() => handleColumnMouseUp(record)}
      >
        <span className="flex-1 truncate flex items-center justify-between">
          <span className="flex items-center truncate">
            <span className=" w-8px h-8px rounded-full mr-4px shrink-0 inline-block bg-#fff border-solid border-2px border-#31d0c6" />
            <span className="flex-1 truncate">
              <Tooltip title={`${record.schemaName}${columnName ? `(${columnName})` : ""}`}>
                {record.schemaName}
                {columnName ? `(${columnName})` : ""}
              </Tooltip>
            </span>
          </span>
          <span>
            {record.isUnique ? (
              <span className="m-r-4px">
                <i className="iconfont icon-key-fill color-#efc553 m-r--4px" />
                <span className="text-12px color-#f15359">P</span>
                {/* <span className="text-12px color-#8dafd1">F</span> */}
              </span>
            ) : (
              <span>
                <i className="iconfont icon-24_beizhu color-#efc553 m-r-4px text-12px" />
              </span>
            )}
            <span>{type?.label}</span>
          </span>
        </span>
      </div>
    );
  };

  return (
    <div
      ref={containerRef}
      className="w-full border border-1px border-solid border-#333 flex flex-col overflow-hidden rounded-8px"
      onMouseEnter={() => setShowEdit(true)}
      onMouseLeave={() => setShowEdit(false)}
    >
      <div
        className="w-full h-10px bg-#eee"
        style={{ background: table.style?.color || "#eee" }}
      ></div>
      <div
        className="
          header 
          border-b-solid 
          border-b-1px 
          border-b-#333 
          bg-#e4e4e7 
          py-4px 
          font-bold 
          text-14px 
          min-h-32px 
          px-8px
          flex 
          justify-between 
          items-center
        "
      >
        <div className="truncate flex-1">
          <span className="text-12px font-normal">
            {table.parentBusinessTableId && "[子]"}
          </span>
          <Tooltip title={`table.schemaName(${tableName})`}>
            {table.schemaName}({tableName})
          </Tooltip>
        </div>
        {showEdit && !playModeEnable && (
          <div
            className="edit-btn w-22px h-22px rounded-md flex items-center justify-center bg-#658dbe cursor-pointer"
            onClick={handleEdit}
          >
            <i className="iconfont icon-bianji color-#fff text-12px" />
          </div>
        )}
      </div>
      <div className="bg-#fafafa flex-1">
        <div className="field-info">
          {tableColumnList.map((item) => {
            return <ColumnItem key={item.id} record={item} />;
          })}
        </div>
      </div>
    </div>
  );
}

register({
  shape: "table-node",
  component: TableNode,
  width: 300,
  height: 220,
  effect: ["data"],
});
