import * as editable from "@zag-js/editable";
import { normalizeProps, useMachine } from "@zag-js/react";
import clsx from "clsx";
import * as React from "react";
import { useGetKey } from "../../hooks";
import { useComposedRefs } from "../../utils/mergeRefs";

type EditableProps = Omit<
  React.HTMLProps<HTMLDivElement>,
  "onSubmit" | "value" | "defaultValue"
> & {
  autoResize?: boolean;
  value?: string;
  onSubmit: (value: string) => void;
  "data-id"?: string;
};

const EditableContext = React.createContext<editable.Api>(undefined as any);
const useEditableContext = () => React.useContext(EditableContext);
export const Editable = ({
  className,
  value,
  children,
  disabled,
  onSubmit,
  autoResize = true,
  ref,
  ...props
}: EditableProps) => {
  const key = useGetKey(props);
  const service = useMachine(editable.machine, {
    defaultValue: value,
    id: key,
    disabled: disabled,
    selectOnFocus: true,
    autoResize,
    onValueCommit: (details) => {
      onSubmit(details.value);
    },
  });
  const api = editable.connect(service, normalizeProps);
  return (
    <div
      ref={ref}
      className={clsx("", className)}
      {...props}
      {...api.getRootProps()}
    >
      <div {...api.getAreaProps()}>
        <EditableContext.Provider value={api}>
          {children}
        </EditableContext.Provider>
      </div>
    </div>
  );
};

Editable.EditablePreview = ({ className, ...props }) => {
  const api = useEditableContext();
  return (
    <span
      className={clsx("__editable-preview", className)}
      {...props}
      {...api?.getPreviewProps()}
    />
  );
};

Editable.EditableInput = ({ className, ref, ...props }) => {
  const inputRef = React.useRef<HTMLInputElement>(null);
  const api = useEditableContext();
  React.useEffect(() => {
    if (inputRef.current && api.editing) {
      window.setTimeout(() => {
        // console.log("api.editing", api.editing, inputRef.current);
        inputRef.current?.focus();
      }, 100);
    }
  }, [api.editing]);
  return (
    <input
      ref={useComposedRefs(inputRef, ref)}
      className={clsx("__editable-input", className)}
      {...props}
      {...api?.getInputProps()}
    />
  );
};
