import { Controlled as CodeMirror } from 'react-codemirror2';

import './formatting/rune';
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/tomorrow-night-eighties.css';

import './formatting/codeMirror.css';
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import styles from './RuneCode.module.scss';

// const highlightErrors = (
//   codeMirror: CodeMirror,
//   diagnostics: any[],
//   styles: Record<string, string>
// ) => {
//   const cm = codeMirror!.editor;

//   cm.getAllMarks().forEach((mark) => mark.clear());

//   diagnostics.forEach((error) => {
//     const { start, end } = error;
//     cm.scrollIntoView({ line: start.line, ch: start.character });
//     cm.markText(
//       { line: start.line, ch: start.character },
//       { line: end.line, ch: end.character },
//       {
//         className: styles.errorHighlight,
//         clearOnEnter: true,
//       }
//     );
//   });
// };

type RuneCodeProps = {
  code: string;
  size: string;
  readOnly?: boolean;
  onChange?: (code: string) => void;
};

export type RuneCodeHandle = {
  highlightErrors: (diagnostics: any[]) => void;
};

const RuneCode = forwardRef<RuneCodeHandle, RuneCodeProps>(
  ({ code, readOnly = false, size = '400px', onChange }, ref) => {
    const codeMirrorRef = useRef<CodeMirror | null>(null);

    const [runeCode, setRuneCode] = useState<string>('');

    useEffect(() => {
      setRuneCode(code);
    }, [code]);

    const highlightErrors = useCallback((diagnostics: any[]) => {
      const cm = codeMirrorRef.current!.editor;

      cm.getAllMarks().forEach((mark) => mark.clear());

      diagnostics.forEach((error) => {
        const { start, end } = error;
        cm.scrollIntoView({ line: start.line, ch: start.character });
        cm.markText(
          { line: start.line, ch: start.character },
          { line: end.line, ch: end.character },
          {
            className: styles.errorHighlight,
            clearOnEnter: true,
          }
        );
      });
    }, []);

    useImperativeHandle(ref, () => ({
      highlightErrors,
    }));

    return (
      <CodeMirror
        ref={codeMirrorRef}
        editorDidMount={(editor) => {
          editor.setSize('', size);
        }}
        value={runeCode}
        options={{
          readOnly,
          mode: 'rune',
          theme: 'tomorrow-night-eighties',
          lineNumbers: true,
        }}
        onBeforeChange={(_editor, _data, value) => {
          setRuneCode(value);
          onChange?.(value);
        }}
      />
    );
  }
);

RuneCode.displayName = 'RuneCode';

export default RuneCode;

Neighbours