<template>
  <div ref="container" :style="containerStyle" class="codeEdit"></div>
  <div class="errorMsg">{{ errorMsg }}</div>
</template>

<script setup>
import { reactive, ref, onMounted } from 'vue'
/**
 * 代码编辑器
 */
import * as monaco from 'monaco-editor'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'


let props = defineProps(['modelValue','codeType','height','width'])
let emit = defineEmits(['update:modelValue','codeError'])

let container = ref()

let errorMsg = ref()


let style = ""
if(props.height !== undefined){
  style = "height:" + props.height +";"
}else {
  style = "height:200px;"
}
if(props.width !== undefined){
  style += "width:" + props.width +";"
}else{
  style += "width:100%;"
}
let containerStyle = ref(style)


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()
  }
}

function createMonaco(){

  const monacoInstance = monaco.editor.create(container.value, {
    value: props.modelValue,  // 默认值
    language: props.codeType, // 语言类型
    theme: 'vs', // 官方自带三种主题 vs, hc-black, or vs-dark
    tabSize: 2,
  })

  monacoInstance.onDidChangeModelContent(val => {
    emit('update:modelValue', monacoInstance.getValue())  // 监听值变化并同步数据到 model
  })

  monaco.editor.onDidChangeMarkers(([uri]) => {
    const markers = monaco.editor.getModelMarkers({resource: uri})
    // markers是返回的错误信息数组，可赋值给需要判断语法错误的关键词，如this.coderErrors = markers
    if(markers.length > 0){
      let marker = markers[0]
      errorMsg.value = "第 "+ marker.startLineNumber +" 行代码语法错误："+ marker.message
    }else{
      errorMsg.value = ""
    }
    emit('codeError',markers.length)
  })



}




onMounted(() => {
  createMonaco()

})


</script>

<style scoped>
.codeEdit{
  border: 1px solid var(--el-border-color);
}
.errorMsg{
  color: #F56C6C;
  font-size: 12px;
}
</style>