import { register } from "@antv/x6-react-shape";
import { Graph, Node, EventArgs } from "@antv/x6";
import { useEffect, useMemo, useState } from "react";
import { Button, InputNumber, Popover } from "antd";
import { Icon } from "umi";

const component = ({ node, graph }: { node: Node; graph: Graph }) => {
  const { line, origin, summarySource, type } = node.getData();
  const [width, setWidth] = useState(node.size().width);
  const [height, setHeight] = useState(node.size().height);
  const [showSetting, setShowSetting] = useState(false);

  const handleResizeChange = () => {
    setWidth(node.size().width);
    setHeight(node.size().height);
  };

  useEffect(() => {
    const handleSelect = (args: EventArgs["node:selected"]) => {
      setShowSetting(args.node.id === origin);
    };
    graph.on("node:selected", handleSelect);
    graph.on("blank:click", () => setShowSetting(false));
    node.on("change:size", handleResizeChange);
    return () => {
      graph.off("node:selected", handleSelect);
      graph.off("blank:click", () => setShowSetting(false));
      node.off("change:size", handleResizeChange);
    };
  }, []);

  const linePosition = useMemo((): "left" | "right" | "top" | "bottom" => {
    const originNode = graph.getCellById(origin);
    if (originNode && originNode.isNode()) {
      const x = originNode.position().x + originNode.size().width / 2;
      const y = originNode.position().y + originNode.size().height / 2;
      if (
        x < node.position().x &&
        y > node.position().y &&
        y < node.position().y + height
      ) {
        return "left";
      }
      if (
        y > node.position().y &&
        x > node.position().x &&
        x < node.position().x + width
      ) {
        return "bottom";
      }
      if (
        y < node.position().y &&
        x > node.position().x &&
        x < node.position().x + width
      ) {
        return "top";
      }
    }
    return "right";
  }, [origin, width, height]);

  const lineStyle = useMemo(() => {
    switch (linePosition) {
      case "right":
        return {
          right: "-40px",
        };
      case "left":
        return {
          left: "-40px",
        };
      case "top":
        return {
          top: "-40px",
        };
      default:
        return {
          bottom: "-40px",
        };
    }
  }, [linePosition]);

  const rightLine = useMemo(() => {
    if (type === 2) {
      return `
        M 20 ${line.width}
        L 36 ${height / 2}
        L 20 ${height - line.width}
      `;
    }
    if (type === 3) {
      return `
        M 20 ${line.width}
        A 10 ${height / 2} 0 0 1 20 ${height - line.width}
        M 30 ${height / 2}
        L 40 ${height / 2}
        `;
    }
    if (type === 4) {
      return `
        M 20 ${line.width}
        Q 30 ${line.width} 30 10
        L 30 ${height / 2 - 10}
        Q 30 ${height / 2} 40 ${height / 2}
        Q 30 ${height / 2} 30 ${height / 2 + 10}
        L 30 ${height - 10}
        Q 30 ${height - line.width} 20 ${height - line.width}
        `;
    }
    return `
      M 20 ${line.width}
      L 30 ${line.width}
      L 30 ${height / 2}
      L 40 ${height / 2}
      L 30 ${height / 2}
      L 30 ${height - line.width}
      L 20 ${height - line.width}
      `;
  }, [type, width, height]);

  const leftLine = useMemo(() => {
    if (type === 2) {
      return `
        M 20 ${line.width}
        L 4 ${height / 2}
        L 20 ${height - line.width}
      `;
    }
    if (type === 3) {
      return `
        M 20 ${line.width}
        A 10 ${height / 2} 0 0 0 20 ${height - line.width}
        M 10 ${height / 2}
        L 0 ${height / 2}
        `;
    }
    if (type === 4) {
      return `
        M 20 ${line.width}
        Q 10 ${line.width} 10 10
        L 10 ${height / 2 - 10}
        Q 10 ${height / 2} 0 ${height / 2}
        Q 10 ${height / 2} 10 ${height / 2 + 10}
        L 10 ${height - 10}
        Q 10 ${height - line.width} 20 ${height - line.width}
        `;
    }
    return `
      M 20 ${line.width}
      L 10 ${line.width}
      L 10 ${height / 2}
      L 00 ${height / 2}
      L 10 ${height / 2}
      L 10 ${height - line.width}
      L 20 ${height - line.width}
      `;
  }, [type, width, height]);

  const topLine = useMemo(() => {
    return `
              M 20 ${line.width}
              L 30 ${line.width}
              L 30 ${height / 2}
              L 40 ${height / 2}
              L 30 ${height / 2}
              L 30 ${height - line.width}
              L 20 ${height - line.width}
              `;
  }, [type, width, height]);

  const bottomLine = useMemo(() => {
    return `
              M 20 ${line.width}
              L 30 ${line.width}
              L 30 ${height / 2}
              L 40 ${height / 2}
              L 30 ${height / 2}
              L 30 ${height - line.width}
              L 20 ${height - line.width}
              `;
  }, [type, width, height]);

  const path = useMemo(() => {
    switch (linePosition) {
      case "bottom":
        return bottomLine;
      case "top":
        return topLine;
      case "left":
        return leftLine;
      case "right":
        return rightLine;
    }
  }, [type, width, height]);

  // 删除概要
  const handleRemove = () => {
    const parentNode = graph.getCellById(summarySource);
    parentNode?.prop("changeNodeData", {
      cellId: parentNode.id,
      data: {
        summary: undefined,
      },
      ignoreRender: false,
    });
  };

  const handleChange = (key: string, value: any) => {
    node.prop("changeNodeData", {
      cellId: node.id,
      data: {
        [key]: value,
      },
      ignoreRender: false,
    });
    const parentNode = graph.getCellById(summarySource);
    if (parentNode) {
      parentNode.prop("changeNodeData", {
        cellId: parentNode.id,
        data: {
          summary: {
            ...parentNode.data.summary,
            border: {
              ...parentNode.data.summary.border,
              [key]: value,
            },
          },
        },
        ignoreRender: false,
      });
    }
  };

  const colors = [
    "#bf1e1b",
    "#63abf7",
    "#71cb2d",
    "#ff9f1a",
    "#30bfbf",
    "#000",
  ];

  const ColorBtn = ({
    color,
    value,
    onClick,
  }: {
    color: string;
    value: string;
    onClick: () => void;
  }) => {
    return (
      <div
        className={`relative w-18px h-18px cursor-pointer rounded-4px flex items-center justify-center hover:opacity-80`}
        style={{
          background: color,
          border: !color ? "1px solid #000" : "",
        }}
        onClick={onClick}
      >
        {color === value && (
          <i className="iconfont icon-zhengque-1 color-#fff" />
        )}
        {!color && (
          <i className="absolute left-0 top-0 block w-1px h-24px bg-#de0f18 origin-top-left rotate--45" />
        )}
      </div>
    );
  };

  return (
    <>
      <div className="relative text-0 w-full h-full">
        {showSetting && (
          <svg
            className="w-full h-full"
            viewBox={`0 0 ${width} ${height}`}
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              fill="none"
              d={`
              M ${0},${0}
              L ${width},${0}
              L ${width},${height}
              L ${0},${height} Z
            `}
              stroke={line.color}
              strokeWidth={2}
            />
          </svg>
        )}

        <svg
          className="absolute w-40px h-full"
          style={lineStyle}
          viewBox={`0 0 ${40} ${height}`}
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d={path}
            fill="none"
            stroke={line.color}
            strokeWidth={line.width}
          />
        </svg>

        {showSetting && (
          <Popover
            trigger={["hover"]}
            content={
              <div className="w-240px">
                <div className="flex justify-between items-center m-b-20px">
                  <span className="text-14px font-bold">概要设置</span>
                  <span
                    className="text-12px cursor-pointer color-#666 hover:color-red"
                    onClick={handleRemove}
                  >
                    删除概要
                    <i className="iconfont icon-shanchu m-l-4px" />
                  </span>
                </div>
                <div className="flex items-center gap-8px m-b-8px">
                  <span className="text-12px color-#333">概要宽度</span>
                  <InputNumber
                    className="w-100px"
                    size="small"
                    min={1}
                    max={4}
                    precision={0}
                    value={line.width}
                    onChange={(val) =>
                      handleChange("line", { ...line, width: val })
                    }
                  />
                </div>
                <div className="flex items-center gap-8px m-b-8px">
                  <span className="text-12px color-#333">概要颜色</span>
                  {colors.map((color) => (
                    <ColorBtn
                      key={color}
                      color={color}
                      value={line.color}
                      onClick={() => handleChange("line", { ...line, color })}
                    />
                  ))}
                </div>
                <div className="flex items-center gap-8px m-b-8px">
                  <span className="text-12px color-#333">概要样式</span>
                  <Button
                    type="text"
                    size="small"
                    icon={<Icon icon="local:1" height="16px" />}
                    className={type === 1 ? "active" : ""}
                    onClick={() => handleChange("type", 1)}
                  ></Button>
                  <Button
                    type="text"
                    size="small"
                    icon={<Icon icon="local:2" height="16px" />}
                    className={type === 1 ? "active" : ""}
                    onClick={() => handleChange("type", 2)}
                  ></Button>
                  <Button
                    type="text"
                    size="small"
                    icon={<Icon icon="local:3" height="16px" />}
                    className={type === 1 ? "active" : ""}
                    onClick={() => handleChange("type", 3)}
                  ></Button>
                  <Button
                    type="text"
                    size="small"
                    icon={<Icon icon="local:4" height="16px" />}
                    className={type === 1 ? "active" : ""}
                    onClick={() => handleChange("type", 4)}
                  ></Button>
                </div>
              </div>
            }
          >
            <i
              className="z-9 iconfont icon-more text-12px absolute top-25% cursor-pointer"
              style={{
                color: line.color || "#000",
                [linePosition]: "-36px",
              }}
            />
          </Popover>
        )}
      </div>
    </>
  );
};

// 主题节点
register({
  shape: "mind-map-summary-border",
  effect: ["data"],
  component: component,
});

export default {
  shape: "mind-map-summary-border",
  data: {
    line: {
      width: 2,
      color: "#63abf7",
    },
    type: 1,
  },
};
