import { FC, useCallback, useRef, useState } from "react";
import { DisplayNameGenerator } from "@/utils/generators/generateDisplayName";
import { EditableTextProps } from "./interface";
import { editableTextWrapperStyle, innerTextStyle, textStyle } from "./style";
import PanIcon from "@mui/icons-material/Create";
import { useTheme } from "@mui/material";

const DISPLAY_NAME_REGEX = /^([a-zA-Z_$])([a-zA-Z0-9_$])*$/;
const isValidDisplayName = (displayName: string): boolean =>
  DISPLAY_NAME_REGEX.test(displayName);
export const EditableText: FC<EditableTextProps> = (props) => {
  const {
    displayName,
    updateDisplayNameByBlur,
    onMouseEnter,
    onClick,
    onBlur,
    onValidate,
  } = props;
  const [inputValue, setInputValue] = useState(displayName);
  const [isFocusInput, setIsFocusInput] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const theme = useTheme();
  const handleChangeInputValue = (value: string) => {
    setInputValue(value);
  };

  const handleClickOnSpan = () => {
    if (isFocusInput) return;
    setIsFocusInput(true);
    onClick?.();
    setTimeout(() => {
      inputRef.current?.focus();
    }, 100);
  };

  const handleBlurInput = useCallback(() => {
    setIsFocusInput(false);
    if (displayName === inputValue) {
      return;
    }
    onBlur?.(inputValue);
    if (!isValidDisplayName(inputValue)) {
      onValidate?.("failed");
      setInputValue(displayName);
      return;
    }
    if (DisplayNameGenerator.isAlreadyGenerate(inputValue)) {
      onValidate?.("failed");
      setInputValue(displayName);
      return;
    }
    onValidate?.("suc");
    updateDisplayNameByBlur(inputValue);
  }, [displayName, inputValue, onBlur, onValidate, updateDisplayNameByBlur]);
  return (
    <div
      css={editableTextWrapperStyle(theme)}
      onMouseEnter={onMouseEnter}
      className="editable-text-container"
      onDoubleClick={handleClickOnSpan}
    >
      {isFocusInput ? (
        <input
          id={displayName}
          onBlur={handleBlurInput}
          ref={inputRef}
          style={{
            height: "24px",
            color: theme.palette.action.active,
            fontSize: "16px",

            fontWeight: 200,
            padding: "5px 8px",
            borderRadius: "5px",
            border: "1px solid #edf2f2",
            // padding: "none",
            width: "80%",
          }}
          value={inputValue}
          onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
            handleChangeInputValue(event.target.value);
          }}
        />
      ) : (
        <span css={textStyle(theme)} className="text-container">
          <span css={innerTextStyle(theme)}>
            {inputValue}
            <PanIcon />
          </span>
        </span>
      )}
    </div>
  );
};
