import React, { useEffect, useMemo, useRef } from "react";
import { register } from "@antv/x6-react-shape";
import { Edge, Graph, Node } from "@antv/x6";
import type { ColumnItem, TableItemType } from "@/type";
import { DATA_TYPE_OPTIONS } from "@/constants";
import { uuid } from "@/utils";

function TableNode({ node, graph }: { node: Node; graph: Graph }) {
  const { table, tableColumnList } = node.getData<TableItemType>();
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const container = containerRef.current;
    if (container?.clientHeight) {
      node.setSize(container.clientWidth, 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")),
              },
            });
          }
        }
      });
    }
  }, []);

  // 连接桩，1用于开始连接拖拽，2用于关系连线连接
  useEffect(() => {
    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: 42 + 16 + index * 27,
          },
          attrs: {
            circle: {
              r: 4,
              magnet: true,
              stroke: "#31d0c6",
              strokeWidth: 2,
              fill: "#fff",
            },
          },
          zIndex: 5,
        });
        node.addPort({
          id: item.id + "_port2",
          group: "columnPort",
          args: {
            x: 0,
            y: 42 + index * 27,
          },
          attrs: {
            rect: {
              magnet: true,
              fill: "rgba(255,255,255,0)",
              strokeWidth: 0,
              width: node.size().width,
              height: 27,
            },
          },
          zIndex: 0,
        });
      }
    });
  }, [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 ColumnItem = ({ record }: { record: ColumnItem }) => {
    const type = DATA_TYPE_OPTIONS.find((item) => item.value === record.type);
    return (
      <div
        className="w-full flex py-4px px-8px"
        onMouseUp={() => handleColumnMouseUp(record)}
      >
        <span className="flex-1 truncate flex items-center justify-between">
          <span className="flex items-center">
            <span className=" w-6px h-6px rounded-full mr-4px bg-#5684bb inline-block cursor-pointer" />
            {record.schemaName}
            {record.cn_name ? `(${record.cn_name})` : ""}
          </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"
    >
      <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 
          truncate 
          bg-#e4e4e7 
          py-4px 
          font-bold 
          text-14px 
          min-h-32px 
          px-8px
        "
      >
        {table.schemaName}({table.cn_name})
      </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"],
});
