import React, { useEffect, useMemo, useRef, useState } from "react";
import { Input, InputRef } from "antd";
import { Node } from "@antv/x6";
import { useSafeState } from "ahooks";
export default function CustomInput(props: {
  value: string;
  styles: React.CSSProperties & {
    textVAlign: "top" | "middle" | "bottom";
    bold: boolean;
    italic: boolean;
  };
  node: Node;
  placeholder?: string;
  txtStyle?: React.CSSProperties;
  onChange?: (value: string) => void;
  notSetData?: boolean;
}) {
  const { value, styles, node, placeholder, txtStyle } = props;
  const [isEditing, setIsEditing] = useSafeState(false);
  const inputRef = useRef<InputRef>(null);

  const style = useMemo(() => {
    const top =
      styles.textVAlign === "top"
        ? 0
        : styles.textVAlign === "middle"
          ? "50%"
          : undefined;
    const bottom = styles.textVAlign === "bottom" ? 0 : undefined;
    return {
      ...styles,
      fontWeight: styles.bold ? "bold" : undefined,
      fontStyle: styles.italic ? "italic" : undefined,
      transform:
        styles.textVAlign === "middle" ? "translateY(-50%)" : undefined,
      minHeight: "12px",
      top,
      bottom,
    };
  }, [styles]);

  const handleChange = (val: string) => {
    if(!props.notSetData) {
      node.setData({ label: val });
    }
    props.onChange?.(val);
  };

  const [findObj, setFindObj] = useState<{
    findStr: string;
    currentCellId?: string;
    currentIndex: number;
  }>();
  // 查找
  const handleFind = (args: any) => {
    setFindObj(args?.current || {});
  };

  const label = useMemo(() => {
    if (!findObj) return value;
    const list = (value || "").split(findObj.findStr || "");
    return list.map((str: string, index) => {
      // 当前的节点展示
      const style =
        findObj.currentCellId === node.id
          ? {
              background:
                index + 1 === findObj.currentIndex
                  ? "#FF9933"
                  : "rgba(255, 153, 51, 0.25)",
            }
          : {
              background: "#ffff00",
            };
      return (
        <span key={index}>
          {str}
          {index < list.length - 1 && (
            <span style={style}>{findObj.findStr}</span>
          )}
        </span>
      );
    });
  }, [value, findObj]);

  const handleReplace = (args: any) => {
    console.log("替换：", args);
    const { type, searchText, replaceText, currentIndex, currentCellId } = args?.current || {};
    if(args.current?.type === 'replaceAll') {
      handleChange(value.replaceAll(searchText, replaceText));
    }
    if(type === 'replace' && currentCellId === node.id) {
      const list = value.split(searchText);
      const text = list.map((str, index) => {
        const result = index + 1 === currentIndex ? replaceText : searchText;
        return str + (index < list.length - 1 ? result : '');
      }).join("");
      console.log(text);
      handleChange(text);
    }
  };

  const handleClear = () => {
    setFindObj(undefined);
  };

  useEffect(() => {
    node.off("change:find", handleFind);
    node.off("change:replace", handleReplace);
    node.off("change:clearFind", handleClear);

    node.on("change:find", handleFind);
    node.on("change:replace", handleReplace);
    node.on("change:clearFind", handleClear);
    return () => {
      node.off("change:find", handleFind);
      node.off("change:replace", handleReplace);
      node.off("change:clearFind", handleClear);
    };
  }, [value]);

  const handleSetEditing = (edit: boolean) => {
    if (node.data?.lock) {
      return;
    }
    node.setData({
      ignoreDrag: edit,
    });
    if (edit) {
      setTimeout(() => {
        inputRef.current?.focus({ cursor: "all" });
      }, 100);
    }
    setIsEditing(edit);
  };

  // useEffect(() => {
  //   // 处理字体加载
  //   // @ts-ignore
  //   // WebFont.load({
  //   //   google: {
  //   //     families: [styles.fontFamily]
  //   //   }
  //   // })
  // }, [styles.fontFamily]);

  return (
    <div className="absolute w-full h-full w-full" style={txtStyle}>
      {isEditing ? (
        <Input.TextArea
          ref={inputRef}
          placeholder={placeholder}
          value={value}
          variant="borderless"
          className="absolute"
          style={style}
          onChange={(e) => handleChange(e.target.value)}
          onBlur={() => handleSetEditing(false)}
          autoSize
        />
      ) : (
        <div
          className="absolute w-full"
          style={style}
          onDoubleClick={() => handleSetEditing(true)}
        >
          {label}
        </div>
      )}
    </div>
  );
}
