<template>
  <div ref="editorRef" style="width: 750px; height: 500px"></div>
</template>

<script lang="ts">
import {
  ref,
  defineComponent,
  onMounted,
  PropType,
  onBeforeUnmount,
} from "vue";
import jsBeautify from "js-beautify";

import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
//@ts-ignore
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
//@ts-ignore
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
//@ts-ignore
import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
//@ts-ignore
import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
//@ts-ignore
import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";

const jsBeautifyOption = {
  indent_size: "2",
  indent_char: " ",
  max_preserve_newlines: "5",
  preserve_newlines: true,
  keep_array_indentation: false,
  break_chained_methods: false,
  indent_scripts: "normal",
  brace_style: "collapse",
  space_before_conditional: true,
  unescape_strings: false,
  jslint_happy: false,
  end_with_newline: true,
  wrap_line_length: "0",
  indent_inner_html: false,
  comma_first: false,
  e4x: false,
  indent_empty_lines: false,
};

export type Language = "javascript" | "json" | "html" | "typescript" | "sql";

export default defineComponent({
  name: "DEditor",
  props: {
    code: {
      type: String,
      default: "",
    },
    language: {
      type: String as PropType<Language>,
      default: "javascript",
    },
  },
  emits: ["update:code", "change"],
  setup(props, { emit }) {
    const editorRef = ref();
    const modelValue = ref(jsBeautify(props.code, jsBeautifyOption));
    let editor: monaco.editor.IStandaloneCodeEditor;

    onMounted(() => {
      self.MonacoEnvironment = {
        getWorker(_, label) {
          if (label === "json") {
            return new jsonWorker();
          }
          if (label === "css" || label === "scss" || label === "less") {
            return new cssWorker();
          }
          if (label === "html" || label === "handlebars" || label === "razor") {
            return new htmlWorker();
          }
          if (label === "typescript" || label === "javascript") {
            return new tsWorker();
          }
          return new editorWorker();
        },
      };
      console.log(props.language)
      editor = monaco.editor.create(editorRef.value, {
        value: modelValue.value,
        language: props.language,
        theme: "vs-dark",
      });

      // 监听代码修改事件
      editor.onDidChangeModelContent(() => {
        const code = editor.getValue();
        emit('change', code);
        emit('update:code', code);
      });
    });

    onBeforeUnmount(() => {
      editor?.dispose();
    });

    return {
      editorRef,
    };
  },
});
</script>

<style scoped></style>
