import { EditorState } from "../_vendor/@codemirror/state/dist-index.js";
import { EditorView, keymap, placeholder } from "../_vendor/@codemirror/view/dist-index.js";
import { useRef, useMemo, useCallback, useLayoutEffect, useEffect } from "react";
import { html } from "../_vendor/@codemirror/lang-html/dist-index.js";
import { javascript, javascriptLanguage, scopeCompletionSource } from "../_vendor/@codemirror/lang-javascript/dist-index.js";
import { defaultKeymap, historyKeymap } from "../_vendor/@codemirror/commands/dist-index.js";
import { autocompletion, completionKeymap } from "../_vendor/@codemirror/autocomplete/dist-index.js";
import { syntaxHighlighting, foldKeymap, defaultHighlightStyle } from "../_vendor/@codemirror/language/dist-index.js";
import { lintKeymap } from "../_vendor/@codemirror/lint/dist-index.js";
import { searchKeymap } from "../_vendor/@codemirror/search/dist-index.js";
import { useBaseExtensions } from "./use-base-extensions.js";
function useJsEditor(props) {
  const {
    value,
    autoFocus,
    onChange,
    readonly,
    lineWrapping,
    placeholder: placeholder$1
  } = props;
  const containerRef = useRef(null);
  const editorViewRef = useRef(null);
  const isInternalChangeRef = useRef(false);
  const customTheme = useMemo(() => {
    return EditorView.theme({
      "&": {
        height: "100%",
        fontSize: "14px"
      },
      ".cm-scroller": {
        fontFamily: "'JetBrains Mono', 'Fira Code', monospace"
      },
      ".cm-content": {
        caretColor: "var(--foreground-default, #000)"
      },
      "&.cm-focused .cm-cursor": {
        borderLeftColor: "var(--foreground-default, #000)"
      },
      "&.cm-focused .cm-selectionBackground, ::selection": {
        backgroundColor: "var(--background-selected, #d4d4d4)"
      },
      ".cm-gutters": {
        backgroundColor: "var(--background-subtle, #f5f5f5)",
        color: "var(--foreground-subtle, #999)",
        border: "none"
      }
    });
  }, []);
  const baseExtensions = useBaseExtensions({
    readonly,
    lineWrapping,
    onChange: (newValue, update) => {
      isInternalChangeRef.current = true;
      onChange == null ? void 0 : onChange(newValue, update);
    },
    theme: customTheme,
    includeLineNumbers: true,
    includeKeymap: false
  });
  const languageExtensions = useMemo(() => {
    const extensions = [
      html({
        autoCloseTags: true
      }),
      javascript({
        jsx: false,
        typescript: false
      }),
      autocompletion({
        activateOnTyping: true,
        icons: true
      }),
      javascriptLanguage.data.of({
        autocomplete: scopeCompletionSource(globalThis)
      }),
      syntaxHighlighting(defaultHighlightStyle),
      keymap.of([
        ...defaultKeymap,
        ...searchKeymap,
        ...historyKeymap,
        ...foldKeymap,
        ...completionKeymap,
        ...lintKeymap
      ])
    ];
    if (placeholder$1) {
      extensions.push(placeholder(placeholder$1));
    }
    return extensions;
  }, [placeholder$1]);
  const createEditor = useCallback(() => {
    if (!containerRef.current) return;
    const config = {
      doc: value ?? "",
      extensions: [
        ...baseExtensions,
        ...languageExtensions
      ]
    };
    const state = EditorState.create(config);
    const editorView = new EditorView({
      parent: containerRef.current,
      state
    });
    editorViewRef.current = editorView;
  }, [value, baseExtensions, languageExtensions]);
  useLayoutEffect(() => {
    createEditor();
    return () => {
      if (editorViewRef.current) {
        editorViewRef.current.destroy();
        editorViewRef.current = null;
      }
    };
  }, []);
  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]);
  useEffect(() => {
    if (autoFocus && editorViewRef.current) {
      editorViewRef.current.focus();
    }
  }, [autoFocus]);
  return {
    containerRef
  };
}
export {
  useJsEditor
};
//# sourceMappingURL=use-js-editor.js.map
