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 Text(props: {
  value: string;
  styles: React.CSSProperties & {
    bold: boolean;
    italic: boolean;
  };
  node: Node;
  fixedWidth: boolean;
  placeholder?: string;
  txtStyle?: React.CSSProperties;
  onChange?: (value: string) => void;
}) {
  const { value, styles, node, placeholder, txtStyle } = props;
  const [isEditing, setIsEditing] = useSafeState(false);
  const inputRef = useRef<InputRef>(null);
  const [labelText, setLabelText] = useState(value);

  useEffect(() => {
    setLabelText(value);
  }, [value]);

  const style = useMemo((): React.CSSProperties => {
    return {
      ...styles,
      fontWeight: styles.bold ? "bold" : undefined,
      fontStyle: styles.italic ? "italic" : undefined,
      minHeight: "12px",
      padding: 0,
      wordBreak: "break-all",
    };
  }, [styles]);

  const handleChange = (val: string) => {
    // node.setData({ label: val });
    setLabelText(val);
    props.onChange?.(val);
  };

  const handleSetEditing = (edit: boolean) => {
    if (node.data?.lock) {
      return;
    }
    node.setData({
      ignoreDrag: edit
    });
    if (edit) {
      // 置顶
      node.toFront();
      setTimeout(() => {
        inputRef.current?.focus({ cursor: "all" });
      }, 100);
    } else {
      // 更新数据
      node.prop("changeNodeData", {
        cellId: node.id,
        data: {
          label: labelText
        },
        ignoreRender: false,
      });
    }
    setIsEditing(edit);
  };

  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,
              color: '#333'
            }}>{findObj.findStr}</span>
          )}
        </span>
      );
    });
  }, [value, findObj]);

  const handleReplace = (args: any) => {
    const { type, searchText, replaceText, currentIndex, currentCellId } = args?.current || {};
    // 单个替换  全部替换不在此实现
    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("");
      handleChange(text);
    }
  };

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

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

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

  return (
    <div style={txtStyle}>
      <div
        style={{
          ...style,
          opacity: isEditing ? 0 : 1,
        }}
        className="min-w-20px"
        onDoubleClick={() => handleSetEditing(true)}
      >
        {label}
      </div>
      {isEditing && (
        <Input.TextArea
          ref={inputRef}
          placeholder={placeholder}
          value={labelText}
          variant="borderless"
          style={{
            ...style,
            position: "absolute",
            left: 0,
            top: 0
          }}
          onChange={(e) => handleChange(e.target.value)}
          onBlur={() => handleSetEditing(false)}
          autoSize
        />
      )}
    </div>
  );
}
