"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const index = require("../_vendor/@codemirror/state/dist-index.cjs");
const index$1 = require("../_vendor/@codemirror/view/dist-index.cjs");
const react = require("react");
const useExtensions = require("./use-extensions.cjs");
const useEvent = require("./use-event.cjs");
const useLanguageExtensions = require("./use-language-extensions.cjs");
function useCodeEditor(props) {
  const {
    value,
    customExtensions,
    autoFocus,
    onChange,
    readonly,
    lineWrapping,
    onEditorUpdate,
    onFormat,
    onCursorChange,
    onSelectionChange
  } = props;
  const id = react.useId();
  const containerRef = react.useRef(null);
  const editorViewRef = react.useRef(null);
  const isInternalChangeRef = react.useRef(false);
  const getCursorPosition = react.useCallback(() => {
    const editor = editorViewRef.current;
    if (!editor) return null;
    const { state } = editor;
    const pos = state.selection.main.head;
    const lineInfo = state.doc.lineAt(pos);
    return {
      column: pos - lineInfo.from + 1,
      line: lineInfo.number
    };
  }, []);
  const getSelectedCharacterCount = react.useCallback(() => {
    const editor = editorViewRef.current;
    if (!editor) return 0;
    const { state } = editor;
    const { from, to } = state.selection.main;
    return to - from;
  }, []);
  const extensions = useExtensions.useExtensions({
    readonly,
    lineWrapping,
    customExtensions,
    onChange: (newValue, update) => {
      isInternalChangeRef.current = true;
      onChange == null ? void 0 : onChange(newValue, update);
    },
    onCursorChange,
    onEditorUpdate: onEditorUpdate ?? (() => {
    }),
    onFormat,
    onSelectionChange
  });
  const { getLanguageExtensions } = useLanguageExtensions.useLanguageExtensions({
    id
  });
  const { blurOnClickOutside } = useEvent.useEvent(editorViewRef);
  const createEditor = react.useCallback(async () => {
    if (!containerRef.current) return;
    const languageExtensions = await getLanguageExtensions(value ?? "");
    const config = {
      doc: value ?? "",
      extensions: [...extensions, ...languageExtensions]
    };
    const parent = containerRef.current;
    const state = index.EditorState.create(config);
    const editorView = new index$1.EditorView({
      parent,
      state
    });
    editorViewRef.current = editorView;
  }, [extensions, getLanguageExtensions, value]);
  react.useLayoutEffect(() => {
    createEditor();
    return () => {
      if (editorViewRef.current) {
        editorViewRef.current.destroy();
        editorViewRef.current = null;
      }
    };
  }, []);
  react.useEffect(() => {
    const editor = editorViewRef.current;
    if (!editor) return;
    if (isInternalChangeRef.current) {
      isInternalChangeRef.current = false;
      return;
    }
    const currentValue = editor.state.doc.toString();
    const newValue = value ?? "";
    if (currentValue !== newValue) {
      editor.dispatch({
        changes: {
          from: 0,
          to: currentValue.length,
          insert: newValue
        }
      });
    }
  }, [value]);
  react.useEffect(() => {
    if (autoFocus && editorViewRef.current) {
      editorViewRef.current.focus();
    }
  }, [autoFocus]);
  react.useEffect(() => {
    document.addEventListener("click", blurOnClickOutside);
    return () => {
      document.removeEventListener("click", blurOnClickOutside);
    };
  }, [blurOnClickOutside]);
  return {
    containerRef,
    editorViewRef,
    getCursorPosition,
    getSelectedCharacterCount
  };
}
exports.useCodeEditor = useCodeEditor;
//# sourceMappingURL=use-code-editor.cjs.map
