import { EditorView, keymap } from '@codemirror/view';
import { javascript } from '@codemirror/lang-javascript';
import { markdown } from '@codemirror/lang-markdown';
import { html } from '@codemirror/lang-html';
import { css } from '@codemirror/lang-css';
import { json } from '@codemirror/lang-json';
import { yaml } from '@codemirror/lang-yaml';
import { history } from '@codemirror/commands';
import { vscodeLight } from '@uiw/codemirror-theme-vscode';
import { formatKeymap } from './modules/keymap';
import { Compartment, Extension } from '@codemirror/state';
import { defaultKeymap } from '@codemirror/commands';
import { autocompletion, Completion } from '@codemirror/autocomplete';
import { getFileType } from './utils/get-file-type';
type BaseEditorOpts = {
  language?: string;
  filename: string;
  autoComplete?: {
    props?: any;
    open?: boolean;
    overrideList?: Completion[];
  };
};
export class BaseEditor {
  editor?: EditorView;
  onChangeCompartment?: Compartment;
  language: string;
  filename: string;
  el?: HTMLElement;
  autoComplete?: {
    props?: any;
    open?: boolean;
    overrideList?: Completion[];
  };

  constructor(opts?: BaseEditorOpts) {
    this.filename = opts?.filename || '';
    this.language = opts?.language || 'typescript';
    if (this.filename && !opts?.language) {
      // 根据文件名自动判断语言
      const fileType = getFileType(this.filename);
      this.language = fileType || 'typescript';
    }
    this.autoComplete = opts?.autoComplete || { open: true, overrideList: [] };
    this.onChangeCompartment = new Compartment(); // 创建一个用于 onChange 的独立扩展
  }
  onEditorChange(view: EditorView) {
    console.log('onChange', view);
  }
  getFileType(filename: string) {
    return getFileType(filename);
  }
  createEditor(el: HTMLElement) {
    this.el = el;
    const onChangeCompartment = this.onChangeCompartment!;
    const language = this.language;
    const extensions: Extension[] = [
      vscodeLight,
      formatKeymap,
      keymap.of(defaultKeymap), //
      history(),
    ];
    if (this.autoComplete?.open) {
      extensions.push(
        autocompletion({
          activateOnTyping: true, // 输入时触发补全
          closeOnBlur: true, // 失去焦点时关闭补全
          activateOnTypingDelay: 2000, // 输入时触发补全
          override: this.autoComplete?.overrideList || [],
          ...this.autoComplete?.props,
        }),
      );
    }
    if (language === 'typescript') {
      extensions.push(javascript({ typescript: true }));
    } else if (language === 'javascript') {
      extensions.push(javascript());
    } else if (language === 'markdown') {
      extensions.push(markdown());
    } else if (language === 'html') {
      extensions.push(html());
    } else if (language === 'css') {
      extensions.push(css());
    } else if (language === 'json') {
      extensions.push(json());
    } else if (language === 'yaml') {
      extensions.push(yaml());
    }

    this.editor = new EditorView({
      parent: el,
      extensions: [
        ...extensions, //
        onChangeCompartment.of([]),
      ],
    });
  }
  resetEditor(el?: HTMLElement) {
    this.editor?.destroy?.();
    this.createEditor(el || (this.el as HTMLElement));
  }
  setLanguage(language: string, el?: HTMLElement) {
    this.language = language;
    this.editor?.destroy?.();
    this.createEditor(el || (this.el as HTMLElement));
  }
  setContent(content: string) {
    this.editor?.dispatch({
      changes: { from: 0, to: this.editor?.state.doc.length, insert: content },
    });
  }
  getContent() {
    return this.editor?.state.doc.toString();
  }
  destroyEditor() {
    this.editor?.destroy();
  }
}

export default BaseEditor;
